Технологии и Инфраструктура → Docker Compose и Dev-окружение
Docker Compose и Dev-окружение
1) Зачем Compose
Docker Compose — быстрый способ поднять реплику прод-стека в локали/CI: приложения, БД, очереди, кэши, обратный прокси, мок-сервисы. Цели:- Паритет с продом (образы, переменные, сети) → меньше «работает у меня».
- Быстрый старт для новичков → `make up` и в бой.
- Изолированные стенды на разработчика/ветку → параллельная работа без конфликтов.
- Интеграционные тесты на реальных зависимостях.
2) Базовая структура репозитория
project/
docker/
app/ # Dockerfile, скрипты web/ # Nginx/Traefik конфиги seed/ # сидеры/фикстуры compose.yaml # общий базовый стек compose.override.yaml # локальные оверрайды (в.gitignore)
compose.ci.yaml # для CI
.env.example # шаблон окружения
Makefile # удобные цели devcontainer.json # VS Code Dev Containers (опционально)
Рекомендации:
- compose.yaml — описывает «скелет» (сервисы, сети, тома) одинаковый для dev/CI.
- override — только локальные правки: маппинги каталогов, порты, debug-флаги.
- .env.example → разработчик копирует в `.env` и подставляет значения.
3) Каркас compose.yaml (пример)
yaml name: project services:
gateway:
image: traefik:v3 command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.dev.acme.tlschallenge=true"
ports: ["80:80", "443:443"]
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro networks: [edge, core]
api:
build:
context:.
dockerfile: docker/app/Dockerfile target: dev env_file: [.env]
command:./scripts/dev-start.sh volumes:
-./:/app:cached depends_on: [db, redis, kafka]
labels:
- "traefik.http.routers.api.rule=Host(`${API_HOST}`)"
- "traefik.http.services.api.loadbalancer.server.port=8080"
networks: [core]
db:
image: postgres:16 environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASS}
POSTGRES_DB: ${DB_NAME}
volumes:
- pgdata:/var/lib/postgresql/data healthcheck: {test: ["CMD-SHELL","pg_isready -U $$POSTGRES_USER"], interval: 5s, timeout: 3s, retries: 20}
networks: [core]
redis:
image: redis:7 command: ["redis-server","--appendonly","yes"]
volumes: [ "redisdata:/data" ]
networks: [core]
kafka:
image: bitnami/kafka:3 environment:
KAFKA_ENABLE_KRAFT: "yes"
KAFKA_CFG_PROCESS_ROLES: "controller,broker"
KAFKA_CFG_NODE_ID: 1
KAFKA_CFG_LISTENERS: PLAINTEXT://:9092
KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092 networks: [core]
mailhog:
image: mailhog/mailhog ports: ["8025:8025"]
networks: [core]
mock-psp:
image: wiremock/wiremock:3 command: ["--verbose","--global-response-templating"]
volumes: ["./docker/mocks/psp:/home/wiremock"]
labels:
- "traefik.http.routers.mockpsp.rule=Host(`${PSP_HOST}`)"
networks: [core]
volumes:
pgdata: {}
redisdata: {}
networks:
edge: {}
core: {}
Ключевые моменты:
- Traefik/NGINX как gateway: приближает схему роутинга к продовой.
- Healthcheck и depends_on с `condition: service_healthy` (в v3 через waiting-скрипты) — упорядоченный старт.
- Volumes для персистентности (БД/кэш) и bind-mount для кода (hot-reload).
4) Профили и несколько файлов
Profiles (`profiles: [dev, ci, extras]`) включают/исключают сервисы (`docker compose --profile extras up -d`).
Несколько файлов:- `docker compose -f compose.yaml -f compose.dev.yaml up` — сливание конфигураций.
- `compose.yaml` — базовый.
- `compose.dev.yaml` — bind-mountы, дебаг, фичефлаги.
- `compose.extras.yaml` — инструментальные (Grafana, pgAdmin, Kafdrop).
- `compose.ci.yaml` — «голова без графики», без bind-mountов.
5) Переменные, секреты и настройки
.env — общий источник переменных: хосты, креды тестовых БД, флаги.
Секреты в dev не держим в явном виде; используем:- локальные dummy-секреты (ключи заглушки),
- интеграцию со skinny-Vault/SOPS для особо чувствительного.
- Принцип: минимально необходимые данные. PAN/PII — токены/фикстуры.
6) Сборки и скорость
6.1 Multi-stage + BuildKit
Dockerfile с целями `base`, `dev`, `prod`; общий cache-layer для зависимостей.
Включить BuildKit: `DOCKER_BUILDKIT=1` (или в конфиге).
Кэширование: `--mount=type=cache,target=/root/.cache/...` для pip/npm/maven.
6.2 Быстрый цикл
Bind-mount кода + hot-reload (nodemon, uvicorn --reload, Spring Devtools).
Отдельный таргет dev со сборкой только нужного.
Makefile цели: `make up`, `make down`, `make logs`, `make rebuild`, `make seed`.
make
ENV?= dev up:
docker compose --profile $(ENV) up -d down:
docker compose down -v logs:
docker compose logs -f --tail=200 rebuild:
DOCKER_BUILDKIT=1 docker compose build --pull --no-cache api seed:
docker compose run --rm api./scripts/seed.sh migrate:
docker compose run --rm api./scripts/migrate.sh test:
docker compose -f compose.yaml -f compose.ci.yaml run --rm api./scripts/test.sh
7) БД, миграции, сидинг
Миграции (Flyway/Liquibase/Alembic/Prisma) запускаются хук-скриптом после старта `db` (ожидание healthcheck).
Сидинг: отдельный контейнер `seed` с фикстурами; повторяемый и идемпотентный.
Снапшоты данных: том `pgdata` можно сбрасывать/восстанавливать скриптом `reset-db.sh`.
8) Брокеры, кэши, CDC
Kafka/Rabbit/Redpanda — как в проде (минимальные конфиги).
Redis с AOF включенным для реалистики.
CDC-коннекторы (опционально): Debezium в отдельном сервисе для интеграционных тестов аналитики.
9) Моки внешних поставщиков
WireMock/Prism для REST, MockServer для сложных сценариев.
Mailhog/SMTP4Dev для писем.
Localstack/MinIO для облачных сторов и S3-совместимости.
Политика: все внешние PSP/KYC/KMS — через мок-хаб по контрактам (OpenAPI), а не «в интернет».
10) Обратный прокси и TLS
Traefik/NGINX раздает сервисы по локальным доменам (`.test`, `.local`):- `api.local.test`, `mockpsp.local.test`.
- TLS: mkcert для выдачи доверенного локального сертификата, чтобы тестировать HSTS/secure-cookies.
- Sticky-сессии включайте только для кейсов, где это правда важно.
11) Профили разработчика: Node/Python/Java
Node: mount `node_modules` как кэш (volume), чтобы ускорить install; `CHOKIDAR_USEPOLLING=1` на Windows/WSL.
Python: `pip cache` как volume, `watchfiles`/`uvicorn --reload`.
Java: JRebel/Devtools, `mvn -T 1C -o` + слой с зависимостями.
12) Тесты и качество
Интеграционные тесты гоняем внутри сети Compose: `docker compose run test`.
Testcontainers (для JVM/Node/Python/.NET) — хороий вариант для unit-интеграции без полного стека.
Контракт-тесты с мок-хабом → gate в CI.
Линтеры/Pre-commit: запускать в контейнере для повторяемости.
13) Devcontainers и «IDE-как-код»
`devcontainer.json` фиксирует образ разраба (CLI, SDK, linters), монтирует проект, прогоняет `postCreateCommand`.
Профит: одинаковые инструменты, не «засоряем» хост, новая машина — готова за минуты.
14) Безопасность в dev
Без root в образах приложений; `readOnlyRootFilesystem` когда возможно.
Никаких боевых ключей/секретов, даже временно.
Логи — без PII/PAN; маскирование на уровне форматтера.
Сегрегация портов и сетей: внешний доступ только через gateway.
15) FinOps/производительность в локали
Ограничьте ресурсы: `deploy.resources.limits` (Compose читает частично, но помогает дисциплине).
Уменьшайте фан-аут (меньше сервисов по умолчанию; extras — профили).
Кэш BuildKit и volume-кэши для менеджеров пакетов.
16) CI с Compose
Используйте те же `compose.yaml` + `compose.ci.yaml` без bind-mountов.
Кэши зависимостей — как attachable volumes между джобами/слоями.
Параллельные джобы: `name:` в Compose различный (или префикс по ветке), чтобы стенды не конфликтовали.
17) Траблшутинг
`docker compose ps` / `logs -f` / `exec` — базовая диагностика.
Проверяйте DNS в сети Compose (сервис по имени).
Если bind-mount «тормозит» на macOS/Windows — `:cached`/`:delegated` или Mutagen/virtiofs.
Healthcheck «зеленый», но сервис «мертв»: проверьте `readiness` вашей аппки и порядок миграций.
18) Чек-лист внедрения
1. Базовый стек (gateway, api, db, cache, queue) в compose.yaml.
2. Локальные правки — в override (в.gitignore).
3..env.example полный и актуальный; `make bootstrap` копирует его в `.env`.
4. Healthchecks и скрипт ожидания БД/миграций.
5. WireMock/Localstack/MinIO для внешних провайдеров.
6. Сидинг и миграции как командлеты `make seed/migrate`.
7. BuildKit + multi-stage, кэши зависимостей.
8. Devcontainers/Makefile для быстрого старта.
9. Профили `extras` для инструментов (Grafana/pgAdmin/Kafdrop).
10. CI использует тот же compose (+ci-оверрайд).
19) Анти-паттерны
«Монстр-compose» на 40 сервисов, всегда запущенный: включайте профили.
Жестко прибитые порты, конфликтующие между разработчиками.
Секреты/ключи в Git или `.env.example`.
Зависимость от «интернета» для тестов (реальные PSP/KYC).
Отсутствие healthcheck/ожидания — гонки миграций и стартов.
Отсутствие сидинга → flaky интеграционные тесты.
20) Итог
Compose — это двигатель разработческой скорости: один файл описывает ваш мир сервисов, а профили/оверрайды дают гибкость. Поддерживайте паритет с продом, автоматизируйте сидинг и миграции, держите моки и TLS «как в бою», ускоряйте сборки BuildKit’ом — и у вас получится локальная среда, в которой удобно работать, легко тестировать и безопасно воспроизводить продовые сценарии iGaming/финтех.