ЯдроКодаподготовка к экзаменам
Учебная платформа

Загружаем материалы

Подготавливаем материалы и навигацию по разделу.

Docker Compose на VPS: обновление, HTTPS и откат

Автор: · Обновлено

Развёртывание на VPS начинается с готового проверенного образа, постоянных данных и понятного пути назад. Compose подходит для управления приложением на одном Engine, но сам по…

Развёртывание на VPS начинается с готового проверенного образа, постоянных данных и понятного пути назад. Compose подходит для управления приложением на одном Engine, но сам по себе не даёт кластерной отказоустойчивости и не обещает обновление без разрыва соединений. Составим процедуру, которую можно сначала проверить на отдельном стенде.

Разделить артефакт и данные

На сервере используйте образ из registry с проверенным digest или управляемым release tag. Конфигурация, секреты, том базы и резервные копии живут отдельно от образа. Сохраните предыдущую конфигурацию и идентификатор артефакта до обновления. Если приложению нужна миграция схемы, заранее проверьте совместимость старой версии с новой схемой.

Простой локальный тренировочный Compose-файл позволяет увидеть последовательность без подключения к чужому серверу:

name: yk-deploy-demo
services:
  web:
    image: ${WEB_IMAGE:?set a tested image reference}
    ports:
      - "127.0.0.1:18083:80"
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://127.0.0.1/ >/dev/null"]
      interval: 5s
      timeout: 3s
      retries: 5

Для опыта установите в .env WEB_IMAGE=nginx:1.28-alpine. Этот тег нужен для первого локального запуска, а для реального релиза замените его проверенным образом и зафиксируйте digest. docker compose config -q должен пройти до изменения работающего сервиса.

Повторяемая последовательность обновления

docker compose pull web
docker compose up -d --wait --wait-timeout 90 web
docker compose ps
curl -f http://127.0.0.1:18083/
docker compose logs --tail 100 --since 5m web

Pull получает артефакт до пересоздания. Up применяет конфигурацию и ждёт готовности в пределах указанного времени. Не называйте деплой успешным только по коду pull: приложение ещё не стартовало. Поведение up.

Если проверка не прошла, сохраните логи и статус, верните прежний IMAGE_REF/WEB_IMAGE и выполните ту же последовательность запуска. Откат образа не откатывает данные автоматически. Если новая версия уже записала несовместимый формат или необратимую миграцию, возврат старого процесса может усугубить проблему. Для такого изменения нужен проверенный план данных и восстановление.

Где HTTPS и доступ к базе

В публичном окружении reverse proxy принимает 80/443 и передаёт запрос приложению во внутренней сети. Caddy может управлять сертификатами при корректном DNS и доступности challenge; Nginx требует выбранного механизма выпуска/обновления. У Caddy сохраните его данные сертификатов в предусмотренном томе, чтобы пересоздание не теряло состояние. Условия automatic HTTPS.

Не публикуйте порт базы всему Интернету только ради связи между сервисами: используйте внутреннее имя и порт. Административный доступ организуйте через доверенный путь, например SSH-туннель. Сам Docker API также должен быть защищён; открытый socket daemon даёт намного больше возможностей, чем доступ к одной веб-странице.

Локальный Nginx с TLS: полный проверяемый пример

Перед настройкой публичного домена полезно проверить сертификат и mount локально. В отдельной папке создайте краткоживущий самоподписанный сертификат только для localhost. В Bash с OpenSSL:

mkdir -p tls
openssl req -x509 -newkey rsa:2048 -sha256 -nodes -days 2 -keyout tls/localhost.key -out tls/localhost.crt -subj '/CN=localhost' -addext 'subjectAltName=DNS:localhost'
chmod 600 tls/localhost.key

Это локальный лабораторный ключ, не сертификат публичного сайта. Не переносите его в production и не отправляйте никому приватный файл. -nodes оставляет ключ без парольного шифрования, чтобы Nginx мог стартовать без диалога; доступ ограничивается правами файла. OpenSSL req.

Сохраните https.conf:

server {
    listen 443 ssl;
    server_name localhost;
    ssl_certificate /etc/nginx/tls/localhost.crt;
    ssl_certificate_key /etc/nginx/tls/localhost.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    location = /healthz {
        default_type text/plain;
        return 200 "tls ready\n";
    }
}

Проверим синтаксис, затем запустим отдельный контейнер:

docker run --rm --mount "type=bind,src=$(pwd)/https.conf,dst=/etc/nginx/conf.d/default.conf,readonly" --mount "type=bind,src=$(pwd)/tls,dst=/etc/nginx/tls,readonly" nginx:1.28-alpine nginx -t
docker run -d --name yk-tls-demo -p 127.0.0.1:18443:443 --mount "type=bind,src=$(pwd)/https.conf,dst=/etc/nginx/conf.d/default.conf,readonly" --mount "type=bind,src=$(pwd)/tls,dst=/etc/nginx/tls,readonly" nginx:1.28-alpine
curl --cacert tls/localhost.crt https://localhost:18443/healthz

Ожидается tls ready. --cacert явно доверяет учебному сертификату и сохраняет проверку имени хоста; curl -k эту проверку обходит и не является доказательством корректного TLS. После опыта остановите и удалите yk-tls-demo, а учебный приватный ключ не храните в репозитории.

Для публичного домена нужны сертификат доверенного центра, соответствующее имя в SAN, полная цепочка и автоматическое продление через выбранный ACME-клиент. Смонтируйте управляемую директорию сертификатов read-only, настройте проверяемый renewal и reload Nginx после успешного nginx -t. При bind mount отдельных файлов замена сертификата через новый inode может не появиться внутри уже работающего контейнера; mount каталога и проверка фактического сертификата уменьшают эту неоднозначность. Настройка HTTPS Nginx.

Что проверить до первого рабочего обновления

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

В production обычно убирают bind mount исходников и используют отдельную конфигурацию эксплуатации. Рекомендации Compose помогают разделить среды, но итоговый docker compose config нужно просмотреть для конкретного проекта.

Практика отката

На локальном одноразовом стенде сначала сохраните рабочий образ, затем задайте заведомо несуществующий тег и убедитесь, что ошибка pull обнаруживается до изменения сервиса. После этого испытайте образ, который запускается, но не проходит healthcheck, и верните рабочую версию. Запишите время восстановления и оставшиеся данные. Полученный регламент должен объяснять и успешный путь, и отказ, не используя down -v как способ «начать заново» с реальной базой.

Источники