📝 Docker

Docker Compose: продвинутые возможности

P
Автор
Pyland
📅
Опубликовано
30.06.2026
⏱️
Время чтения
3 мин
👁️
Просмотров
76
🌳
Уровень
Продвинутый
🐦 💼 ✈️

Базовый docker-compose.yml — это старт. Для production нужны healthcheck, профили, override-файлы и управление ресурсами.

healthcheck для depends_on

По умолчанию depends_on гарантирует только запуск контейнера, но не готовность сервиса. Postgres может стартовать, но ещё принимать соединения. Решение — healthcheck.

services:
  db:
    image: postgres:15
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 5s       # как часто проверять
      timeout: 3s        # таймаут одной проверки
      retries: 5         # сколько раз повторить
      start_period: 10s  # пауза перед первой проверкой

  web:
    build: .
    depends_on:
      db:
        condition: service_healthy   # ждать healthcheck

Варианты condition:
- service_started — контейнер запущен (по умолчанию)
- service_healthy — прошёл healthcheck
- service_completed_successfully — завершился с кодом 0 (для init-контейнеров)

Примеры healthcheck для разных сервисов:

# Redis
healthcheck:
  test: ["CMD", "redis-cli", "ping"]
  interval: 5s
  timeout: 3s
  retries: 3

# HTTP-сервис
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
  interval: 10s
  timeout: 5s
  retries: 3
  start_period: 30s

profiles: dev/prod конфигурации

Profiles позволяют определить сервисы, которые запускаются только в конкретных сценариях.

services:
  web:
    build: .
    ports:
      - "8000:8000"
    # Без профиля — запускается всегда

  db:
    image: postgres:15
    # Без профиля — запускается всегда

  pgadmin:
    image: dpage/pgadmin4
    profiles: [dev]          # только в dev
    ports:
      - "5050:80"

  mailhog:
    image: mailhog/mailhog
    profiles: [dev]          # только в dev
    ports:
      - "8025:8025"

  nginx:
    image: nginx:alpine
    profiles: [prod]         # только в prod
    ports:
      - "80:80"
      - "443:443"
# Запуск только базовых сервисов
docker compose up -d

# Запуск с dev-профилем
docker compose --profile dev up -d

# Несколько профилей
docker compose --profile dev --profile monitoring up -d

Override: docker-compose.override.yml

Docker Compose автоматически загружает docker-compose.override.yml и мержит его с основным файлом. Удобно для локальных настроек разработчика.

# docker-compose.yml — общий, коммитится в git
services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      LOG_LEVEL: info

  db:
    image: postgres:15
# docker-compose.override.yml — локальный, в .gitignore
services:
  web:
    volumes:
      - .:/app          # live reload: монтируем код в контейнер
    environment:
      LOG_LEVEL: debug
      DEBUG: "true"
    command: python manage.py runserver 0.0.0.0:8000

  db:
    ports:
      - "5432:5432"     # в dev: postgres доступен с хоста

Явное указание файлов:

# Использовать конкретные файлы
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# Только основной файл (без автоматического override)
docker compose -f docker-compose.yml up -d

Переменные и интерполяция ${VAR}

# docker-compose.yml
services:
  web:
    image: ${REGISTRY:-docker.io}/${IMAGE_NAME}:${IMAGE_TAG:-latest}
    ports:
      - "${APP_PORT:-8000}:8000"
    deploy:
      replicas: ${WEB_REPLICAS:-1}

Синтаксис подстановок:
- ${VAR} — значение переменной, ошибка если не задана
- ${VAR:-default} — значение или дефолт если не задана
- ${VAR:?error message} — ошибка с сообщением если не задана

# Проверить итоговую конфигурацию после подстановок
docker compose config

deploy: ресурсы и реплики

Секция deploy управляет распределением ресурсов (актуально для Docker Swarm и Compose v3+, частично работает в локальном Compose).

services:
  web:
    build: .
    deploy:
      replicas: 3               # количество копий сервиса
      update_config:
        parallelism: 1          # обновлять по одной реплике
        delay: 10s              # пауза между репликами
      restart_policy:
        condition: on-failure
        max_attempts: 3
      resources:
        limits:
          cpus: "0.5"           # не более 50% одного ядра
          memory: 512M          # не более 512 МБ RAM
        reservations:
          cpus: "0.1"
          memory: 128M

  db:
    image: postgres:15
    deploy:
      resources:
        limits:
          memory: 1G
        reservations:
          memory: 256M

Лимиты ресурсов — важная защита от ситуации, когда один контейнер “съедает” всю память хоста.

Команды управления

# Запуск
docker compose up -d                   # запустить в фоне
docker compose up -d --build           # с пересборкой образов
docker compose up -d web db            # только конкретные сервисы

# Остановка
docker compose down                    # остановить и удалить контейнеры
docker compose down -v                 # также удалить volumes
docker compose down --rmi local        # также удалить локальные образы
docker compose stop web                # остановить сервис без удаления

# Логи
docker compose logs -f                 # все логи в реальном времени
docker compose logs -f web             # логи конкретного сервиса
docker compose logs --tail=100 web     # последние 100 строк

# Выполнение команд
docker compose exec web bash           # войти в контейнер
docker compose exec web python manage.py migrate
docker compose run --rm web pytest     # запустить одноразовый контейнер

# Масштабирование
docker compose up -d --scale web=3    # запустить 3 копии web

# Информация
docker compose ps                      # статус всех сервисов
docker compose top                     # процессы внутри контейнеров
docker compose images                  # образы сервисов
docker compose port web 8000           # узнать проброшенный порт

Полный пример: production-like стек

version: "3.8"

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      web:
        condition: service_healthy
    profiles: [prod]

  web:
    build: .
    image: ${IMAGE_NAME:-myapp}:${IMAGE_TAG:-latest}
    environment:
      DATABASE_URL: postgresql://${DB_USER}:${DB_PASS}@db:5432/${DB_NAME}
      SECRET_KEY: ${SECRET_KEY}
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 20s
    deploy:
      replicas: ${WEB_REPLICAS:-2}
      resources:
        limits:
          cpus: "1.0"
          memory: 512M

  db:
    image: postgres:15
    environment:
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASS}
      POSTGRES_DB: ${DB_NAME}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
      interval: 5s
      timeout: 3s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 1G

volumes:
  pgdata:

Ваша реакция на статью

💬 Комментарии (0)

🔐 Войдите в систему, чтобы оставить комментарий
🚪 Войти
💭

Комментариев пока нет

Станьте первым, кто поделится мнением об этой статье!

🔗 Похожие

Похожие статьи

Продолжите изучение с этими материалами

📝

Деплой FastAPI с Docker

Или Railway автоматически найдёт Dockerfile.

📅 30.06.2026 👁️ 83
📝

Multi-stage builds: уменьшаем Docker-образ

Большой образ — это медленная загрузка, больше места на диске и большая поверхность атаки. Multi-stage...

📅 30.06.2026 👁️ 79
📝

Docker Networking: как контейнеры общаются

Контейнеры изолированы, но часто должны взаимодействовать друг с другом и с внешним миром. Docker решает...

📅 30.06.2026 👁️ 78

Понравилась статья?

Подпишитесь на наши обновления и получайте новые статьи первыми. Развивайтесь вместе с PyLand!