DockerMiddleExperience
Когда контейнеризация решает реальную инженерную проблему, а когда Docker только добавляет лишний слой сложности?
Docker решает проблему расхождения окружений, воспроизводимости артефактов и изоляции зависимостей. Лишний слой сложности появляется при простых сценариях, неготовой команде или managed PaaS, где buildpack справляется без Dockerfile.
Когда контейнеризация решает реальную проблему
Docker устраняет конкретный класс проблем — расхождение окружений между разработкой, CI и production («works on my machine»). Это особенно заметно в нескольких сценариях:
- Зависимости системного уровня: если сервис требует конкретной версии libssl, ffmpeg, glibc или Python — контейнер упаковывает всё это вместе с кодом. Альтернатива — скрипты установки, которые расходятся между людьми и серверами.
- Множество сервисов с разными стеками: Node.js API, Python ML-сервис, Go worker, PostgreSQL 17, Redis 8 — запустить это локально без Docker означает поддерживать сложные инструкции по настройке.
docker compose upстандартизирует onboarding до нескольких минут. - Воспроизводимые CI-сборки: образ собирается из зафиксированных слоёв, тег с digest гарантирует, что в staging и production деплоится тот же артефакт, что прошёл тесты.
- Изоляция процессов и ресурсов: cgroups ограничивают CPU/memory, namespaces изолируют сеть и файловую систему. Это полезно на shared серверах и при запуске ненадёжного кода (парсеры, обработка файлов).
Когда Docker добавляет лишний слой сложности
- Простой скрипт или CLI-инструмент: если это один Python-скрипт с двумя зависимостями —
uvилиvenvпроще и быстрее. Docker здесь создаёт overhead без выгоды. - Команда не умеет поддерживать образы: кто обновляет base image при CVE? Кто следит за размером образов? Без процесса контейнеризация даёт false sense of security.
- Production на managed PaaS: Heroku, Railway, Fly.io, Render — платформы с buildpacks могут деплоить без Dockerfile. Добавление Docker только ради Docker увеличивает maintenance.
- High-performance networking или bare-metal требования: если нужен прямой доступ к GPU, RDMA-сети или специфичным kernel модулям — Docker NAT и overlay добавляют latency. Podman с
--network=hostили нативная инсталляция могут быть лучше. - Маленькая команда с одним сервером:
systemdunit +venvчасто проще в эксплуатации, чем Docker daemon + compose file + volume management для одного монолита.
Что реально сравнивать при выборе
- Стоимость onboarding: сколько времени нужно новому разработчику, чтобы запустить проект локально?
- Воспроизводимость: гарантируете ли вы, что в prod идёт тот же артефакт, что тестировался?
- Operational overhead: кто обновляет образы, следит за размером, проверяет CVE?
- Изоляция: нужна ли вам изоляция ресурсов или процессов, или достаточно user permissions?
- Зрелость команды: есть ли люди, которые понимают Docker networking, volumes и security model?
Подводные камни
- Контейнеры не изолируют от host kernel — критические kernel CVE затрагивают все контейнеры на хосте.
- Volumes и bind mounts добавляют сложность backup и permission management.
- Docker daemon — privileged процесс. Доступ к
/var/run/docker.sockравен root на хосте. - Multi-arch сборки (amd64 vs arm64) требуют QEMU или native builders — не все Dockerfile готовы к этому из коробки.
- Stateful сервисы (PostgreSQL, Kafka) в Docker на production требуют продуманного volume management и backup стратегии.
What hurts your answer
- Выбирать Docker по популярности, а не по требованиям проекта
- Игнорировать опыт команды, эксплуатацию и стоимость поддержки
- Не называть ситуации, где Docker будет плохим выбором
What they're listening for
- Называет критерии выбора Docker
- Учитывает команду, эксплуатацию, стоимость и риски
- Может назвать сценарии, где выбрал бы альтернативу