Конфигурация Compose: .env, environment и файлы секретов
Автор: Казачкин Даниил Михайлович · Обновлено
Один и тот же Compose-файл может запускать локальный стенд и тестовый проект с разными настройками. Но .env, переменные shell, environment, env_file и secrets действуют на разных…
Один и тот же Compose-файл может запускать локальный стенд и тестовый проект с разными настройками. Но .env, переменные shell, environment, env_file и secrets действуют на разных этапах. Разделим подстановку в YAML и окружение процесса, чтобы отсутствие значения обнаруживалось до запуска приложения.
Подстановка не передаёт всё окружение
Файл .env помогает Compose подставлять значения в конфигурацию. Он не отправляет автоматически каждую строку внутрь каждого контейнера. Для передачи нужны environment или env_file; значения, заданные при конкретном docker compose run -e, могут иметь другой приоритет. Полный порядок перечислен в официальной таблице.
Создайте рядом два файла. .env:
GREETING=hello from dotenvcompose.yaml:
name: yk-env-demo
services:
probe:
image: alpine:3.22
environment:
MESSAGE: ${GREETING:?set GREETING in .env or shell}
command: ["sh", "-c", "printf '%s\\n' \"$$MESSAGE\""]docker compose run --rm probe выводит приветствие. Затем в Bash выполните GREETING='hello from shell' docker compose run --rm probe: вы увидите другое значение, хотя файл .env не менялся. Это полезный опыт для случая, когда разработчики получают разные результаты из одинакового репозитория.
Ошибка до создания контейнера
Конструкция ${NAME:?message} требует непустое значение. ${NAME:-fallback} использует запасное, когда переменная отсутствует или пуста. Эти операции выполняет Compose при чтении файла. Для переменной, которую должен раскрыть shell контейнера, используйте $$NAME, как в примере выше. Правила interpolation.
docker compose config -q проверяет структуру без печати полной конфигурации. Обычный config полезен при исследовании путей и подстановок, но способен вывести чувствительные значения в терминал или CI-лог. Не прикладывайте такой вывод к публичной ошибке без просмотра. Для исследования приоритетов пользуйтесь учебными значениями, а не реальными токенами.
Файл секрета вместо строки в YAML
Для приложения, которое умеет читать файл, можно предоставить Compose secret. Подготовьте demo-secret.txt с небоевым значением и отдельный Compose-файл:
name: yk-secret-demo
services:
probe:
image: alpine:3.22
command: ["sh", "-c", "test -s /run/secrets/app_password && echo 'secret file is present'"]
secrets:
- app_password
secrets:
app_password:
file: ./demo-secret.txtСервис сообщает о наличии файла, не печатая содержимое. Наличие файла ещё не заставляет программу использовать его: приложение должно читать этот путь, либо официальный образ должен поддерживать соответствующую переменную _FILE. Это соглашение образа, не универсальный механизм Docker для любого имени переменной.
Локальный Compose монтирует файловый secret; это не автоматическое шифрование файла на диске и не полная система управления секретами Swarm. Ограничьте доступ к файлу хоста, исключите его из Git и подготовьте способ доставки в окружение. Механизм Compose secrets.
Проверка самостоятельности
Удалите GREETING из .env и shell, запустите config -q и объясните, почему контейнер ещё не появился. Верните значение, добавьте новую переменную в .env, но не в environment, и проверьте её отсутствие внутри процесса. Наконец измените probe секрета так, чтобы он проверял только доступность файла. Эти три опыта отделяют ошибку конфигурации, передачу окружения и чтение секретного материала.