Один контейнер с приложением – это удобно, но реальные системы так не живут. Веб-приложение тянет за собой базу, кэш, очередь, обратный прокси. Запускать их руками через docker run с десятком флагов --link и -v – путь к ошибкам и невоспроизводимым стендам. После выхода Docker 1.0 и перехода на контейнеры в продакшене этот вопрос встал у нас на каждом втором проекте. Ответ – описывать всё окружение как код.
Fig: окружение в одном YAML-файле
Инструмент, который сейчас решает эту задачу, называется Fig. Его сделала команда Orchard, а летом 2014 года Docker купил проект и ведёт его как официальный способ оркестрации нескольких контейнеров на одной машине. Именно из Fig вырастает то, что Docker планирует выпустить под именем Compose. Пока работаем с тем, что есть в продакшене сегодня.
Идея простая. Весь стек описывается в файле fig.yml:
web:
build: .
ports:
- "8000:8000"
links:
- db
- redis
db:
image: postgres:9.3
volumes:
- ./pgdata:/var/lib/postgresql/data
redis:
image: redis:2.8
Дальше одна команда fig up поднимает весь стек, прописывает связи между контейнерами и пробрасывает порты. fig down гасит всё разом. Разработчик клонирует репозиторий, выполняет одну команду и получает то же окружение, что у коллеги и на тестовом сервере. Никаких «у меня работает».
Почему это важно для корпоративных и госпроектов
Главная выгода – воспроизводимость. Файл fig.yml лежит рядом с кодом, проходит ревью, версионируется. Состав окружения перестаёт быть устным знанием одного админа и становится частью репозитория. Для приёмки в госсекторе это весомый аргумент: стенд собирается из описания, а не из памяти.
Второй эффект – скорость онбординга и единообразие сред. Dev, тестовый контур и предпрод собираются из одного описания, отличаясь только параметрами. Меньше расхождений между средами – меньше дефектов, которые «всплывают только на проде».
Но сам YAML-файл безопасности не приносит. Контейнеры наследуют все проблемы хоста и базовых образов. Поэтому к описанию окружения мы прикладываем те же требования, что и к любому Linux-серверу: фиксируем версии образов, не тащим latest в продакшен, проверяем базовые образы на известные уязвимости. История с уязвимостью Shellshock в bash показала, как быстро дырявый базовый образ компрометирует весь стек. Хост под Docker готовим по чек-листу харденинга Linux – изоляция, минимум открытых портов, контроль доступа.
Где проходит граница применимости
Fig хорош для одной машины: разработка, CI, небольшие стенды. Кластер из нескольких хостов он не оркеструет – для этого нужны другие инструменты, и они пока сырые. Не стоит ждать от fig.yml распределённого планировщика. Это формат описания, а не система управления кластером.
Мы используем Fig там, где он даёт результат: единые dev-окружения команд, сборка тестовых контуров под приёмку, демонстрационные стенды для заказчика. Под продакшен-нагрузку выносим базы данных за пределы контейнеров и оставляем в Docker только приложение.
Вывод
Описание многоконтейнерного окружения как код убирает ручную сборку стендов и расхождения между средами. Начните с малого: перенесите одно приложение со всеми зависимостями в fig.yml и прогоните на нём dev и тестовый контур. Дальше масштабируйте подход до проектирования и внедрения инфраструктуры под ваши требования.