Блог "Дети ОИТа"
/поиск

Автоматизация развёртывания тестовых окружений с помощью Docker Compose и Makefile

Автоматизация развёртывания тестовых окружений с помощью Docker Compose и Makefile

Введение

В современной разработке скорость предоставления тестовых окружений напрямую влияет на time-to-market. Ручная настройка сервисов (база данных, кэш, брокер сообщений) отнимает время и приводит к ошибкам из-за человеческого фактора. Решение — декларативная инфраструктура и автоматизация.

В этой статье мы рассмотрим, как связать docker-compose.yml и Makefile для создания единого интерфейса управления окружением, который будет понятен всей команде.

Часть 1. Структура проекта

Типичный микросервисный проект требует нескольких зависимостей:

  • PostgreSQL — основная база данных.
  • Redis — кэш и брокер сообщений.
  • MinIO — эмулятор S3 для хранения файлов.
  • Application — сам код вашего сервиса.

Создадим директорию infra/ для хранения конфигураций.

Часть 2. docker-compose.yml

Файл infra/docker-compose.yml описывает сервисы:

version: '3.8'

services:
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app_user
      POSTGRES_PASSWORD: secret_password
      POSTGRES_DB: app_db
    ports:
      - "5432:5432"
    volumes:
      - pg_data:/var/lib/postgresql/data

  cache:
    image: redis:7-alpine
    ports:
      - "6379:6379"

  storage:
    image: minio/minio
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin
    ports:
      - "9000:9000"
      - "9001:9001"

volumes:
  pg_data:

Часть 3. Makefile как единый интерфейс

Разработчикам не нужно помнить флаги docker-compose. Makefile скрывает сложность.

Создайте Makefile в корне проекта:

# Переменные
DC := docker-compose -f infra/docker-compose.yml
DC_RUN := $(DC) run --rm

# Цели
.PHONY: up down shell logs clean recreate

# Поднять всё
up:
	@echo "🚀 Запуск тестового окружения..."
	@$(DC) up -d

# Опустить всё
down:
	@echo "🛑 Остановка окружения..."
	@$(DC) down

# Удалить тома (чистая БД)
clean:
	@echo "🧹 Удаление томов (БД будет пустой)..."
	@$(DC) down -v

# Пересоздать с нуля
recreate: clean up

# Открыть консоль в приложении
shell:
	@$(DC_RUN) app /bin/sh

# Логи
logs:
	@$(DC) logs -f

# Выполнить миграции (пример)
migrate:
	@$(DC_RUN) app npm run migrate

Часть 4. Расширение: условные переменные

Часто нужно иметь разные конфиги для разных сред. Используем переменные в Makefile:

# .env.test
POSTGRES_PASSWORD=super_secret_test

# .env.dev
POSTGRES_PASSWORD=dev_password

# Makefile
ifeq ($(ENV), test)
	include .env.test
else
	include .env.dev
endif

export

up:
	@echo "Запуск для среды: $(ENV)"
	@$(DC) --env-file .env.$(ENV) up -d

Теперь запуск выглядит так: make up ENV=test.

Часть 5. Типичные проблемы и решения

  1. Конфликт портов: Если у разработчика уже запущен локальный PostgreSQL, docker-compose упадёт. Решение: использовать переменные для портов в Makefile (например, POSTGRES_PORT?=5432).

  2. Мусорные тома: Данные накапливаются. Решение: регулярный запуск make clean или использование tmpfs для временных данных.

  3. Зависимости запуска: Если приложению нужна БД, оно упадёт при старте. Решение: использовать healthcheck в docker-compose.yml для db и depends_on с условием service_healthy.

Заключение

Связка Docker Compose и Makefile — это мощный, но простой инструмент. Он устраняет проблему «а на моей машине всё работало» и позволяет новому разработчику начать работу над проектом одной командой: make up.

Этот подход является базой для более сложных систем, таких как переход на Testcontainers или полноценную оркестрацию в Kubernetes.

Чек-лист

  • Все сервисы имеют restart: unless-stopped.
  • В .gitignore добавлены локальные .env.* файлы.
  • В README.md есть таблица с командами make.
  • Настроен healthcheck для критичных сервисов.