Изменили .env API-шлюза в Docker, но настройки прежние: подстановки, окружение и пересоздание
Разделите подстановки Compose, окружение контейнера и настройки приложения. Проверьте переопределения Shell и файлов, пустые значения и разницу между перезапуском и пересозданием, затем подтвердите изменение на трёх уровнях.
Вы изменили .env в каталоге API-шлюза, перезапустили контейнер, но адрес, тайм-аут или уровень журналирования остался прежним. Это не обязательно означает, что файл не сохранился. Настройка проходит три этапа: разбор Compose, создание контейнера и чтение приложением. Исправленный файл — лишь входные данные первого этапа.
Статья посвящена самостоятельно развёрнутым шлюзам под управлением Docker Compose и вопросу «почему настройка не применяется». Универсальных имён переменных для всех шлюзов здесь нет. Документация проверена 22 октября 2026 года. Ниже описаны официальные механизмы и порядок диагностики; пересоздание рабочего шлюза и платные API-вызовы не выполнялись.
1. Определите, какой уровень вы изменили
Два файла с именем .env могут иметь разные назначения. Сначала найдите реальную точку запуска: запишите версию Compose, рабочий каталог, имя проекта, файлы Compose и их порядок, параметры файлов окружения, имя сервиса и целевую среду Docker. Задание по расписанию, кнопка в панели и ручной запуск могут использовать разные настройки.
| Источник | Основная роль | Чего он не доказывает |
|---|---|---|
Окружение Shell, .env Compose или --env-file | Значения для подстановок в файле Compose | Что все ключи из файла попадут в контейнер |
environment или env_file сервиса | Объявление переменных окружения контейнера | Что приложение распознаёт эти имена |
| Файл конфигурации, смонтированный в контейнер | Файл, который может прочитать приложение | Что приложение перечитает его автоматически или предпочитает его окружению |
| Панель шлюза, настройки в базе, аргументы запуска | Источники и приоритеты определяет приложение | Что .env на хосте переопределит сохранённую настройку панели |
Документация Docker разделяет источники подстановки и окружение контейнера: переменная хоста или .env сама по себе не становится переменной контейнера, для передачи требуется соответствующая конфигурация.[1][2] Если приложение самостоятельно читает .env, это другой механизм. Его нужно проверять по версии приложения, не смешивая с загрузкой файла Compose.
Для проверки выберите документированную, несекретную и наблюдаемую настройку, например подтверждённый уровень журналирования. Не экспериментируйте произвольно с адресом базы или настоящим upstream-ключом. Не прикладывайте полный список переменных окружения к обращению в поддержку.
2. Проверьте переопределения при подстановке и передаче в контейнер
Сначала выясните, какую конфигурацию Compose собирается применить, затем — с какой конфигурацией работает контейнер сейчас. Подкоманда config разбирает и объединяет файлы Compose, разрешает переменные и показывает подготовленную модель. Она не читает фактическое текущее окружение работающего контейнера.[3]
Используйте те же файлы, каталог и параметры, что и при настоящем развёртывании. Проверка настроек по умолчанию из другого каталога может относиться к другому проекту. Полный вывод config и вывод с --environment способны содержать секреты. Просматривайте их в контролируемой среде, а для передачи оставляйте только необходимые несекретные поля. Режим проверки --quiet не подтверждает, что значение соответствует задаче приложения.
Особенно внимательно проверьте следующие отношения:
- Shell может переопределить файл подстановок. Одноимённая переменная в окружении процесса, запускающего Compose, может заменить значение из
.envили явно указанного файла.[1] У CI, панели и ручного терминала окружение может различаться. environmentимеет приоритет надenv_fileсервиса. Явное объявление одноимённой переменной в сервисе важнее файла. Даже пустое значение или форма без определённого значения не дают оснований ожидать автоматического возврата к значению из файла.[4]- Порядок файлов имеет значение. Более поздний
--env-fileможет переопределить предыдущий; то же относится к порядку спискаenv_fileу сервиса.[1][4] Это два разных этапа, поэтому записывайте оба списка отдельно. - Одноразовый контейнер не доказывает состояние постоянного сервиса. Временное переопределение окружения через
runизменяет значение для соответствующего запуска, но не подтверждает обновление существующего контейнера.[2]
Предположим, тестовое приложение действительно распознаёт APP_MODE. Файл окружения сервиса задаёт test, а секция environment явно задаёт production: контейнер должен получить последнее значение. Это условный пример приоритета, а не имя настройки конкретного шлюза и не выполненный тест.
Пустая строка и отсутствие переменной — разные состояния. Выражение ${VAR:-default} использует значение по умолчанию при отсутствии переменной или пустой строке; ${VAR-default} — только при отсутствии.[1] Для обязательного непустого ввода используйте документированную проверку обязательности, чтобы ошибка не превращалась незаметно в пустое значение. Успешная проверка выражения ещё не подтверждает правильность адреса, учётных данных или смысла настройки.
Если значение содержит $, кавычки или переносы строк, изучите правила разбора именно этого формата файла. Не «исправляйте» настоящий ключ массовым удалением кавычек или заменой символов. Сначала воспроизведите ситуацию на несекретном значении, затем внесите исправление согласно формату.
3. Отличайте перезапуск от пересоздания
Официальное описание restart однозначно: перезапуск не применяет изменения файла Compose, в том числе изменения переменных окружения.[5] Он запускает заново существующий контейнер, а не создаёт его с новой конфигурацией.
При изменении конфигурации сервиса или образа up останавливает и пересоздаёт соответствующие контейнеры, сохраняя подключённые тома. --no-recreate запрещает пересоздание, а --force-recreate принудительно его выполняет.[6] Это описание поведения, а не указание немедленно принудительно обновить рабочую систему.
Подготовьтесь в следующем порядке:
- Убедитесь, что результат разбора конфигурации уже правильный. Если он неверен, повторное пересоздание не поможет.
- Сохраните предыдущую конфигурацию, найдите постоянные данные и проверенную резервную копию. Назначьте допустимое окно недоступности и дождитесь завершения текущих запросов.
- Зафиксируйте используемый образ, чтобы изменение окружения случайно не стало обновлением программы. Проверьте монтирования, сеть, зависимости и точное имя сервиса.
- Обновите затронутый сервис по процедуре вашей версии Compose. Подтвердите, что пересоздан нужный контейнер, а не только перезапущен процесс или создана копия другого проекта.
- Проверьте состояние запуска и затем поведение приложения. При нескольких репликах проверьте каждую, иначе запросы могут попеременно попадать в старые и новые экземпляры.
Сохранение подключённых томов при пересоздании не означает сохранения временных данных в записываемом слое контейнера. Не удаляйте тома ради применения переменных. Изменения базы или обновление программы требуют отдельного плана по резервному копированию и восстановлению шлюза; диагностика окружения его не заменяет.
4. Почему новое окружение контейнера не меняет поведение приложения
Уполномоченный администратор должен сравнить необходимые несекретные поля в метаданных конфигурации целевого контейнера и проверить его идентичность и время создания. Не экспортируйте окружение целиком: там могут находиться ключи API, секреты сессий и пароли базы.
Правильное окружение при создании подтверждает лишь передачу значения контейнеру. Скрипт входа может преобразовать переменную, приложение — прочитать её только при первой инициализации, а база панели — хранить другое значение. Приоритеты нужно уточнить в документации конкретного приложения и версии. Окружение нового интерактивного Shell также не равно полному набору настроек, фактически используемых главным процессом.
| Наблюдение | Где искать прежде всего |
|---|---|
| Итоговая конфигурация Compose уже содержит старое или пустое значение | Shell, пути, правила подстановки, файлы переопределения, объявления сервиса |
| Итоговая конфигурация новая, окружение целевого контейнера старое | Было ли пересоздание, не перепутаны ли проект и сервис, все ли реплики обновлены |
| Окружение правильное, поведение прежнее | Имя переменной и версия, скрипт входа, аргументы запуска, панель или база, момент чтения |
| Часть запросов ведёт себя по-новому, часть по-старому | Реплики, цели балансировщика, прежнее развёртывание, всё ещё принимающее трафик |
| В журнале новый адрес, но вызов не работает | Сам адрес, протокол, сеть или авторизация; не продолжайте объяснять всё загрузкой переменных |
Новое значение на странице панели и новое значение в реальном запросе тоже следует различать. Используйте обезличенные записи о цели маршрута, отметку версии конфигурации или безопасный статус приложения, не записывая полные учётные данные. Нужна ли перезагрузка конфигурации, перезапуск или изменение настройки через панель, определяет документация продукта.
Если применение подтверждено, но контейнер не соединяется с локальным сервисом, переходите к диагностике адресов Docker и локальных моделей. Если теряются параметры при пересылке запроса, используйте разбор неработающих параметров. Это другие классы ошибок.
5. Завершите приёмку и подготовьте откат одной записью
Для изменения сохраните запись: время по Пекину, проект и сервис, фиксированная версия образа, источник настройки, ожидаемое несекретное значение, результат разбора, целевой контейнер, фактическое поведение приложения и непроверенные области. Для ключей используйте имя или идентификатор версии из системы управления, а не секретное значение.
Приёмка состоит из трёх шагов: подтвердить результат разбора, обновление нужного контейнера и поведение приложения на локальном имитируемом маршруте без чувствительных данных. Заранее убедитесь, что этот маршрут не переключится на платный upstream. Он не подтверждает права на настоящую модель или доступность поставщика. Если необходим реальный вызов, администратор проверяет его отдельно в своём разрешённом бюджете.
При изменении обычной настройки откат обычно означает восстановление проверенной старой конфигурации и повторное создание нужных контейнеров тем же процессом, после чего нужна повторная приёмка. Если изменение переключило базу или вызвало запись данных, простого возврата файла недостаточно: сначала разберите новые записи и различия состояния. Не включайте снова скомпрометированные учётные данные ради восстановления работы.
Условие завершения — не «контейнер перезапущен», а совпадение трёх вещей: значения, подготовленного развёртыванием, значения, полученного целевым экземпляром, и значения, реально используемого приложением. Сохраните проверку для следующих обновлений из панели или автоматизации, чтобы временная настройка ручного терминала не скрывала проблему.
6. Официальные источники и границы применения
- Docker Compose: подстановки и файлы окружения. Источники, приоритет Shell, несколько файлов и пустые значения; при подготовке прочитан соответствующий Markdown официального репозитория документации.
- Docker Compose: приоритет переменных окружения. Различие источников подстановки и окружения контейнера, временные переопределения.
- Docker Compose: config. Разбор и объединение, окружение для подстановок, режим проверки без вывода.
- Compose Services: env_file и environment. Переопределения, порядок файлов и пустые значения.
- Docker Compose: restart. Перезапуск не применяет изменения конфигурации.
- Docker Compose: up. Пересоздание, подключённые тома и соответствующие параметры.
Материал относится к цепочке настройки Docker Compose. Эти правила нельзя автоматически переносить на Swarm, Kubernetes или любую управляемую платформу. Готового исполняемого сценария производственных изменений здесь нет, реальное пересоздание Docker не тестировалось. Поддержку переменной приложением и момент её чтения проверяйте по нужной версии.