Содержание
Зачем нужен Docker Compose
В реальных приложениях несколько сервисов: бэкенд, фронтенд, база данных, Redis, очередь задач. Запускать каждый вручную через docker run — неудобно. Compose описывает все сервисы в одном файле и запускает их одной командой. (Основы — в гайде Docker для новичка, образы — в статье про Dockerfile.)
Структура docker-compose.yml
version: '3.9'
services: # Список сервисов (контейнеров)
app:
build: .
ports:
- "3000:3000"
networks: # Кастомные сети (опционально)
backend:
volumes: # Именованные тома для хранения данных
pgdata:
Полный пример: приложение + PostgreSQL + Redis
version: '3.9'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
NODE_ENV: production
DATABASE_URL: postgres://user:secret@db:5432/myapp
REDIS_URL: redis://cache:6379
depends_on:
db:
condition: service_healthy # Ждём пока база готова
cache:
condition: service_started
networks:
- backend
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d myapp"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
cache:
image: redis:7-alpine
volumes:
- redisdata:/data
networks:
- backend
networks:
backend:
driver: bridge
volumes:
pgdata:
redisdata:
Переменные окружения через .env
Не хардкоди секреты прямо в docker-compose.yml. Используй .env файл (и не забудь добавить его в .gitignore):
# .env
POSTGRES_USER=user
POSTGRES_PASSWORD=supersecret
POSTGRES_DB=myapp
APP_PORT=3000
# docker-compose.yml
services:
db:
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
app:
ports:
- "${APP_PORT}:3000"
⚠️ Добавь
.envв.gitignore! Для CI/CD используй.env.exampleс заглушками.
Health checks — ждём готовности сервиса
Без depends_on + condition бэкенд стартует раньше чем поднимется база, получает ошибку подключения и падает.
db:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s # Проверять каждые 10 сек
timeout: 5s # Таймаут одной проверки
retries: 5 # После 5 неудач — unhealthy
start_period: 30s # Не считать неудачи первые 30 сек
Профили — разные конфигурации для dev и prod
services:
app:
build: .
# Без профиля — запускается всегда
pgadmin:
image: dpage/pgadmin4
profiles:
- dev # Только в dev-режиме
ports:
- "5050:80"
nginx:
image: nginx:alpine
profiles:
- prod # Только в продакшне
# Запустить только dev-профиль
docker-compose --profile dev up -d
# Запустить prod-профиль
docker-compose --profile prod up -d
Основные команды
# Запустить всё в фоне
docker-compose up -d
# Посмотреть логи всех сервисов
docker-compose logs -f
# Логи конкретного сервиса
docker-compose logs -f app
# Выполнить команду в запущенном контейнере
docker-compose exec app sh
# Остановить без удаления данных
docker-compose stop
# Остановить и удалить контейнеры (данные в volumes остаются)
docker-compose down
# Удалить всё включая volumes (ОСТОРОЖНО — удалит данные БД!)
docker-compose down -v
💡 Для локальной разработки создай
docker-compose.override.yml— он автоматически мержится с основным файлом и позволяет монтировать код для hot-reload без изменения основного compose-файла.
Обсуждение
Пока нет комментариев. Будьте первым.