bolt Valebyte VPS от $4/мес — NVMe, запуск за 60 секунд.

Получить VPS arrow_forward
eco Начальный Туториал

Установка SFTPGo на VPS: защищённый SFTP-сервер, веб-панель и S3-хранилище

calendar_month Sep 29, 2026 schedule 20 мин. чтения visibility 33 просмотров
Установка SFTPGo на VPS: защищённый SFTP-сервер, веб-панель и S3-хранилище
info

Нужен сервер для этого гайда? Мы предлагаем выделенные серверы и VPS в 50+ странах с мгновенной настройкой.

Нужен сервер для этого гайда?

Разверните VPS или выделенный сервер за минуты.

Установка SFTPGo на VPS: защищённый SFTP-сервер, веб-панель и S3-хранилище

TL;DR

SFTPGo — это самостоятельный SFTP-сервер с веб-панелью, управлением пользователями, квотами, виртуальными папками и поддержкой локального диска либо объектного S3-хранилища. В этом руководстве мы установим SFTPGo 2.6.x на Ubuntu Server 24.04 LTS через Docker Compose, закроем административную панель HTTPS-сертификатом Caddy, создадим пользователя и подключим S3-бакет для хранения файлов.

  • ОС: Ubuntu Server 24.04 LTS, Docker Engine и Docker Compose Plugin.
  • SFTPGo: официальный контейнерный образ версии 2.6.x.
  • Доступ: SFTP на отдельном порту, веб-панель и REST API через HTTPS.
  • Хранилище: локальный диск VPS или совместимое с S3 объектное хранилище.
  • Защита: SSH-ключи, UFW, Fail2ban, TLS, отдельный администратор и регулярные бэкапы.
  • Обслуживание: обновление контейнеров с сохранением конфигурации и базы данных.

1. TL;DR

SFTPGo подходит, когда нужен собственный файловый портал и SFTP-сервер без привязки к SaaS-провайдеру. Сервис предоставляет веб-интерфейс для администраторов и пользователей, поддерживает SFTP, HTTP/S, WebDAV, FTP/S, квоты и подключение S3-совместимых хранилищ.

Для небольшой команды достаточно VPS с 2 vCPU, 4 ГБ RAM и SSD-диском от 40 ГБ. Если сами файлы будут храниться в S3, локальный диск нужен в основном для контейнеров, базы данных, журналов и временных операций. Если используется локальная файловая система, объём диска должен соответствовать объёму данных с запасом не менее 25–30 процентов.

  • Административный интерфейс не публикуется на случайном порту: наружу отдаётся только через Caddy и HTTPS.
  • SFTP работает на отдельном TCP-порту, например 2022.
  • Данные SFTPGo и PostgreSQL находятся в постоянных Docker volumes.
  • Пароли и ключи доступа к базе не записываются в конфигурацию веб-сервера.
  • Резервная копия включает базу, конфигурацию, Docker Compose и данные пользователей.

2. Содержание

Статья рассчитана на владельца VPS, который хочет самостоятельно развернуть SFTPGo и контролировать доступ к файлам. Команды приведены для Ubuntu Server 24.04 LTS с пользователем, имеющим права sudo.

  1. Сначала определим архитектуру: SFTPGo, PostgreSQL, Caddy и внешний S3.
  2. Затем подготовим сервер: обновим ОС, создадим отдельного пользователя, настроим SSH, UFW и Fail2ban.
  3. После этого запустим контейнеры и проверим логи, порты и HTTP-ответы.
  4. В веб-панели создадим администратора, обычного пользователя и подключим S3-бакет.
  5. В конце настроим резервное копирование и процедуру обновления.

3. Что мы настраиваем и зачем

Схема: 3. Что мы настраиваем и зачем
Схема: 3. Что мы настраиваем и зачем

Что такое SFTPGo

SFTPGo — серверная система для безопасного обмена файлами. Основной протокол в этом руководстве — SFTP поверх SSH. В отличие от обычного системного пользователя Linux, пользователь SFTPGo управляется из приложения: ему можно назначить квоту, домашнюю директорию, виртуальные папки, разрешения на загрузку и скачивание, срок действия учётной записи и ограничения по IP.

У SFTPGo есть отдельная административная веб-панель. Через неё создаются пользователи, группы, политики хранения, ключи SSH и токены. Пользовательский веб-интерфейс позволяет обмениваться файлами через браузер, поэтому для обычной загрузки документов не обязательно устанавливать SFTP-клиент.

Целевая схема

Компонент Назначение Публичный доступ
SFTPGo Аутентификация, SFTP, веб-панель, REST API HTTPS и SFTP-порт
PostgreSQL Пользователи, группы, настройки и метаданные Нет
Caddy Reverse proxy и автоматические TLS-сертификаты 80 и 443
S3 Фактическое хранение файлов пользователей Через API S3, не напрямую с VPS

Что получится в результате

После выполнения инструкции SFTPGo будет доступен по адресу вроде https://files.example.com. Пользователь сможет войти в веб-панель или подключиться из WinSCP, Cyberduck, FileZilla, командной строки Linux и других клиентов.

Административная база будет храниться в PostgreSQL, а файлы можно разместить в S3. Это разделяет приложение и данные: замену VPS или контейнера не нужно совмещать с миграцией большого файлового массива. Однако база и настройки всё равно требуют резервного копирования.

Self-hosted или облачный сервис

Облачные сервисы обмена файлами проще начать использовать: не нужно обновлять ОС, следить за TLS и настраивать резервные копии. За это приходится платить регулярную абонентскую плату, принимать ограничения тарифов и передавать данные внешнему оператору.

Self-hosted-вариант на VPS оправдан, если нужен контроль над местоположением данных, собственная политика доступа, интеграция с S3, LDAP или внутренними системами. Владелец сервера отвечает за обновления и бэкапы, зато может самостоятельно выбирать протоколы, лимиты и схему хранения.

Когда SFTPGo не лучший выбор

Если требуется только одноразово передать несколько файлов, полноценный сервис будет избыточен. Для синхронизации рабочих каталогов между ноутбуками могут лучше подойти Nextcloud, Syncthing или специализированные backup-инструменты. SFTPGo особенно полезен там, где нужны именно управляемые аккаунты, SFTP-совместимость, ограничение прав и доступ к объектному хранилищу.

4. Какой VPS-конфиг нужен под эту задачу

Схема: 4. Какой VPS-конфиг нужен под эту задачу
Схема: 4. Какой VPS-конфиг нужен под эту задачу

Минимальная конфигурация

Для одного администратора и нескольких пользователей SFTPGo не требует большого количества CPU. Основная нагрузка зависит от числа одновременных соединений, TLS-терминации, скорости хранилища и размера файлов. Для тестовой установки достаточно 1 vCPU и 2 ГБ RAM, но для постоянной эксплуатации лучше начинать с 2 vCPU и 4 ГБ RAM.

Сценарий CPU RAM Диск Сеть
Тестирование 1 vCPU 2 ГБ 20–30 ГБ SSD 100 Мбит/с
Небольшая команда 2 vCPU 4 ГБ 40–80 ГБ SSD 500 Мбит/с или выше
Много пользователей 4–8 vCPU 8–16 ГБ 80 ГБ плюс объём кэша 1 Гбит/с

Если файлы лежат в S3, не нужно покупать диск размером с весь архив. Но запас диска всё равно нужен для PostgreSQL, журналов Docker, временных файлов, резервных копий и обновлений. Практичный базовый вариант — 2 vCPU, 4 ГБ RAM, 60 ГБ NVMe SSD и публичный IPv4. Для такой конфигурации можно взять подходящий VPS с Linux и полным root-доступом.

Требования к сети

Нужен входящий IPv4-адрес, а желательно также IPv6. DNS-имя files.example.com должно указывать на адрес сервера. Для автоматического получения TLS-сертификата Caddy нужны открытые TCP-порты 80 и 443. Для SFTP будет использоваться отдельный порт, например 2022.

Проверьте ограничения провайдера на исходящие соединения к S3. Некоторые сети блокируют отдельные диапазоны или ограничивают количество соединений. При работе с большими файлами важна не только скорость порта, но и стабильность маршрута до региона S3.

Когда нужен dedicated

Выделенный сервер оправдан, если объём локального хранилища превышает несколько терабайт, нужны несколько быстрых NVMe-дисков, десятки или сотни одновременных загрузок либо жёсткая изоляция от соседних виртуальных машин. Для SFTPGo, который использует внешний S3, переход на dedicated обычно не является первым шагом масштабирования.

Сначала следует измерить CPU, RAM, I/O и сетевую пропускную способность. Если узким местом становится только хранилище, выгоднее вынести данные в S3 или подключить отдельный storage-сервер. Dedicated имеет смысл, когда требуется предсказуемая производительность всех ресурсов одновременно.

Выбор локации

Размещайте VPS ближе к основным пользователям и региону S3. Это уменьшает задержку при работе с веб-панелью и передачах через SFTP. Если данные регулируются требованиями законодательства или политикой компании, регион сервера и объектного хранилища должен соответствовать этим требованиям.

5. Подготовка сервера

Схема: 5. Подготовка сервера
Схема: 5. Подготовка сервера

Обновление системы и имя хоста

Далее предполагается чистая Ubuntu Server 24.04 LTS. Подключитесь под временным пользователем с sudo или под root, установите имя хоста и обновите пакеты.

# Задаём имя сервера
sudo hostnamectl set-hostname sftp-01

# Обновляем список пакетов и устанавливаем обновления
sudo apt update && sudo apt full-upgrade -y

# Перезагружаем сервер, если обновлялось ядро
sudo reboot

После перезагрузки снова подключитесь по SSH. Создайте отдельного пользователя для администрирования. Используйте своё имя вместо deploy.

# Создаём обычного пользователя
sudo adduser deploy

# Добавляем его в группу sudo
sudo usermod -aG sudo deploy

# Проверяем принадлежность к группам
id deploy

SSH-ключи

На локальном компьютере сгенерируйте ключ Ed25519, если его ещё нет. Не передавайте приватный ключ на сервер и не храните его в Docker-проекте.

# Выполняется на вашем локальном компьютере
ssh-keygen -t ed25519 -C "deploy@sftp-01"

# Копируем публичный ключ на сервер
ssh-copy-id deploy@SERVER_IP

Проверьте вход в новой сессии, не закрывая текущую root-сессию. Только после успешной проверки можно отключать вход по паролю.

# Открываем конфигурацию SSH
sudoedit /etc/ssh/sshd_config.d/99-hardening.conf
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
MaxAuthTries 3
# Проверяем синтаксис и перечитываем конфигурацию SSH
sudo sshd -t && sudo systemctl reload ssh

Firewall

До включения UFW разрешите SSH-порт. В примере SSH работает на стандартном порту 22. Если вы изменили его, подставьте собственное значение.

# Устанавливаем UFW и разрешаем SSH, HTTP и HTTPS
sudo apt install -y ufw
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Отдельный порт SFTPGo
sudo ufw allow 2022/tcp

# Включаем firewall с политикой deny incoming
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable

# Проверяем активные правила
sudo ufw status verbose

Fail2ban и базовые утилиты

Fail2ban анализирует журналы неудачных входов и временно блокирует IP-адреса. Он не заменяет SSH-ключи, MFA и firewall, но уменьшает количество автоматического перебора.

# Устанавливаем защиту SSH и служебные инструменты
sudo apt install -y fail2ban ca-certificates curl wget git jq unzip \
    htop ncdu unattended-upgrades apt-transport-https

# Включаем Fail2ban при запуске
sudo systemctl enable --now fail2ban

# Создаём локальную настройку jail для SSH
sudo tee /etc/fail2ban/jail.d/sshd.local > /dev/null <<'EOF'
[sshd]
enabled = true
port = 22
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
EOF

# Перезапускаем Fail2ban и проверяем статус
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

Если SSH работает на другом порту, измените параметр port в jail и правило UFW. Не используйте смену порта как единственный метод защиты: ключи, запрет root и ограничение попыток важнее.

6. Установка ПО — пошагово

Схема: 6. Установка ПО — пошагово
Схема: 6. Установка ПО — пошагово

Шаг 1. Установка Docker из официального репозитория

Для воспроизводимого развёртывания используем Docker Engine и Compose Plugin из официального apt-репозитория Docker. На момент подготовки инструкции для продакшена используйте актуальный стабильный Docker Engine 27.x или более новый совместимый выпуск, доступный в репозитории.

# Удаляем конфликтующие старые пакеты
sudo apt remove -y docker.io docker-compose docker-doc podman-docker containerd runc || true

# Добавляем официальный ключ репозитория Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
    sudo tee /etc/apt/keyrings/docker.asc > /dev/null
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Подключаем репозиторий для текущего релиза Ubuntu
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Устанавливаем Docker Engine и Compose Plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
    docker-buildx-plugin docker-compose-plugin

# Включаем Docker при загрузке
sudo systemctl enable --now docker

# Проверяем версии
sudo docker version
sudo docker compose version

Шаг 2. Доступ пользователя deploy к Docker

Добавление пользователя в группу docker позволяет запускать Docker без sudo, но фактически даёт права уровня root. Делайте это только доверенному администратору.

# Добавляем deploy в группу Docker
sudo usermod -aG docker deploy

# Обновляем группу в текущей shell-сессии
newgrp docker

# Проверяем запуск без sudo
docker run --rm hello-world

Шаг 3. Создание структуры проекта

Создадим отдельный каталог. Файл .env будет содержать секреты и останется только на сервере.

# Создаём каталог приложения
sudo mkdir -p /opt/sftpgo
sudo chown -R deploy:deploy /opt/sftpgo
cd /opt/sftpgo

# Создаём файл секретов с закрытыми правами
touch .env
chmod 600 .env

# Проверяем текущий каталог
pwd

Шаг 4. Секреты окружения

Сгенерируйте длинные случайные пароли. Пароль PostgreSQL не должен совпадать с паролем администратора SFTPGo. Переменная SFTPGO_DEFAULT_ADMIN_PASSWORD используется только при первоначальной инициализации, поэтому сохраните её в менеджере паролей.

# Генерируем случайные значения
DB_PASSWORD=$(openssl rand -hex 32)
ADMIN_PASSWORD=$(openssl rand -base64 30 | tr -dc 'A-Za-z0-9!@#%+=' | head -c 28)

# Записываем переменные в .env
cat > .env <<EOF
POSTGRES_DB=sftpgo
POSTGRES_USER=sftpgo
POSTGRES_PASSWORD=${DB_PASSWORD}
SFTPGO_ADMIN_USERNAME=admin
SFTPGO_ADMIN_PASSWORD=${ADMIN_PASSWORD}
EOF

# Показываем только имена переменных, не значения
cut -d= -f1 .env

Шаг 5. Docker Compose

Ниже используется PostgreSQL 16 и официальный образ SFTPGo. Тег v2.6.x следует заменить на конкретный последний стабильный patch-релиз 2.6, проверенный перед установкой. Не используйте постоянно плавающий тег latest в критичной системе без тестирования.

# Создаём Docker Compose файл
cat > compose.yml <<'EOF'
services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    env_file:
      - .env
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - backend

  sftpgo:
    image: drakkan/sftpgo:v2.6.x
    restart: unless-stopped
    env_file:
      - .env
    environment:
      SFTPGO_DATA_PROVIDER__DRIVER: postgresql
      SFTPGO_DATA_PROVIDER__NAME: ${POSTGRES_DB}
      SFTPGO_DATA_PROVIDER__HOST: postgres
      SFTPGO_DATA_PROVIDER__PORT: 5432
      SFTPGO_DATA_PROVIDER__USERNAME: ${POSTGRES_USER}
      SFTPGO_DATA_PROVIDER__PASSWORD: ${POSTGRES_PASSWORD}
      SFTPGO_DEFAULT_ADMIN_USERNAME: ${SFTPGO_ADMIN_USERNAME}
      SFTPGO_DEFAULT_ADMIN_PASSWORD: ${SFTPGO_ADMIN_PASSWORD}
      SFTPGO_SFTPD__BINDINGS__0__PORT: 2022
      SFTPGO_HTTPD__BINDINGS__0__PORT: 8080
      SFTPGO_HTTPD__BINDINGS__0__BIND_ADDRESS: 0.0.0.0
    ports:
      - "2022:2022"
      - "127.0.0.1:8080:8080"
    volumes:
      - sftpgo_data:/var/lib/sftpgo
      - sftpgo_home:/srv/sftpgo
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - backend

  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    depends_on:
      - sftpgo
    networks:
      - backend

volumes:
  postgres_data:
  sftpgo_data:
  sftpgo_home:
  caddy_data:
  caddy_config:

networks:
  backend:
EOF

В Compose используются два постоянных тома SFTPGo. Первый хранит конфигурацию и внутренние данные приложения, второй предназначен для локального домашнего каталога пользователей. Даже если основной backend будет S3, эти тома нельзя удалять без резервной копии.

Шаг 6. Запуск базы и SFTPGo

# Проверяем итоговую конфигурацию Compose
docker compose config

# Загружаем образы и запускаем PostgreSQL и SFTPGo
docker compose up -d postgres sftpgo

# Проверяем состояние контейнеров
docker compose ps

# Смотрим журнал запуска SFTPGo
docker compose logs --tail=100 sftpgo

На первом запуске SFTPGo создаёт таблицы PostgreSQL и пользователя администратора. Если контейнер перезапускается, сначала проверьте журнал базы: наиболее частая причина — неверные переменные подключения, повреждённый volume или запуск приложения раньше готовности PostgreSQL.

Шаг 7. Установка Caddy

Caddy будет работать в отдельном контейнере и проксировать веб-интерфейс SFTPGo. SFTP-соединения через Caddy не проходят: порт 2022 публикуется непосредственно контейнером SFTPGo.

# Создаём Caddyfile с доменным именем
cat > Caddyfile <<'EOF'
files.example.com {
    reverse_proxy sftpgo:8080

    header {
        X-Content-Type-Options "nosniff"
        Referrer-Policy "strict-origin-when-cross-origin"
        X-Frame-Options "SAMEORIGIN"
    }

    encode zstd gzip
}
EOF

# Запускаем reverse proxy
docker compose up -d caddy

# Проверяем все сервисы
docker compose ps

Замените files.example.com на собственное DNS-имя до запуска Caddy. Если DNS ещё не обновился, контейнер будет работать, но автоматический сертификат получить не сможет.

7. Конфигурация

Схема: 7. Конфигурация
Схема: 7. Конфигурация

Проверка DNS, HTTPS и SFTP

Сначала убедитесь, что домен резолвится на правильный адрес. Проверку выполняйте с локального компьютера или другой машины в интернете.

# Проверяем DNS-запись
dig +short files.example.com

# Проверяем HTTPS и цепочку перенаправления
curl -I https://files.example.com

# Проверяем SFTP-порт
nc -vz files.example.com 2022

# Проверяем локальный HTTP-порт на сервере
curl -I http://127.0.0.1:8080

Ожидаемый ответ HTTPS — 200, 302 или другой ответ приложения без ошибки TLS. Команда nc должна показать успешное TCP-соединение. Если порт доступен локально, но не снаружи, проверяйте UFW и правила сетевого экрана в панели VPS.

Первый вход в панель

Откройте https://files.example.com и войдите с логином и паролем из файла .env. Сразу измените первоначальный пароль в интерфейсе и сохраните его в менеджере паролей. Не используйте учётную запись администратора для ежедневной передачи файлов.

В панели проверьте разделы настроек HTTP, SFTP, пользователей, групп и журналов. Если в будущем измените порт или binding через веб-интерфейс, учитывайте, что переменные окружения Compose применяются при создании контейнера и могут быть переопределены настройками приложения.

Создание пользователя для SFTP

  1. Откройте раздел пользователей и создайте новую учётную запись.
  2. Задайте уникальное имя и длинный пароль либо добавьте SSH public key.
  3. Укажите домашний каталог или виртуальную папку.
  4. Ограничьте права: обычно достаточно list, download и upload.
  5. Задайте квоту дискового пространства и количество файлов.
  6. При необходимости ограничьте разрешённые IP-адреса.
  7. Сохраните пользователя и выполните тестовое подключение.

Для сервисных интеграций предпочтительнее отдельный пользователь с минимальными правами и SSH-ключом. Не передавайте общий пароль нескольким сотрудникам: при увольнении или утечке невозможно будет точно определить источник доступа.

Подключение S3-хранилища

SFTPGo позволяет назначать пользователю или виртуальной папке backend объектного хранилища. Поддерживаются Amazon S3 и многие совместимые API, включая хранилища с собственным endpoint. В панели создания пользователя откройте настройки файловой системы и выберите тип хранения S3.

Заполните поля по следующей схеме:

Поле Пример Комментарий
Bucket company-files-prod Имя бакета без URL-префикса
Region eu-central-1 Регион, в котором создан бакет
Endpoint https://s3.example-storage.com Нужен для S3-compatible провайдера; для AWS может быть пустым
Access key отдельный ключ приложения Не используйте мастер-ключ аккаунта
Secret key секретный ключ Храните только в панели и менеджере секретов
Key prefix team-a/ Изолирует файлы одного пользователя в бакете

Создайте отдельный S3-пользователь с доступом только к нужному бакету и префиксу. Минимальный набор разрешений обычно включает чтение, загрузку, удаление объектов и просмотр содержимого бакета. Для некоторых провайдеров дополнительно нужен доступ к multipart upload.

Не публикуйте S3-бакет напрямую в интернет, если файлы должны выдаваться только через SFTPGo. Отключите публичный доступ, включите шифрование на стороне хранилища и настройте lifecycle-политику для старых версий или незавершённых multipart-загрузок.

Тестирование SFTP

Создайте тестовый файл и подключитесь к серверу. На Linux или macOS можно использовать встроенный клиент OpenSSH.

# Подключаемся к SFTPGo обычным паролем
sftp -P 2022 [email protected]

# После входа выполняются команды SFTP
pwd
ls
put test.txt
get test.txt
exit

Для подключения по ключу укажите приватный ключ клиента:

# Подключение с SSH-ключом
sftp -i ~/.ssh/sftp_user_ed25519 -P 2022 [email protected]

Проверьте, что пользователь не может выйти из назначенного виртуального пространства, читать чужие каталоги или выполнять команды оболочки. SFTPGo не предоставляет обычный shell-доступ, но итоговые права всё равно следует проверять отдельным тестовым аккаунтом.

Мониторинг логов и healthcheck

# Просматриваем логи приложения в реальном времени
docker compose logs -f --tail=100 sftpgo

# Просматриваем ошибки reverse proxy
docker compose logs --tail=100 caddy

# Проверяем, не перезапускаются ли контейнеры
docker compose ps

# Смотрим использование диска и памяти
df -h
free -h
docker system df

Для автоматического мониторинга добавьте проверку HTTPS, доступность TCP-порта 2022 и свободное место на диске. Внешняя система мониторинга должна уведомлять, если HTTP-ответ не приходит несколько минут или заполнение диска превышает 80 процентов.

Безопасность панели

Панель администратора должна быть доступна только через HTTPS. Не публикуйте порт 8080 в интернет: в Compose он привязан к 127.0.0.1, поэтому доступен только на самом сервере и из сети Docker.

Используйте MFA, если функция доступна в вашей версии и выбранном способе аутентификации. Отдельно ограничьте доступ к REST API, не храните API-токены в Git и отзывайте их после завершения интеграции. Административные журналы следует просматривать после изменений пользователей и прав.

8. Бэкапы и обслуживание

Схема: 8. Бэкапы и обслуживание
Схема: 8. Бэкапы и обслуживание

Что необходимо сохранять

Минимальный комплект резервной копии состоит из PostgreSQL, файла compose.yml, Caddyfile, файла окружения или его зашифрованной копии, а также Docker volumes SFTPGo. Если файлы находятся на локальном диске, нужно копировать и пользовательские данные. При S3-хранении сами объекты уже находятся вне VPS, но следует сохранять конфигурацию bucket, права, lifecycle-политику и версионирование.

Объект Частота Рекомендуемый срок
PostgreSQL dump Ежедневно 14–30 дней
Конфигурация Compose и Caddy После каждого изменения Все версии за 90 дней
Локальные файлы пользователей Ежедневно или по RPO По требованиям бизнеса
S3-объекты Версионирование и lifecycle По политике хранения

Простой backup через restic

Ниже используется restic и внешний S3-compatible репозиторий. Резервная копия базы сначала создаётся через pg_dump, затем каталог проекта архивируется в restic. Пароль restic и ключи S3 должны храниться в отдельном защищённом файле, недоступном другим пользователям.

# Устанавливаем restic
sudo apt install -y restic

# Создаём файл переменных резервного копирования
sudo install -m 600 /dev/null /root/.restic-env
sudoedit /root/.restic-env
export AWS_ACCESS_KEY_ID="backup-access-key"
export AWS_SECRET_ACCESS_KEY="backup-secret-key"
export RESTIC_REPOSITORY="s3:https://backup-s3.example.com/sftpgo-repo"
export RESTIC_PASSWORD="длинный-пароль-restic"

Создайте скрипт. Команда docker compose exec выполняет дамп внутри контейнера PostgreSQL и сохраняет его в подключённый каталог проекта.

# Создаём каталог для временных дампов
sudo mkdir -p /var/backups/sftpgo
sudo chmod 700 /var/backups/sftpgo

# Создаём скрипт резервного копирования
sudo tee /usr/local/sbin/backup-sftpgo.sh > /dev/null <<'EOF'
#!/usr/bin/env bash
set -Eeuo pipefail

cd /opt/sftpgo
source /root/.restic-env

STAMP="$(date +%F-%H%M%S)"
DUMP="/var/backups/sftpgo/postgres-${STAMP}.sql.gz"

docker compose exec -T postgres \
  pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" | gzip > "$DUMP"

restic backup \
  "$DUMP" \
  /opt/sftpgo/compose.yml \
  /opt/sftpgo/Caddyfile \
  /opt/sftpgo/.env

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

find /var/backups/sftpgo -type f -name '.sql.gz' -mtime +3 -delete
EOF

# Делаем скрипт исполняемым
sudo chmod 700 /usr/local/sbin/backup-sftpgo.sh

# Инициализируем restic repository один раз
sudo bash -c 'source /root/.restic-env && restic init'

# Выполняем тестовый backup
sudo /usr/local/sbin/backup-sftpgo.sh

Для запуска по расписанию добавьте cron от root. Ночной backup — только пример; выберите время с учётом активности пользователей и требований RPO.

# Открываем cron root
sudo crontab -e
30 02    /usr/local/sbin/backup-sftpgo.sh >> /var/log/backup-sftpgo.log 2>&1

Раз в месяц выполняйте пробное восстановление в отдельный каталог или на тестовый VPS. Backup, который никогда не проверяли восстановлением, нельзя считать надёжным.

Обновление SFTPGo

Перед обновлением зафиксируйте текущий тег образа и выполните полный backup. Для небольшой установки используйте окно обслуживания: остановите сервисы, скачайте новый образ, запустите контейнеры и проверьте функциональность.

# Переходим в каталог проекта
cd /opt/sftpgo

# Создаём резервную копию перед обновлением
sudo /usr/local/sbin/backup-sftpgo.sh

# Загружаем новую проверенную версию образов
docker compose pull

# Перезапускаем контейнеры без удаления volumes
docker compose up -d

# Проверяем состояние и последние ошибки
docker compose ps
docker compose logs --tail=100 sftpgo

Не выполняйте docker compose down -v: ключ -v удаляет именованные volumes и может уничтожить базу и локальные данные. Обновляйте сначала тестовую копию, затем production. Для крупной инсталляции используйте blue-green или отдельный standby-сервер, но миграции базы всё равно требуют совместимости версий.

Контроль ресурсов

Следите за заполнением файловой системы, inode, памятью и размером Docker-логов. Ограничьте ротацию журналов Docker, иначе длительная работа сервиса может заполнить диск.

# Проверяем inode и свободное место
df -h
df -i

# Проверяем потребление контейнеров
docker stats --no-stream

# Ищем крупные каталоги
sudo du -xhd1 /var/lib/docker /opt /var/log 2>/dev/null | sort -h

9. Troubleshooting и FAQ

Почему HTTPS показывает ошибку сертификата?

Проверьте, что DNS-имя указывает на публичный IP сервера, а TCP-порты 80 и 443 разрешены в UFW и внешнем firewall. Посмотрите журнал командой docker compose logs caddy: там будет причина отказа ACME. Убедитесь, что другой веб-сервер не занял порты 80 или 443. Если используется прокси DNS, временно проверьте корректность A/AAAA-записей и доступность origin-сервера.

Контейнер SFTPGo перезапускается. Что проверить?

Начните с docker compose logs --tail=200 sftpgo и docker compose ps. Частые причины — неправильное имя переменной PostgreSQL, неверный пароль в .env, недоступный сервис базы или повреждённый volume. Проверьте состояние PostgreSQL через docker compose logs postgres. Команда docker compose config покажет итоговые значения и ошибки YAML, но не выводите её результат в публичные логи: там могут присутствовать секреты.

Какой VPS-конфиг минимально подойдёт?

Для тестирования подойдёт 1 vCPU, 2 ГБ RAM и 20–30 ГБ SSD. Для постоянной работы небольшой команды лучше использовать 2 vCPU, 4 ГБ RAM и 40–60 ГБ NVMe. Если файлы хранятся в S3, диск не обязан быть равен размеру архива, но нужен запас для базы, логов, временных файлов и резервных копий. При локальном хранении добавьте объём пользовательских данных и минимум 25 процентов свободного пространства.

Что выбрать — VPS или dedicated для этой задачи?

В большинстве случаев достаточно VPS: SFTPGo и PostgreSQL умеренно потребляют CPU, а данные можно вынести в S3. Dedicated нужен при большом локальном файловом архиве, высокой постоянной нагрузке на диски, большом числе параллельных передач или требованиях к физической изоляции. Перед переходом измерьте ресурсы через мониторинг. Часто дешевле масштабировать диск или S3, чем сразу арендовать выделенный сервер.

Порт 2022 открыт, но SFTP не подключается

Проверьте, что контейнер опубликован с правилом 2022:2022, а SFTPGo действительно слушает этот порт: docker compose logs sftpgo и sudo ss -lntp | grep 2022. Затем проверьте UFW и внешний firewall. В клиенте должен быть выбран именно протокол SFTP, а не FTP или FTPS. Также проверьте логин, статус пользователя, срок действия аккаунта и разрешённый IP-список.

Пользователь входит, но не видит файлы в S3

Сначала проверьте bucket, регион и endpoint. Для совместимого S3 endpoint обычно нужно указывать полный URL с HTTPS. Проверьте права ключа: нужны как минимум операции просмотра, чтения и загрузки, а для удаления — отдельное разрешение delete. Убедитесь, что prefix не содержит лишних пробелов или начального слеша. Посмотрите журнал SFTPGo в момент операции: ошибки AWS SDK обычно указывают на неверный регион, подпись, ACL или отсутствие права.

После перезапуска исчезли пользователи и настройки

Проверьте, что PostgreSQL и SFTPGo используют именованные volumes, указанные в Compose. Не запускайте проект из другого каталога с другим файлом Compose и не выполняйте docker compose down -v. Команды docker volume ls и docker volume inspect покажут существующие тома. Если база была удалена, восстановите её из pg_dump и только после этого запускайте SFTPGo.

Как ограничить доступ к административной панели?

Оставьте HTTP-порт SFTPGo привязанным к 127.0.0.1, как в примере, и публикуйте интерфейс только через Caddy. Дополнительно можно ограничить доступ к домену на уровне VPN, reverse proxy или сетевого firewall. Используйте отдельные администраторские аккаунты, MFA и короткоживущие API-токены. Не размещайте панель на прямом публичном порту без TLS.

Можно ли хранить файлы только на VPS?

Да. Создайте пользователя с локальной файловой системой и укажите домашний каталог внутри тома sftpgo_home либо отдельного bind mount. Такой вариант проще и быстрее в локальной сети, но требует контроля диска и отдельной копии данных. Не считайте Docker volume резервной копией: отказ диска или удаление VPS уничтожит его вместе с контейнером. Для production используйте внешний backup или репликацию.

10. Выводы и следующие шаги

Схема: 10. Выводы и следующие шаги
Схема: 10. Выводы и следующие шаги

В результате мы получили SFTPGo на VPS с PostgreSQL, HTTPS через Caddy, отдельным SFTP-портом, управлением пользователями и возможностью хранить файлы в S3. Система отделяет метаданные приложения от файлов и позволяет масштабировать хранилище независимо от вычислительных ресурсов.

Следующий практический шаг — включить MFA, настроить внешний мониторинг и регулярно тестировать восстановление из backup. При росте нагрузки измеряйте CPU, память, сетевой трафик и задержки S3, а затем выбирайте между увеличением VPS, отдельным storage-сервером и выделенным dedicated.

  • Создайте отдельные группы пользователей с минимальными правами и квотами.
  • Включите версионирование и lifecycle-политику в S3 для защиты от случайного удаления.
  • Документируйте процедуру восстановления на чистом сервере и проверяйте её после каждого крупного обновления.

Был ли этот гайд полезен?

Ваш отзыв помогает нам улучшать гайды.

Поделиться записью:

Отправьте гайд тому, кому он может пригодиться.

Telegram VKVK WhatsApp Facebook LinkedIn XX

установка sftpgo на vps: защищённый sftp-сервер, веб-панель и s3-хранилище
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.