ADG Оставить заявку
Блог DevOps 4 мин чтения

Docker Compose для локального стенда: web + db + cache в одном файле

Тестируем Docker Compose - бывший Fig - для локального dev-окружения. Один docker-compose.yml вместо трёх страниц инструкций. Что работает, где пока трёт.

Контекст момента

Docker Compose (бывший Fig) выходит как официальный инструмент оркестрации multi-container приложений

Несколько недель назад Docker Inc. официально объявила, что Fig становится Docker Compose - инструментом в составе официальной экосистемы. Мы с Fig поигрались ещё в конце 2014-го, поэтому когда вышел Compose, решили прогнать его на реальном проекте и посмотреть, стоит ли рекомендовать клиентам.

Контекст: есть небольшой веб-проект - Python/Django-приложение, PostgreSQL, Redis. Стандартный стек. Задача - чтобы разработчик поднял локальное окружение без пятиминутного созвона с DevOps и трёх страниц инструкций в вики.

Что было до

До этого жили примерно так. Вики-страница «Как поднять проект локально» содержала: установи PostgreSQL нужной версии, создай базу, прогони миграции, установи Redis, пропиши переменные окружения в .env, не забудь про virtualenv, проверь что порты не заняты. Семь пунктов, каждый с подпунктами.

Работало примерно так: старожилы проекта делали это на автопилоте, новые люди тратили час, иногда два, причём половина времени уходила на «у меня не та версия PostgreSQL» или «порт 5432 занят другим проектом».

docker-compose.yml

Файл получился такой:

web:
  build: .
  command: python manage.py runserver 0.0.0.0:8000
  volumes:
    - .:/code
  ports:
    - "8000:8000"
  links:
    - db
    - cache
  env_file:
    - .env

db:
  image: postgres:9.3
  environment:
    POSTGRES_DB: myapp
    POSTGRES_USER: myapp
    POSTGRES_PASSWORD: localpass

cache:
  image: redis:2.8

Сорок строк. Запускается через docker-compose up. Всё.

Через минуту-полторы (если образы уже скачаны) три контейнера поднимаются в правильном порядке: сначала db и cache, потом web. Django видит базу по имени хоста db, Redis - по cache. Переменные окружения берутся из .env, который не коммитится, а .env.example лежит в репозитории.

Что реально удобно

docker-compose up и docker-compose down. Это главное. Поднять всё окружение и убрать его без следов - одна команда. Никакого «убей процесс PostgreSQL, удали сокет, очисти tmp». docker-compose down останавливает контейнеры и убирает сеть.

Изоляция по проектам. Два проекта с разными версиями PostgreSQL живут на одной машине без конфликтов. Это решает ровно ту проблему, о которой написано выше.

volumes для кода. Директория проекта монтируется внутрь контейнера, Django видит изменения файлов напрямую - стандартный runserver с автоперезагрузкой работает как обычно. Не нужно пересобирать образ при каждом изменении кода.

Логи из одного места. docker-compose logs -f показывает потоки от всех трёх контейнеров вперемешку, с префиксом сервиса. Удобно отлаживать: видно что web-запрос пришёл, db выполнила запрос, redis ответил.

Где пока трёт

Не всё радужно. Несколько мест, где мы споткнулись.

Первый запуск медленный. Образы postgres:9.3 и redis:2.8 весят вместе около 300 МБ. На офисном интернете - минут пять. Для CI это приемлемо, для нового разработчика в первый рабочий день - немного обескураживает. Локальный registry решает проблему, но это уже отдельная инфраструктура.

Пересборка образа при изменении Dockerfile. docker-compose up не пересобирает образ автоматически если Dockerfile поменялся. Нужно явно docker-compose build. Люди забывают, получают старое окружение, тратят время на диагностику. Добавили в вики одно предупреждение, но лучше бы это поведение было очевиднее.

links как механизм сети. В текущей версии Compose сервисы видят друг друга через links. Это работает, но выглядит как временное решение: нужно явно прописывать зависимости, а не просто называть сервисы по имени. Docker сейчас активно меняет сетевую модель, и здесь явно будут изменения - приходится держать это в голове.

Данные не персистентны между down и up. docker-compose down убивает контейнеры вместе с данными базы. Для чистого локального стенда - это хорошо, для разработки где хочется сохранить тестовые данные - нужно монтировать volume явно. Мы добавили закомментированный блок в пример-конфиг с пояснением.

Итог для клиентов

Мы протестировали на одном проекте, добавили в общую инфраструктуру. В рамках интеграционных работ начинаем рекомендовать Docker Compose как стандартный способ описать локальное dev-окружение для новых проектов. Не для продакшна - там пока своя история. Именно для локальной разработки.

Три страницы вики свернулись в сорок строк YAML и один README с тремя командами. Новый разработчик поднял окружение за семь минут. Для нас это достаточный аргумент чтобы двигаться в этом направлении.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.