Один контейнер с приложением – это удобно, но реальные системы так не живут. Веб-приложение тянет за собой базу, кэш, очередь, обратный прокси. Запускать их руками через 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 и тестовый контур. Дальше масштабируйте подход до проектирования и внедрения инфраструктуры под ваши требования.