📦 Что это
Набор проверенных шаблонов и практик для работы с Docker и Docker Compose, ориентированный на локальную разработку, безопасность контейнеров, управление сетями и томами, а также оркестрацию нескольких сервисов. Помогает инженерам быстро настраивать рабочие окружения, избегать типовых ошибок и внедрять best practices с первых строк docker-compose.yml.
🛠️ Как работает
⚙️ Docker Compose для локальной разработки
Главный сценарий — описание полноценного стека сервисов в одном файле. На примере типового веб-приложения:
- Сервис приложения (
app): собирается из Dockerfile с multi-stage, использует target: dev для этапа разработки. Пробрасывает порт 3000, монтирует исходный код через bind mount (.:/app) для hot reload, а node_modules сохраняется анонимным томом (/app/node_modules) — чтобы не затирать зависимости хоста.
- Зависимости:
depends_on с condition: service_healthy для PostgreSQL и service_started для Redis — гарантирует, что приложение стартует только после готовности базы.
- Вспомогательные сервисы: PostgreSQL 16 Alpine, Redis 7 Alpine, Mailpit для тестирования отправки писем (SMTP + веб-интерфейс на порту 8025).
- Тома: именованные
pgdata и redisdata для персистентности данных.
🧩 Production-сборка через Override-файлы
Используются два подхода:
docker-compose.override.yml — автоматически подгружается при простом docker compose up, содержит отладочные настройки (порт 9229 для Node.js debugger, переменные DEBUG, LOG_LEVEL).
docker-compose.prod.yml — включается явно (-f), переопределяет target: production, добавляет restart: always и ограничения ресурсов (cpus, memory).
Пример запуска:
# разработка
docker compose up
# production (явно два файла)
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
🌐 Сеть и Service Discovery
- Автоматический DNS: в рамках одной сети Compose сервисы доступны по имени:
db:5432, redis:6379. Никаких жестко заданных IP.
- Изоляция через несколько сетей:
frontend-net и backend-net — frontend видит только API, API видит и frontend, и БД. База изолирована от фронтенда.
- Безопасное пробрасывание портов: для dev-доступа с хоста используйте
127.0.0.1:5432:5432 — порт открыт только для localhost. В production порты из сервисов лучше убрать совсем, оставив доступ только через внутреннюю сеть.
💾 Volume-стратегии
| Тип тома |
Назначение |
Именованный (pgdata) |
Персистентность данных БД, управляется Docker |
Bind mount (./src:/app/src) |
Живая синхронизация кода для разработки |
Анонимный (/app/node_modules) |
Предотвращает перезапись содержимого контейнера хостом (например, node_modules, .next cache) |
Популярный паттерн для приложения:
volumes:
- .:/app # код
- /app/node_modules # защита node_modules в контейнере
- /app/.next # сохранение билд-кэша
🔒 Контейнерная безопасность
В Dockerfile:
- Фиксированные версии базовых образов (
node:22.12-alpine3.20 вместо :latest).
- Создание непривилегированного пользователя (
adduser -S app -u 1001) и переключение на него (USER app).
- Минимизация слоёв и никаких секретов в образе.
В docker-compose.yml:
security_opt: [no-new-privileges:true] — запрет повышения привилегий.
read_only: true + tmpfs для /tmp и /app/.cache — файловая система контейнера только для чтения, запись только во временные каталоги.
cap_drop: ALL + cap_add: NET_BIND_SERVICE — удалить все capability, оставить только привязку к привилегированным портам (<1024).
Секреты:
- Никаких хардкодных
ENV API_KEY=... в образе.
- Использование внешних
.env-файлов (не коммитятся в git) или Docker Secrets для Swarm-режима.
🧹 Anti-паттерны (чего делать нельзя)
- ❌ Использовать
docker compose как продакшн-оркестратор — для этого есть Kubernetes, ECS, Swarm.
- ❌ Хранить данные без томов — контейнер эфемерен, после перезапуска всё пропадёт.
- ❌ Работать от root — всегда создавайте отдельного пользователя.
- ❌ Использовать тег
:latest — нарушает воспроизводимость сборок.
- ❌ Мешать всё в один контейнер — один контейнер = один процесс.
- ❌ Зашивать секреты в
docker-compose.yml — используйте .env или secrets.
🔍 Диагностика и отладка
Набор команд для частых сценариев:
# логи конкретного сервиса
docker compose logs -f app
# выполнить команду внутри контейнера
docker compose exec app sh
docker compose exec db psql -U postgres
# проверка сетевой связности
docker compose exec app nslookup db
docker compose exec app wget -qO- http://api:3000/health
# сброс состояния
docker compose down -v # удалить всё, включая тома
docker system prune # очистить неиспользуемые образы/контейнеры
📌 Когда использовать
- На старте нового микросервиса — скопировать шаблон
docker-compose.yml с нужными сервисами, подогнать порты и переменные.
- Перевод проекта с локального запуска в контейнеры — взять готовый паттерн multi-stage Dockerfile и структуру volume.
- Диагностика сетевых проблем — изоляция сетей, проверка DNS, проброс только необходимых портов.
- Аудит безопасности — сверка с чеклистом:
no-new-privileges, read_only, cap_drop, пользователь не root, отсутствие секретов в образе.
- Оптимизация размера образа — внедрение multi-stage сборки,
dockerignore, фиксация версий базовых образов.
⚠️ Важно знать
- Примеры в этом патерне преимущественно для Node.js, но концепции универсальны: достаточно заменить базовый образ и команды.
docker-compose.override.yml подходит только для разработки — в CI/CD или production используйте явный -f с двумя файлами.
- Перед запуском production-сборки убедитесь, что secrets и
.env-файлы не попали в репозиторий (добавьте .env* в .gitignore).
- Паттерн не заменяет полноценный оркестратор — для нескольких нод, автоскейлинга и rolling updates смотрите в сторону Kubernetes.
Комментарии
Комментариев пока нет. Будьте первым.