Docker Compose — это инструмент для описания и запуска многоконтейнерных приложений с помощью единого конфигурационного файла (обычно
docker-compose.yml
Основная идея
Вместо того чтобы вручную запускать каждый контейнер и связывать их сетью и томами, вы описываете всю инфраструктуру приложения в YAML-файле:
- Сервисы (services) — отдельные контейнеры с указанием образа или .
Dockerfile
- Сети (networks) — как контейнеры будут общаться друг с другом.
- Тома (volumes) — куда сохраняются данные.
- Переменные окружения (environment) — настройки для каждого сервиса.
- Порты (ports) — маппинг между хостом и контейнером.
Пример конфигурации
version: "3.9" services: app: build: . ports: - "8080:8080" environment: DB_HOST: db DB_USER: appuser depends_on: - db db: image: postgres:16-alpine environment: POSTGRES_USER: appuser POSTGRES_PASSWORD: secret POSTGRES_DB: appdb volumes: - db_data:/var/lib/postgresql/data volumes: db_data:
Ключевые возможности
- Быстрый запуск окружений— и всё приложение поднимается за один шаг.
docker compose up -d
- Локальная разработка
Легко эмулировать продакшн-среду у каждого разработчика. - Версионирование конфигурации
Файлхранится в Git, что делает конфигурацию воспроизводимой.docker-compose.yml
- Изоляция окружений
Каждое окружение (dev, test, stage) может иметь свой compose-файл или override.
Практические приёмы
- Override-файлы () — для настройки параметров в dev-режиме (маппинг исходников, hot-reload).
docker-compose.override.yml
- .env файл — вынос чувствительных данных и параметров окружения.
- Профили (profiles) — запуск только нужных сервисов ().
docker compose --profile debug up
- Мульти-stage build в связке с Compose для оптимизации образов.
- Поддержка нескольких файлов:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
Интеграция с другими инструментами
- Docker Swarm — можно масштабировать сервисы на нескольких узлах с теми же конфигами.
- CI/CD — автоматический запуск Compose-окружения для тестов.
- Kubernetes — через утилиты типа Kompose можно конвертировать в манифесты K8s.
docker-compose.yml
Безопасность и удобство
- Не храните пароли прямо в YAML — используйте или секреты (
.env
).docker secrets
- Для production лучше разделять образы и конфиги, избегая dev-инструментов в рантайме.
- Мониторьте версии образов и регулярно пересобирайте сервисы.
Для чего это клиенту
Compose делает инфраструктуру приложения прозрачной, воспроизводимой и управляемой. Клиент или команда разработки получают среду, которую можно поднять на любом компьютере или сервере за минуты, без «сюрпризов» в настройках. Это сокращает время на развёртывание, упрощает онбординг новых сотрудников и минимизирует человеческий фактор.
Вот компактный продакшн‑шаблон
docker-compose.yml
version: "3.9" x-common-env: &common_env TZ: "UTC" APP_ENV: "production" # секреты/пароли — через .env или secrets, а не в YAML x-common-deploy: &common_deploy restart: always # Ограничения ресурсов (примерные значения — подберите по нагрузке) deploy: resources: limits: cpus: "1.0" memory: "512M" reservations: cpus: "0.25" memory: "256M" networks: edge: driver: bridge backend: driver: bridge internal: true # недоступна извне хоста volumes: db_data: caddy_data: # для certmagic (автосертификаты) caddy_config: secrets: db_password: file: ./secrets/db_password.txt services: reverse-proxy: image: caddy:2.8 command: caddy run --config /etc/caddy/Caddyfile --adapter caddyfile ports: - "80:80" - "443:443" environment: <<: *common_env volumes: - ./ops/caddy/Caddyfile:/etc/caddy/Caddyfile:ro - caddy_data:/data - caddy_config:/config depends_on: - web networks: - edge - backend <<: *common_deploy healthcheck: test: ["CMD-SHELL", "wget -qO- http://web:8080/health || exit 1"] interval: 30s timeout: 5s retries: 3 web: build: context: . dockerfile: Dockerfile target: runtime # используйте multi-stage build environment: <<: *common_env DATABASE_HOST: db DATABASE_USER: app_user DATABASE_PASSWORD_FILE: /run/secrets/db_password DATABASE_NAME: app # Логирование LOG_LEVEL: info secrets: - db_password expose: - "8080" # видим только в сети backend depends_on: db: condition: service_healthy networks: - backend <<: *common_deploy healthcheck: test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"] interval: 20s timeout: 3s retries: 5 db: image: postgres:16-alpine environment: <<: *common_env POSTGRES_DB: app POSTGRES_USER: app_user POSTGRES_PASSWORD_FILE: /run/secrets/db_password # Безопасные дефолты: отключите авто‑создание экстеншенов, ограничьте локали и т.п. — по нужде secrets: - db_password volumes: - db_data:/var/lib/postgresql/data expose: - "5432" # только в backend networks: - backend <<: *common_deploy healthcheck: test: ["CMD-SHELL", "pg_isready -U app_user -d app -h localhost"] interval: 15s timeout: 5s retries: 5 # Доп. защита: read_only & tmpfs (сложно с БД, используйте на stateless-сервисах)
Файл ops/caddy/Caddyfile
(пример с автоматическим TLS и проксированием)
ops/caddy/Caddyfile
example.com, www.example.com { encode zstd gzip log { output stdout format json } handle_path /health { respond 200 } reverse_proxy web:8080 { health_uri /health trusted_proxies 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 } # базовые заголовки безопасности header { Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" X-Content-Type-Options "nosniff" Referrer-Policy "no-referrer" X-Frame-Options "DENY" } }
Рекомендации к продакшн‑использованию
- Секреты: храните в , доступ ограничьте правами ОС. Для облака — лучше менеджер секретов (AWS/GCP/Azure).
./secrets/…
- .env: выносите не чувствительные параметры (порты, флаги фич). Не лепите туда пароли.
- Образы: используйте multi‑stage builds, distroless/‑slim; запускайте процесс от непривилегированного пользователя ().
USER
- Логи: JSON‑формат; централизуйте сбор (ELK/Vector/Loki) через драйверы логирования или sidecar/агенты.
- Здоровье: поддерживайте реальные ‑эндпойнты на web; для БД —
health
/pg_isready
.mysqladmin ping
- Сети: внешние порты открывайте только на reverse‑proxy. Внутренние сервисы держите в сети.
internal
- Резервирование: бэкапы БД вне контейнера, регулярные тесты восстановления (backup verification).
- Обновления: пересобирайте образы на патчи базового слоя; фиксируйте версии и используйте digest ().
image@sha256:…
- Безопасность: включайте и
readonly
для stateless‑сервисов,tmpfs
,no-new-privileges
(где возможно).cap_drop: ["ALL"]