Подготовка к продакшену: что важно учесть

Рейтинг: 78.5% · 14 голосов
Практический курс по Docker: образы, контейнеры, тома, сети, Compose и продакшен. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
Marina_DevOps
Сообщения: 25
Зарегистрирован: 11 май 2026, 05:31

Подготовка к продакшену: что важно учесть

Сообщение Marina_DevOps »

АкадемияDocker с нуляГлава 12 из 17
Оглавление курса (17)
  1. Что такое Docker и какие задачи он решает
  2. Установка Docker и запуск первого контейнера
  3. Образы: слои, теги и реестр Docker Hub
  4. Пишем свой Dockerfile
  5. Тома и хранение данных: volumes и bind mounts
  6. Сети в Docker: связываем контейнеры между собой
  7. Переменные окружения и конфигурация контейнеров
  8. Docker Compose: поднимаем многоконтейнерное приложение
  9. Оптимизация образов: multi-stage сборка, размер и кэш слоёв
  10. Логи, отладка и мониторинг контейнеров
  11. Базовая безопасность контейнеров
  12. Подготовка к продакшену: что важно учесть (вы здесь)
  13. Dockerfile глубже: ENTRYPOINT и CMD, HEALTHCHECK, .dockerignore, запуск не от root
  14. Реестры образов: приватные registry, push и pull, теги и digest, imagePullSecrets
  15. BuildKit и buildx: multi-arch сборки, секреты сборки, экспорт кэша
  16. Docker в CI/CD: автосборка, сканирование образов (Trivy, Docker Scout), публикация
  17. Итоговый проект и куда расти: от Dockerfile до прода, обзор оркестрации (Kubernetes, Podman, OCI)
За одиннадцать глав мы прошли путь от docker run hello-world до многоконтейнерного стека с Compose, сетями и томами. Осталось главное: довести всё это до состояния, когда выкатить на боевой сервер не страшно. Эта глава, по сути, чеклист отличий прода от локальной машины.

Фиксируйте версии образов:

Тег latest на проде это мина. Сегодня за ним стоит одна версия, после очередного docker compose pull уже другая, и сервис ведёт себя не так, как вчера. Указывайте точный тег, а свои образы собирайте в CI и тегируйте номером версии или хэшем коммита.

Код: Выделить всё

# плохо
image: nginx:latest

# хорошо
image: nginx:1.28.0
image: cr.yandex/crp9f3k2/shop-api:1.4.2
Рестарты, healthcheck, лимиты и логи:

Контейнер должен сам подниматься после падения процесса и после перезагрузки сервера, за это отвечает restart: unless-stopped. Но рестарт не спасает, когда процесс жив, а приложение зависло. Для этого есть healthcheck. Соберём типичный прод-сервис целиком:

Код: Выделить всё

services:
  api:
    image: cr.yandex/crp9f3k2/shop-api:1.4.2
    restart: unless-stopped
    stop_grace_period: 30s
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 20s
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "1.0"
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
Пара уточнений. Сам по себе Docker unhealthy контейнер не перезапускает, статус виден в docker ps, им пользуются оркестраторы и мониторинг (глава 10). Если в образе нет curl, добавьте его в Dockerfile или проверяйте здоровье маленьким скриптом самого приложения. Лимит памяти подбирайте по docker stats под нагрузкой плюс запас процентов 30-50: без лимита потёкший сервис съест всю память машины, и OOM killer прибьёт кого попало, иногда базу.

Логи без max-size за пару месяцев забивают диск, /var/lib/docker разрастается до десятков гигабайт. Лимит можно задать и глобально в /etc/docker/daemon.json, после правки нужен systemctl restart docker, и настройка коснётся только новых контейнеров.

Код: Выделить всё

{
  "log-driver": "json-file",
  "log-opts": { "max-size": "10m", "max-file": "3" }
}
Graceful shutdown:

При docker stop контейнер получает SIGTERM, а через 10 секунд (или stop_grace_period) уже SIGKILL. Чтобы приложение успело закрыть соединения и дописать данные, нужны два условия: оно обрабатывает SIGTERM в коде и реально его получает. Со вторым часто подводит shell-форма CMD:

Код: Выделить всё

# shell-форма: PID 1 будет /bin/sh, сигнал до node не дойдёт
CMD node server.js

# exec-форма: node сам PID 1 и получит SIGTERM
CMD ["node", "server.js"]
Секреты и данные:

Файл .env с паролями живёт только на сервере, с правами 600, и обязательно прописан в .gitignore и .dockerignore. Помните из главы 7: переменные окружения видны через docker inspect любому, у кого есть доступ к демону. Для чувствительных систем смотрите в сторону Vault или docker secrets. Всё ценное храните в named volumes (глава 5) и бэкапьте: контейнер расходный материал, том нет. Базы бэкапьте штатными средствами вроде pg_dump, а не копированием каталога у живого постгреса.

Типичные грабли:

Сборка образа прямо на боевом сервере. Билд отъедает CPU и память у работающих сервисов и плохо воспроизводится. Собирайте в CI или хотя бы на отдельной машине, на прод только docker compose pull.

docker compose down -v. Флаг -v сносит тома вместе с базой. На проде эту комбинацию лучше не набирать вообще.

Открытые наружу порты. Запись ports: "5432:5432" вешает постгрес на все интерфейсы, причём Docker правит iptables напрямую и спокойно обходит ufw. Внутренним сервисам публикация портов не нужна вовсе, они общаются по сети Compose (глава 6). Если порт нужен только локально, привязывайте явно: "127.0.0.1:5432:5432".

Root в контейнере. Про USER и read-only мы говорили в главе 11. Перед выкаткой проверьте, что это не осталось "на потом".

Что усвоили:

Прод отличается от локалки дисциплиной: точные теги, рестарт-политики, healthcheck, лимиты ресурсов, ротация логов, корректное завершение, закрытые порты и бэкапы томов. На этом курс закончен. Дальше идут оркестрация (Docker Swarm или Kubernetes) и автоматизация выкаток через CI/CD, но и без них вы уже способны уверенно держать на Docker небольшой боевой проект.
👍4 ❤️1 🔥1 😄 🤔1
✔ Лучший ответ сформирован автоматически — laigle
Marina_DevOps писал(а):Сам по себе Docker unhealthy контейнер не перезапускает и какой тогда смысл в healthcheck, если оркестратора нет? нашел контейнер willfarrell/autoheal, который рестартит unhealthy сам. это нормальная практика для прода или костыль и лучше сразу учить swarm?
Перейти к ответу →
Аватара пользователя
laigle
Сообщения: 1
Зарегистрирован: 16 май 2026, 11:06

Re: Подготовка к продакшену: что важно учесть

Сообщение laigle »

✔ Лучший ответ — сформирован автоматически
Marina_DevOps писал(а):Сам по себе Docker unhealthy контейнер не перезапускает
и какой тогда смысл в healthcheck, если оркестратора нет? нашел контейнер willfarrell/autoheal, который рестартит unhealthy сам. это нормальная практика для прода или костыль и лучше сразу учить swarm?
👍3 ❤️1 🔥 😄 🤔
Аватара пользователя
tomlin51
Сообщения: 2
Зарегистрирован: 13 май 2026, 10:13

Re: Подготовка к продакшену: что важно учесть

Сообщение tomlin51 »

дочитал все 12 глав, спасибо за курс. отдельный респект за кусок про shell-форму CMD. у нас воркеры очереди умирали посреди задачи при каждом деплое, неделю грешили на rabbitmq, а оказалось ровно это, sh глотал SIGTERM
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
cliffp
Сообщения: 1
Зарегистрирован: 02 июн 2026, 07:54

Re: Подготовка к продакшену: что важно учесть

Сообщение cliffp »

подтверждаю про ufw, это не теория. у меня редис торчал наружу полгода, узнал только когда увидел в логах чужой FLUSHALL. с тех пор во всех compose только 127.0.0.1 в ports и после деплоя прогоняю nmap с другой машины
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
muttdogg
Сообщения: 2
Зарегистрирован: 12 май 2026, 18:08

Re: Подготовка к продакшену: что важно учесть

Сообщение muttdogg »

а если сервер один и CI нет? проект маленький, vps за 600р в месяц, поднимать отдельную машину под сборку жаба душит. собирать ночью когда трафика нет, или есть вариант получше?
👍2 ❤️2 🔥 😄 🤔
Ответить
← Предыдущая глава
Базовая безопасность контейнеров
Следующая глава →
Dockerfile глубже: ENTRYPOINT и CMD, HEALTHCHECK, .dockerignore, запуск не от root

Все главы курса «Docker с нуля»

Поделиться темой: ✈ Telegram VK

Вернуться в «Docker с нуля»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей