#Что означает ошибка и при каких условиях возникает
Файл .env рядом с compose.yaml может подставлять значения в конфигурацию Compose, но не добавляет их автоматически в окружение приложения. Проверьте путь и environment. Нужно различать интерполяцию ${NAME} в YAML, передачу значений через services.environment и services.env_file, а также переменные окружения уже созданного контейнера.
#Как различить причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Файл .env используется только для подстановкиCompose прочитал NAME из .env, но services.environment/ services.env_file не содержит передачи NAME приложению. | docker compose config --environment видит значение, а docker compose exec app printenv NAME — нет. | Добавить environment: NAME: ${NAME} либо env_file в нужную службу. |
| Файл читается не из того каталогаCompose запускают из другого проекта/каталога либо с --env-file; источники интерполяции различаются. | В config выводится не то значение или предупреждение о незаданном параметре. | Выяснить каталог проекта и используемые файлы окружения. |
| Переменная переопределяетсяЗначение из среды оболочки либо services.environment перекрывает значение из файла. | После смены .env в контейнере всё равно прежнее или пустое значение. | Сопоставить приоритет источников и убрать случайное переопределение. |
| Контейнер не пересоздали после изменения переменныхОкружение процесса определяется при создании контейнера; простой перезапуск не обязательно применяет новую конфигурацию. | docker compose config содержит новое значение, а старый контейнер — прежнее. | Согласованно пересоздать нужную службу после проверки настроек. |
#Пошаговая диагностика и исправление
- Определите имя переменной без публикации её значенияОткройте проект в VS Code («Файл» → «Открыть папку») и найдите compose.yaml и .env. Для учебного примера используйте только несекретную переменную APP_MODE=development; если речь о пароле или токене, не выводите их в консоль и не присылайте в журналы — для рабочих секретов используйте механизм secrets. Запишите название переменной, а не конфиденциальное значение.
- Проверьте путь запуска ComposeОткройте терминал в каталоге, содержащем compose.yaml (Windows PowerShell, Терминал macOS/Linux или встроенный VS Code). Выполните
docker compose versionиdocker compose config -q. Если команда сообщает, что файл не найден, перейдите в верный каталог через cd или укажите явный -f. Когда используются -f, --project-directory либо --env-file, учитывайте, что правила поиска .env зависят от параметров запуска. - Отличите подстановку значений от окружения контейнераВыполните
docker compose config --environmentтолько в безопасном тестовом проекте, не содержащем секретов: эта команда показывает значения, использованные для подстановки. Отдельно посмотритеdocker compose configи найдите в конкретной службе секцию environment. Наличие APP_MODE в выводе --environment ещё не доказывает, что программа увидит APP_MODE — нужен services.environment либо services.env_file. - Передайте переменную приложению явноДля варианта с подстановкой в compose.yaml добавьте к службе
environment: APP_MODE: ${APP_MODE:?APP_MODE is required}. Конструкция:?останавливает обработку конфигурации, если APP_MODE не задана или пуста; таким образом ошибку видно до запуска. Альтернативно можно использоватьenv_file: ./.env, если у сервиса должны появиться все подходящие значения, но не делайте это без проверки наличия секретов. - Проверьте конкурирующие источники значенийЕсли вместо ожидаемого значения выводится другое, сопоставьте среды: переменная из оболочки, явный
--env-file, файл .env и services.environment. У Compose есть приоритеты и переопределения. Например, environment в YAML перекрывает env_file сервиса. Не удаляйте неизвестные переменные в рабочей системе; сначала узнайте, откуда они приходят — сценарий CI, оболочка либо служба Docker. - Пересоздайте только отдельный тестовый контейнерВ новой папке создайте пару файлов из примера. В терминале выполните
docker compose config -q, затемdocker compose up -d. Если вы исправили APP_MODE в .env, повторитеdocker compose up -d --force-recreateименно в тестовой папке. На рабочем сервисе пересоздание вызывает кратковременный перерыв и может затронуть данные, поэтому требуется отдельное согласование. - Убедитесь, что приложение получает правильное несекретное значениеВ учебном проекте выполните
docker compose exec app printenv APP_MODE; ожидаетсяdevelopment. Еслиexecсообщает, что контейнер не запущен, посмотритеdocker compose ps -aиdocker compose logs app. Если вместо development пусто, проверьте именно services.environment; если значение неожиданное, проверьте источники из предыдущего шага. - При сохранении проблемы сравните окончательную конфигурацию с контейнеромКоманда
docker compose configпоказывает итоговую модель, аdocker compose exec app printenv APP_MODE— окружение действующего процесса в тестовом контейнере. Если модель правильная, но процесс старый, пересоздайте его после сохранения важных данных и согласования перерыва. Если модель уже неверная, проблема раньше — в файлах или приоритете переменных; не переустанавливайте Docker. - Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
#Минимальный пример для отдельного тестового проекта
APP_MODE=developmentservices:
app:
image: alpine:3.20
command: ["sh", "-c", "sleep 3600"]
environment:
APP_MODE: ${APP_MODE:?APP_MODE is required}#Как проверить результат и что делать, если проблема осталась
Успех — учебный docker compose exec app printenv APP_MODE выводит development, а приложение получает требуемый параметр. Если не получается, отдельно проверьте имя ключа, расположение .env, параметры запуска и приоритет services.environment/ env_file; не публикуйте конфиденциальные значения.