MAATRIX / Блог / Как установить и настроить Docker Compose для продакшена на VPS

Как установить и настроить Docker Compose для продакшена на VPS

Как установить и настроить Docker Compose для продакшена на VPS

MAATRIX

Docker Compose удобен для локальной разработки, но продакшен предъявляет к нему другие требования: контейнеры должны сами подниматься после сбоя, не съедать всю память, переживать перезагрузку и обновляться без простоя. Настроить Docker Compose для продакшена на VPS — значит добавить к обычному compose-файлу политики перезапуска, лимиты ресурсов, проверки здоровья и продуманное хранение данных. Разберём это по шагам.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Чем продакшен отличается от локального запуска

На локальной машине compose-файл обычно минимален: образ, порты, пара переменных. Для сервера этого мало, и разница принципиальна. Локально вы сами перезапускаете упавший контейнер, а на проде он должен подниматься автоматически. Локально не страшно, если один сервис съест всю память, а на сервере это уронит соседей. Локально данные не жалко, а в продакшене их потеря — катастрофа.

Из этого вытекает набор обязательных настроек. Политика перезапуска, чтобы контейнеры возвращались после падения и перезагрузки. Лимиты памяти и процессора, чтобы один сервис не задушил остальные. Проверки здоровья, чтобы система знала, что контейнер не просто запущен, а действительно работает. Явные именованные тома для данных, чтобы они переживали пересоздание контейнеров. И аккуратная работа с переменными и секретами, чтобы пароли не лежали в открытом виде в репозитории.

Ещё один сдвиг мышления — обновления. Локально вы останавливаете всё и запускаете заново, а на проде хочется обновлять сервисы с минимальным простоем и с возможностью откатиться, если новая версия сломалась. Всё это Docker Compose умеет, нужно лишь правильно описать.

Установка Docker и Compose на VPS

Для продакшена берите VPS с запасом под ваши контейнеры: типовому набору из веб-приложения, базы и кеша комфортно на 2–4 ядрах и 4–8 ГБ RAM, а под тяжёлые сервисы ресурсы считают отдельно. Ставьте Docker из официального репозитория, а не из стандартного пакета дистрибутива, — так вы получите свежую версию с плагином Compose:

curl -fsSL https://get.docker.com | sh
docker --version
docker compose version

Скрипт установки подключает официальный репозиторий и ставит Docker Engine вместе с плагином compose (обратите внимание: современная команда — docker compose без дефиса). Включите автозапуск демона, чтобы после перезагрузки VPS всё поднималось само:

systemctl enable --now docker

Локацию сервера выбирайте по задаче проекта: для российской аудитории ниже пинг с RU-площадки, для доступа к зарубежным сервисам — US, для Европы — UK. У MAATRIX доступны все три с оплатой из России картой, СБП или криптой, поэтому продакшен-сервер можно взять там, где он ближе к пользователям.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Политики перезапуска и автозагрузка

Первое, что отличает продакшен-конфиг, — политика перезапуска у каждого сервиса. Без неё упавший контейнер так и останется лежать. Значение unless-stopped — оптимальный выбор: контейнер поднимается после сбоя и после перезагрузки сервера, но не стартует сам, если вы остановили его вручную. Вот базовый каркас compose.yaml:

services:
  web:
    image: myapp:1.4.0
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    env_file: .env
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:

Обратите внимание на две детали. Порт опубликован как 127.0.0.1:8080:8080 — сервис доступен только с самого хоста, а наружу его отдаёт реверс-прокси, а не Docker напрямую. И depends_on с условием service_healthy — приложение стартует лишь после того, как база прошла проверку здоровья, а не просто запустилась.

Лимиты ресурсов и проверки здоровья

Чтобы один сервис не съел всю память сервера и не уронил остальные, задайте лимиты. В Compose это делается блоком deploy.resources, который учитывается и при обычном запуске:

services:
  web:
    image: myapp:1.4.0
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "0.75"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 5s
      retries: 3

Лимит памяти 512M означает, что при превышении контейнер будет остановлен, а не утянет за собой весь сервер — это защищает соседей. Проверка здоровья healthcheck регулярно опрашивает эндпоинт приложения: если он перестал отвечать, Docker пометит контейнер нездоровым, и это увидят и depends_on, и ваш мониторинг. Без healthcheck контейнер считается живым, пока запущен его процесс, даже если приложение внутри давно висит.

Тома, переменные и секреты

Данные в продакшене должны переживать пересоздание контейнеров, поэтому всё важное складывают в именованные тома, а не внутрь контейнера. Базы, загрузки пользователей, состояние — всё в тома, объявленные в разделе volumes. При обновлении образа контейнер пересоздаётся, а том с данными остаётся на месте.

Секреты — отдельная тема. Пароли и ключи не место в самом compose-файле, который попадает в репозиторий. Выносите их в файл .env, который не коммитится, и подключайте через env_file. Проверьте, что этот файл закрыт от посторонних и исключён из системы контроля версий:

chmod 600 .env
echo ".env" >> .gitignore

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

Запуск, обновления и обслуживание

Запуск продакшен-стека выполняется в фоновом режиме флагом -d, а состояние проверяется отдельными командами:

docker compose up -d
docker compose ps
docker compose logs -f web

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

docker compose pull web
docker compose up -d web

Если новая версия сломалась, откат — это возврат тега образа на прежний в compose-файле и повторный up -d. Именно поэтому в продакшене фиксируют конкретные версии образов (myapp:1.4.0), а не тег latest: с latest вы не знаете, что именно развернулось, и не можете предсказуемо откатиться. Регулярно чистите неиспользуемые образы командой docker image prune, следите за местом на диске и держите мониторинг ресурсов. Когда контейнеров становится много и сервер стабильно у потолка по памяти, это честный сигнал взять VPS помощнее с быстрым NVMe — у MAATRIX апгрейд доступен без смены провайдера и с оплатой из России картой или криптой.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Частые вопросы

Какую политику перезапуска использовать в продакшене?

unless-stopped — контейнер поднимается после сбоя и перезагрузки сервера, но не стартует сам, если вы остановили его вручную.

Зачем нужны лимиты памяти для контейнеров?

Чтобы один сервис при утечке или всплеске не съел всю память и не уронил соседей: при превышении лимита останавливается только он.

Почему не стоит использовать тег latest на проде?

С latest вы не знаете, какая версия развернулась, и не можете предсказуемо откатиться; фиксируйте конкретные версии образов.

Как хранить пароли в Docker Compose?

Выносите их в некоммитящийся файл .env с правами 600 и подключайте через env_file, а для повышенной защиты используйте механизм секретов Docker.

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.