docker-compose.yml — синтаксис, примеры, все параметры

docker-compose.yml — декларативный файл конфигурации. Описываешь какие сервисы должны работать, как они связаны и настроены — Docker запускает всё одной командой.

Вся рубрика Docker: уроки, команды и практические сценарии

Структура файла

version: "3.9"  # версия схемы Compose (необязательно в v2+)

services:       # контейнеры (сервисы)
  app:
    ...
  db:
    ...

volumes:        # именованные volumes
  pgdata:

networks:       # пользовательские сети
  backend:
  frontend:

Параметры сервиса — полный справочник

services:
  app:
    # Использовать готовый образ из Docker Hub
    image: nginx:latest

    # ИЛИ собрать из Dockerfile
    build:
      context: .                     # папка с Dockerfile
      dockerfile: Dockerfile.prod    # имя файла (по умолчанию Dockerfile)
      args:
        NODE_VERSION: 20             # аргументы сборки

    # Имя контейнера (по умолчанию: project_service_1)
    container_name: my-app

    # Проброс портов: HOST:CONTAINER
    ports:
      - "80:80"
      - "443:443"
      - "127.0.0.1:8080:80"  # только localhost

    # Переменные окружения
    environment:
      - NODE_ENV=production
      - DB_HOST=db           # имя сервиса как hostname
    # Или в виде словаря
    environment:
      NODE_ENV: production
      DB_HOST: db

    # Переменные из файла
    env_file:
      - .env
      - .env.production

    # Volumes
    volumes:
      - ./app:/app                   # bind mount
      - nodemodules:/app/node_modules # named volume
      - ./config:/app/config:ro      # только чтение

    # Сети
    networks:
      - frontend
      - backend

    # Зависимости — запустить после db
    depends_on:
      db:
        condition: service_healthy   # ждать healthcheck

    # Политика перезапуска
    restart: unless-stopped
    # no | always | on-failure | unless-stopped

    # Переопределить CMD
    command: ["npm", "start"]

    # Переопределить ENTRYPOINT
    entrypoint: ["/docker-entrypoint.sh"]

    # Лимиты ресурсов
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
        reservations:
          memory: 256M

depends_on и healthcheck

services:
  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s     # проверять каждые 10 секунд
      timeout: 5s       # таймаут одной проверки
      retries: 5        # считать unhealthy после 5 провалов
      start_period: 30s # не считать провалы первые 30 секунд

  app:
    image: myapp
    depends_on:
      db:
        condition: service_healthy  # ждать пока db пройдёт healthcheck
    # Без condition: service_healthy — app может стартовать до готовности db!

Полный пример — Flask + PostgreSQL + Nginx

version: "3.9"

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - app
    networks:
      - frontend
    restart: unless-stopped

  app:
    build: .
    env_file: .env
    volumes:
      - ./app:/app
    depends_on:
      db:
        condition: service_healthy
    networks:
      - frontend
      - backend
    restart: unless-stopped

  db:
    image: postgres:16
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U myuser -d mydb"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - backend
    restart: unless-stopped

volumes:
  pgdata:

networks:
  frontend:
  backend:

Profiles — разные конфигурации

services:
  app:
    image: myapp
    # Без профиля — запускается всегда

  debug-tools:
    image: busybox
    profiles: ["debug"]
    # Запускается только с флагом --profile

  mailhog:
    image: mailhog/mailhog
    profiles: ["dev"]
    ports:
      - "8025:8025"
# Запустить с профилем
docker compose --profile debug up -d
docker compose --profile dev up -d

Override файлы — dev vs prod

# docker-compose.yml — базовая конфигурация
# docker-compose.override.yml — применяется АВТОМАТИЧЕСКИ поверх
# docker-compose.prod.yml — для продакшена

# docker-compose.override.yml (для разработки)
services:
  app:
    volumes:
      - .:/app          # bind mount с кодом
    command: flask run --debug --host=0.0.0.0
    environment:
      FLASK_ENV: development

  mailhog:
    image: mailhog/mailhog
    ports:
      - "8025:8025"
# Применить конкретный файл
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Часто задаваемые вопросы

Что значит version в docker-compose.yml?

Версия схемы Compose-файла (не версия Docker Compose). version: "3.9" — означает синтаксис Compose specification v3.9. В Docker Compose v2 (плагин) поле version необязательно и может быть опущено — используется актуальная спецификация. Для максимальной совместимости оставь version: "3.9" — работает везде.

Как передать secrets в docker-compose?

Три способа: 1) .env файл (простой): env_file: .env — не коммить .env в git. 2) Docker secrets (для Docker Swarm): secrets: секция в compose-файле. 3) Переменные в среде CI/CD — передать через -e или через secrets GitHub/GitLab. Никогда не хардкодь пароли прямо в docker-compose.yml если файл в git.

depends_on не ждёт готовности базы данных — почему?

По умолчанию depends_on ждёт только запуска контейнера — не готовности приложения внутри. База запустилась, но PostgreSQL ещё инициализируется — app уже пытается подключиться. Решение: добавить healthcheck для db и использовать condition: service_healthy в depends_on. Тогда app стартует только после того как pg_isready вернёт 0.

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x