Fig: один файл вместо трёх команд запуска dev-окружения
Попробовали Fig для описания многоконтейнерного dev-окружения: web + postgres + redis в одном fig.yml. Разработчики сказали «наконец-то» и больше не спрашивают, как всё это поднять.
Fig позволяет описать многоконтейнерное приложение в одном YAML-файле и запустить всё одной командой; Docker официально включил его в свою экосистему как стандартный инструмент для описания многоконтейнерных приложений
Обычная история с Docker-окружением для разработчика выглядела примерно так: три открытых вкладки терминала, три docker run с разными флагами, которые надо помнить или держать в wiki, и периодическое «а у тебя порты правильно пробиты?». Документировать это честно - значит писать длинный README с командами, которые всё равно устаревают.
Fig решает это прямолинейно: один YAML-файл с описанием всех сервисов, fig up в корне проекта - и всё запустилось. Звучит банально, но на практике разница заметная.
Что такое Fig
Fig - это утилита от orchardup, которую Docker в октябре объявил официальным проектом экосистемы. По сути это обёртка над Docker API, которая читает fig.yml и управляет несколькими контейнерами как единым приложением: запускает в нужном порядке, пробрасывает переменные окружения, создаёт линки между контейнерами.
Нас заинтересовало применение именно в dev-окружении - не в продакшене, где оркестрация сложнее, а именно как инструмент «поднять локально то, что похоже на прод».
Пример: web + postgres + redis
Взяли типичный стек одного из проектов. До Fig разворачивание занимало три отдельные команды с нетривиальными флагами. После - вот такой fig.yml в корне репозитория:
web:
build: .
ports:
- "8000:8000"
links:
- db
- cache
volumes:
- .:/app
db:
image: postgres:9.3
environment:
POSTGRES_DB: myapp
POSTGRES_USER: myapp
POSTGRES_PASSWORD: dev_password
cache:
image: redis:2.8
fig up - и через несколько секунд всё работает. fig up -d - если не нужен поток логов в терминале. fig logs - посмотреть, что происходит. fig stop - остановить. fig rm - убрать контейнеры.
Что важно: links не просто говорит «эти контейнеры связаны», он ещё прописывает в /etc/hosts контейнера web записи для db и cache. Приложение обращается к базе по имени db, к Redis по имени cache - никакого захардкоженного localhost с конкретным портом, который надо помнить.
Как восприняли разработчики
Честно говоря, лучше, чем мы ожидали. Обычно новый инструмент - это «окей, потом разберусь». Здесь после первого fig up реакция была примерно «и всё? вот так просто?».
Несколько наблюдений из практики первых недель:
fig psстал первым рефлексом вместоdocker ps- потому что показывает только то, что относится к текущему проекту, без шума от остальных контейнеров на машине.fig run web bashудобен для разовых задач: миграции базы, запуск тестов, отладка внутри контейнера - без отдельногоdocker execс поиском ID контейнера.- Volumes для кода (
- .:/app) означают, что изменения в файлах видны в контейнере мгновенно. На macOS с boot2docker это работает медленнее из-за VirtualBox shared folders, но терпимо.
Одна вещь, которую пришлось объяснять: fig up --build - если изменился Dockerfile или зависимости, контейнер надо пересобрать явно. Без флага Fig использует кешированный образ, и это иногда вводило в заблуждение.
Что решили стандартизировать
После первого опыта договорились: все новые проекты получают fig.yml в корне по умолчанию. Правило простое - если приложение требует больше одного процесса для запуска, в репозитории есть fig.yml.
Для проектов, которые мы сопровождаем в рамках managed-инфраструктуры, это ещё и удобный способ синхронизировать dev-окружение с тем, как сервисы разложены в продакшене: те же образы, те же переменные окружения (кроме паролей), тот же порядок зависимостей.
Отдельный вопрос - prod-деплой через Fig. Пробовали, работает, но там своя специфика: перезапуск контейнеров при fig up с остановкой сервиса не всегда приемлем, нет нормального rolling update, мониторинг не знает про fig-абстракцию. Для разработки - отлично, для продакшена у нас пока Ansible и руками написанные скрипты.
Fig продолжают активно развивать, и то, что Docker взял его под крыло, обнадёживает: теперь он не сторонний эксперимент, а часть официальной экосистемы. Посмотрим, куда это придёт.