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

- Структура файла
- Параметры сервиса — полный справочник
- depends_on и healthcheck
- Полный пример — Flask + PostgreSQL + Nginx
- Profiles — разные конфигурации
- Override файлы — dev vs prod
- Часто задаваемые вопросы
- Что значит version в docker-compose.yml?
- Как передать secrets в docker-compose?
- depends_on не ждёт готовности базы данных — почему?
- Что читать дальше по 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.
Что читать дальше по Docker
Чтобы связать тему с соседними практическими материалами, дальше удобно открыть:
- Docker Compose — посмотреть общий сценарий запуска через Compose.
- Docker volumes — описать постоянные данные.
- Docker network — настроить сети между сервисами.
- Python Flask в Docker — применить файл Compose в Flask-проекте.



