Антон Ларичев

Введение
Docker Compose для разработки стал стандартным инструментом в арсенале современного разработчика. Вместо того чтобы вручную устанавливать PostgreSQL, Redis и RabbitMQ на локальную машину, вы описываете всё окружение в одном YAML-файле и запускаете одной командой.
В этой статье мы соберём полноценное окружение для разработки с базой данных, кешем и очередью сообщений. Весь процесс займёт не больше 10 минут, а результатом станет воспроизводимая конфигурация, которую можно передать любому члену команды.
Структура compose.yaml: описание сервисов
Современная спецификация Docker Compose рекомендует использовать файл compose.yaml вместо устаревшего docker-compose.yml. Поле version больше не требуется. Начнём с базовой структуры:
services:
postgres:
image: postgres:17
container_name: dev-postgres
restart: unless-stopped
environment:
POSTGRES_USER: ${DB_USER:-devuser}
POSTGRES_PASSWORD: ${DB_PASSWORD:-devpass}
POSTGRES_DB: ${DB_NAME:-devdb}
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-devuser}"]
interval: 5s
timeout: 3s
retries: 5
redis:
image: redis:7-alpine
container_name: dev-redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redisdata:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
rabbitmq:
image: rabbitmq:4-management
container_name: dev-rabbitmq
restart: unless-stopped
environment:
RABBITMQ_DEFAULT_USER: ${RABBIT_USER:-guest}
RABBITMQ_DEFAULT_PASS: ${RABBIT_PASSWORD:-guest}
ports:
- "5672:5672"
- "15672:15672"
volumes:
- rabbitdata:/var/lib/rabbitmq
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "check_running"]
interval: 10s
timeout: 5s
retries: 5
volumes:
pgdata:
redisdata:
rabbitdata:
Каждый сервис использует официальный образ с фиксированной мажорной версией. Это защищает от неожиданных изменений при обновлениях.
Как настроить Docker Compose с базой данных PostgreSQL
PostgreSQL в контейнере настраивается через переменные окружения. Обратите внимание на синтаксис ${DB_USER:-devuser} — это значение по умолчанию, которое используется, если переменная не задана в файле .env.
Создайте файл .env в корне проекта:
# .env
DB_USER=myapp
DB_PASSWORD=secret123
DB_NAME=myapp_dev
RABBIT_USER=admin
RABBIT_PASSWORD=rabbit_secret
Директива volumes с именованным томом pgdata обеспечивает сохранность данных между перезапусками контейнеров. Без неё каждый docker compose down уничтожал бы все данные в базе.
Для инициализации схемы базы при первом запуске добавьте маунт SQL-скриптов:
postgres:
# ... остальные настройки
volumes:
- pgdata:/var/lib/postgresql/data
- ./init-scripts:/docker-entrypoint-initdb.d
Все .sql файлы из папки init-scripts выполнятся автоматически при первом создании базы.
Docker Compose Redis: настройка кеширования
Redis в нашей конфигурации используется как кеш. Образ redis:7-alpine весит всего около 30 МБ, что ускоряет первый запуск. Health check через redis-cli ping гарантирует, что зависимые сервисы запустятся только после готовности Redis.
Если вам нужна кастомная конфигурация Redis, подключите файл настроек:
redis:
image: redis:7-alpine
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- redisdata:/data
- ./redis.conf:/usr/local/etc/redis/redis.conf
Пример redis.conf для разработки:
maxmemory 256mb
maxmemory-policy allkeys-lru
save 60 1000
Docker Compose RabbitMQ: очередь сообщений для микросервисов
RabbitMQ с тегом 4-management включает веб-интерфейс управления, доступный на порту 15672. Это удобно для отладки: вы видите все очереди, обменники и сообщения в реальном времени.
Порт 5672 — это AMQP-протокол, через который ваше приложение подключается к очереди. Подключение из кода (пример на Node.js):
import { connect } from 'amqplib';
// Docker Compose создаёт сеть автоматически,
// поэтому имя сервиса работает как хостнейм
const connection = await connect('amqp://admin:rabbit_secret@rabbitmq:5672');
const channel = await connection.createChannel();
await channel.assertQueue('tasks', { durable: true });
channel.sendToQueue('tasks', Buffer.from(JSON.stringify({ type: 'email', to: 'user@example.com' })));
Добавление приложения в окружение с depends_on
Теперь подключим ваш сервис, который зависит от всех трёх инфраструктурных компонентов:
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://${DB_USER:-devuser}:${DB_PASSWORD:-devpass}@postgres:5432/${DB_NAME:-devdb}
REDIS_URL: redis://redis:6379
AMQP_URL: amqp://${RABBIT_USER:-guest}:${RABBIT_PASSWORD:-guest}@rabbitmq:5672
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
develop:
watch:
- action: sync
path: ./src
target: /app/src
Ключ depends_on с condition: service_healthy гарантирует, что приложение запустится только после полной готовности всех зависимостей. Без health checks Docker проверяет лишь факт запуска контейнера, а не готовность сервиса внутри.
Секция develop.watch включает автоматическую синхронизацию файлов при изменениях, заменяя ручной маунт директорий.
Частые ошибки при настройке Docker Compose
Порты уже заняты. Если на хосте уже запущен PostgreSQL, порт 5432 будет занят. Измените маппинг на 5433:5432 и обновите строку подключения.
Данные пропадают после docker compose down. Команда docker compose down -v удаляет именованные тома. Используйте просто docker compose down, чтобы сохранить данные.
Контейнер не видит другой контейнер. Убедитесь, что используете имя сервиса (не container_name) в строках подключения. Docker Compose создаёт DNS-записи именно по именам сервисов.
RabbitMQ долго запускается. Это нормально — первый старт занимает 15-30 секунд. Health check с interval: 10s и retries: 5 учитывает это.
Запуск и управление окружением
Основные команды для работы с окружением:
# Запустить все сервисы в фоне
docker compose up -d
# Посмотреть логи конкретного сервиса
docker compose logs -f postgres
# Проверить статус всех контейнеров
docker compose ps
# Остановить без удаления данных
docker compose down
# Полная очистка (включая данные)
docker compose down -v
# Запустить с пересборкой приложения
docker compose up -d --build app
Заключение
Docker Compose для разработки решает проблему "у меня на машине работает". Один файл compose.yaml описывает PostgreSQL, Redis и RabbitMQ с health checks, переменными окружения и персистентными данными. Новый разработчик в команде запускает docker compose up -d и получает готовое окружение за минуту. Храните compose.yaml в репозитории, а секреты — в .env, добавленном в .gitignore.





Комментарии
0