Настройка Docker Compose для staging/production окружения

Staging и production расходятся в настройках — и правки, проверенные на тестовом контуре, ведут себя иначе на боевом. Мы настраиваем Docker Compose под ключ: раздельные конфигурации окружений, управление секретами и предсказуемый выпуск обновлений. Согласованные настройки сокращают время на подготовку релиза в разы.
Часто задаваемые вопросы

Docker Compose production: где ломается конфигурация

Docker Compose удобно описывает окружение одной машины, пока речь идёт о стенде. В production к тому же файлу добавляются переопределения, копии на разных серверах и правки по ходу инцидентов — так начинается дрейф конфигурации. Проверенная сборка стартует в бою с другим набором томов, лимитов и адресов.

Отдельная беда — переменные окружения. Пароли, адреса баз и внешних сервисов нередко зашиваются в образ на этапе сборки вместо подачи контейнеру при запуске. Тогда один и тот же образ несёт настройки стенда: боевой контейнер стучится в тестовую базу, и это выясняется по логам, а не на проверке конфигурации.

Откат релиза ломается по той же причине. Возврат на предыдущий образ не возвращает настройки — файл остаётся текущим, поэтому старый код поднимается с новыми переменными и томами и тянет за собой чужие значения. Пока конфигурация не версионируется вместе с артефактом, откат нельзя считать безопасной операцией.

Расходятся окружения и по мелочам: имя проекта, сеть, точки монтирования, политика перезапуска, порядок старта зависимых сервисов. Каждое такое отличие — отдельный класс отказов, от переполненного диска до сервиса, поднявшегося раньше базы. Ветвления по имени окружения внутри одного файла проблему не снимают, а прячут.

Лечится это разделением: общий файл с описанием сервисов, отдельные файлы для стенда и боя, все значения — только из переменных окружения, проверка конфигурации перед выкладкой, настройки привязаны к тому же артефакту, что и код. Тогда откат возвращает и образ, и конфигурацию целиком. Разбираем, как выстроить этот контур у вас.

Что даёт раздельная настройка окружений

Конфигурация, зашитая внутрь образа, ломает саму идею продвижения одного артефакта: чтобы поменять адрес базы или лимит соединений, приходится пересобирать образ, а значит — заново проходить весь путь проверок. Различия между тестовым и промышленным контуром накапливаются в слоях, и предсказуемо воспроизвести сборку на другой машине уже не получается.

Раздельная настройка переносит различия в переменные окружения, монтируемые файлы и переопределения в отдельном описании контура. Образ остаётся неизменным и продвигается ровно тот же, что проверяли на тестовом стенде: Docker Compose подставляет параметры на старте, а не на этапе сборки.

Отсюда время выката: обновление сводится к перезапуску сервиса с новым набором параметров, без пересборки и прогона всего контура заново. Откат — возврат к предыдущему набору переменных, десятки секунд вместо повторной сборки и повторных проверок. Простой сервиса ограничен временем остановки одного контейнера, а не всего стека, если перезапускать по одному.

Восстановление ускоряется за счёт того, что состояние вынесено в тома и внешние сервисы, а сам контейнер становится заменяемым. Уходит целый класс отказов, где пересборка образа уносила накопленные данные или оставляла стенд в полусобранном виде: поднять контур с нуля — это поднять те же образы с теми же параметрами.

Доля инцидентов, вызванных расхождением контуров, падает: проверки идут на том же артефакте, что попадёт в промышленный контур, и различие остаётся только в значениях параметров. Воспроизводимость сборки перестаёт зависеть от того, кто и в каком порядке правил конфигурацию на сервере.

Способы организации окружений: сравнение вариантов

Выбор способа описания окружений определяет, сколько ручной работы стоит каждый релиз и как часто правка уезжает не в тот контур. Ниже — четыре схемы, которые реально применяют для staging и production, и границы, за которыми каждая начинает мешать.

Вариант Когда подходит Ограничения
Один общий файл конфигурации один контур, небольшой проект, ранняя стадия правки для разных сред живут рядом, риск задеть боевой контур растёт с каждой новой услугой
Файлы наложений базовый набор сервисов общий, отличия — порты, лимиты, переменные при трёх и более контурах комбинации наложений становится трудно отслеживать вручную
Шаблоны окружений с подстановкой значений значения приходят из переменных окружения и секретов без проверки шаблона опечатка в имени переменной всплывает только при запуске
Отдельный репозиторий конфигураций несколько команд и контуров, нужно ревью и история изменений требует регламента доступа и синхронизации с репозиториями сервисов

На практике схемы почти всегда совмещают: базовый набор сервисов держат в одном файле, различия выносят в наложения, а конкретные значения — в шаблоны. Отдельный репозиторий конфигураций оправдан, когда контуров больше двух и изменение перед раскаткой должно проходить ревью. Мы выбираем вариант по числу окружений и частоте правок, а не по привычке: лишний слой абстракции здесь стоит дороже, чем его отсутствие.

Порядок внедрения: от аудита до передачи

Работу начинаем не с переписывания файлов, а с инвентаризации: compose-файлы, файлы-наложения для стенда, переменные окружения, внешние тома и сети. Часто различие между промышленным и тестовым контуром держится в голове одного инженера, а не в конфигурации.

  1. Аудит конфигурации. Состав сервисов, источники образов, тома, порты, продублированные параметры. Отмечаем места, где окружение подменяется вручную.
  2. Схема окружений. Базовый файл плюс наложения для стенда и промышленного контура; пароли и токены уходят из репозитория в отдельное хранилище.
  3. Настройка сервисов. Теги образов, лимиты ресурсов, политика перезапуска, проверки живости, порядок запуска зависимостей.
  4. Проверка на стенде. Полный цикл: подъём с нуля, обновление, откат на предыдущий тег, падение отдельного сервиса, перезапуск узла.
  5. Регламент выката. Порядок действий, критерии остановки, чтение логов, процедура отката и действия при изменении схемы данных.
  6. Передача документации. Карта сервисов, схема сетей и томов, описание переменных, инструкции для дежурного, чек-лист типовых сбоев.

На выходе — воспроизводимый процесс: одинаковый набор команд поднимает стенд и промышленный контур, обновление и откат занимают минуты, а знание об устройстве не остаётся у одного человека.

Передаваемые артефакты: файлы, схемы, регламенты

На выходе заказчик получает не настроенный сервер, а комплект, по которому окружение поднимается с нуля на другой машине и передаётся новому инженеру без устных пояснений. Ниже — что именно фиксируется в репозитории и документации.

  • Файлы окружений — базовый compose-файл плюс переопределения для staging и production: различаются лимиты, тома и адреса внешних сервисов, а не логика приложения.
  • Список переменных окружения — какие обязательны, какие имеют значения по умолчанию и что подаётся из хранилища секретов, а не лежит в репозитории.
  • Схема сервисов — карта зависимостей: кто с кем общается, какие порты публикуются наружу, какие тома переживают перезапуск контейнера.
  • Политики доступа — роли в репозитории и панели управления, кто вправе выкатывать в production, как выдаются и отзываются доступы.
  • Регламент отката — пошаговый порядок при неудачном релизе: возврат на предыдущий образ, точки проверки состояния, за какое время окружение приходит в рабочее состояние.
  • Проверки и наблюдаемость — условия готовности сервиса, правила перезапуска, куда уходят логи и алерты, по каким признакам видно деградацию.
  • Инструкции для команды — как поднять окружение на своей машине, как добавить новый сервис, как собирается и публикуется образ.

Комплект обновляется вместе с инфраструктурой: расхождение между документацией и фактическим состоянием окружения проверяем на каждом релизе.

Кейс: как два контура перестали расходиться в настройках

На старте staging и production жили в двух независимых наборах файлов: разные имена сервисов, свои переменные окружения и тома, проверки готовности настроены только на проде. Правки в staging не доезжали до production, и перед каждым релизом инженер вручную сверял конфигурации — сверка занимала 40–60 минут, а расхождения всплывали уже на живом трафике.

Мы свели оба контура к одному описанию на Docker Compose: базовый файл с сервисами, сетями и проверками готовности, поверх — два файла переопределения, где отличаются только переменные окружения, лимиты ресурсов и политика перезапуска. Секреты вынесены в отдельные файлы окружения вне репозитория, а порядок старта задан через условия готовности зависимостей.

Время выката сократилось с 45 до 8 минут: сборка и запуск идут одной командой, ручных шагов на сервере не осталось. Число инцидентов, связанных с конфигурацией, упало с 5–6 за квартал до нуля за сопоставимый период, доля ручных правок при выкате — с трети до нуля.

Ключевой эффект не в самой автоматизации, а в том, что staging перестал быть «примерно похож» на production. Откат тоже описан конфигурацией: предыдущий набор запускается той же командой, а состояние данных сохраняется в томах.

Что делать, если staging и production уже разошлись?

Расхождение почти никогда не начинается с файла конфигурации. Оно появляется из ручных правок на боевом сервере: поправили переменную, добавили том, поменяли политику перезапуска — и в репозиторий это не вернули. Поэтому сначала снимаем фактическое состояние работающих контейнеров и сравниваем с описанным в файлах: расхождение настроек на этом уровне обычно шире, чем ожидают.

Дальше фиксируем источник истины. Общий базовый файл описывает то, что одинаково: образы, зависимости, внутренние сети, проверки работоспособности, порядок запуска. Различия — адреса, параметры подключения, лимиты, публикация портов, монтирование данных — уходят в файлы-переопределения по окружению. Тогда staging и production отличаются коротким и предсказуемым списком, а не двумя независимыми описаниями.

План выравнивания строится по приоритетам, а не по удобству правок. Сначала то, что создаёт необратимые различия: схема данных, миграции, форматы файлов, содержимое томов — ошибка здесь дороже всего. Затем конфигурация приложений и переменные окружения. Последними — настройки исполнения: лимиты, политики перезапуска, размещение сервисов; их правки обратимы и применяются поочерёдным перезапуском.

Простой не обязателен: сервисы переводим по одному, проверяя результат после каждого шага. Миграции делаем расширяющими — новый формат сначала поддерживают оба окружения, и только потом старое убирается. Завершаем правилом: любая ручная правка на сервере либо переносится в файл, либо откатывается, а сравнение окружений становится регулярной проверкой при поставке. Иначе они разойдутся снова.

Секреты, тома и миграции: частые технические вопросы

Секреты в Compose не попадают в файл описания сервисов: там остаются только имена переменных, а значения подставляет среда исполнения из внешнего хранилища. Для стенда и боевого контура наборы разные — адреса, уровни логирования, доступы к внешним сервисам, — а логика запуска одна, поэтому поведение совпадает.

Данные живут в именованных томах, отдельно от жизненного цикла контейнера: пересборка образа или перезапуск сервиса их не затрагивают, а удаление тома остаётся осознанной операцией с копией. Миграции схемы идут отдельным шагом до старта приложения — новая версия кода не должна встречать старое состояние базы.

Что произойдёт с данными при обновлении релиза?

Ничего: тома не пересоздаются вместе с контейнером. Обновление подменяет образ, содержимое тома остаётся на месте. Перед рискованными миграциями делаем копию и проверяем восстановление на стенде.

Можно ли откатить релиз?

Код — возвратом предыдущего тега образа, это минуты. Схема базы откатывается только заранее подготовленным обратным шагом миграции; если он небезопасен, восстановлением из копии.

Как разделяются окружения?

Общий шаблон описания сервисов плюс отдельные наборы значений для стенда и боевого контура. Отличия — параметры подключений и профили внешних сервисов, а не разошедшиеся инструкции запуска.

Кто получает доступ к секретам?

Только сервисы, которым они нужны, и дежурный инженер — через журнал доступов. Ротация значений плановая: она не требует пересборки образов и не останавливает работу окружения.

Обсудим задачу и вернёмся с оценкой и планом

Оценку по такой задаче нельзя дать «на глаз» — она зависит от того, сколько сервисов, как они связаны и что уже автоматизировано. Поэтому просим прислать то, что есть: текущие compose-файлы, образы сборочных инструкций, переменные окружения без секретов. По ним сразу видно, где зависимости зашиты жёстко, а где уже вынесены в конфигурацию.

  • Схему сервисов и связей: кто с кем общается, какие тома и сети общие, что должно быть доступно снаружи.
  • Различия контуров: чем staging отличается от production по ресурсам, репликам, переменным и внешним интеграциям.
  • Как деплой и откат устроены сейчас: скрипты, конфигурация непрерывной интеграции, ручные шаги, простой при выкатке.
  • Целевую инфраструктуру: число хостов, где хранятся образы, как выдаются секреты, ограничения по сети.
  • Работу с данными: миграции схемы, резервные копии, что нельзя терять при перезапуске контейнеров.
  • Ограничения: окна обслуживания, регламенты безопасности, ожидаемые сроки запуска.

Из этого набора собираем оценку работ, план внедрения по этапам, состав команды и сроки — без допущений, которые потом превращаются в переделки. Если части данных нет, это тоже рабочий случай: скажем, что нужно собрать перед стартом. Опишите задачу — вернёмся с оценкой и планом.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    815
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139