Переменные окружения в Docker — как передать

Быстрые ссылки
- Для чего нужны переменные окружения?
- Через аргумент командной строки
- Дополнительная безопасность с файлом .env
- Через docker-compose
- Через Kubernetes
- Когда это не работает
- Альтернативные подходы
- Чек-листы и сниппеты
- Риски и меры
- FAQ
Для чего используются переменные окружения?
Переменные окружения позволяют вынести конфигурацию из исполняемого кода. Это простой ключ=значение, доступный приложению в том же сеансе оболочки. Основные преимущества:
- Отделение секретов (пароли, ключи) от репозитория.
- Удобство для разных окружений: dev/staging/production.
- Простота замены значений без пересборки образа.
Определение: переменная окружения — пара ключ/значение, доступная приложению внутри процесса.
Через аргумент командной строки
Команда запуска контейнера docker run принимает переменные окружения через флаг -e (сокращение от –env). Пример:
sudo docker run \
-e POSTGRES_USER='postgres' \
-e POSTGRES_PASSWORD='password' \
... image-nameЕсли переменные уже установлены в окружении оболочки, можно передать их по имени. Это удобно, когда секреты уже экспортированы в текущую сессию:
# задать переменную в текущей сессии
POSTGRES_PASSWORD='password'
# использовать её при запуске
docker run -e POSTGRES_PASSWORD -e POSTGRES_USER ...Важно: значения, переданные в командной строке, видны на хосте (в истории команд и в списке процессов), если не принять меры.
Дополнительная безопасность с файлом .env
Передавать длинные или чувствительные пары через CLI удобно, но рискованно: команды сохраняются в истории и видимы в процессах. Файл .env позволяет хранить пары в файле и управлять доступом через права файловой системы (chmod, chown).
Создайте файл .env с переменными в формате “ключ=значение”, по одной записи на строку:
POSTGRES_PASSWORD='password'
POSTGRES_USER='postgres'
APPLICATION_URL='example.com'Запустите контейнер с флагом –env-file:
docker run --env-file ./envfile ...Советы по безопасности:
- Храните .env вне репозитория или добавьте в .gitignore.
- Ограничьте права доступа к файлу: chmod 600 .env.
- При необходимости используйте менеджеры секретов вместо плоских файлов.
Через docker-compose
docker-compose упрощает запуск нескольких сервисов. В compose‑файле можно пробросить переменные из окружения хоста в контейнер и задать значения по умолчанию:
version: '3.1'
services:
my-service:
build:
context: .
args:
- POSTGRES_USER=${POSTGRES_USER:-default}
environment:
- POSTGRES_USER=${POSTGRES_USER:-default}Замечания:
- docker-compose читает переменные из текущего окружения оболочки при запуске docker-compose up.
- Можно использовать отдельный .env рядом с docker-compose.yml — docker-compose автоматически подхватит его (если имя .env).
- Не храните секреты непосредственно в compose-файле, если файл в репозитории.
Через Kubernetes
Kubernetes управляет конфигурацией на уровне манифестов. В Pod/Deployment вы явно указываете переменные в spec.containers.env:
apiVersion: v1
kind: Pod
metadata:
name: example
spec:
containers:
- name: app
image: example-image
env:
- name: SERVICE_PORT
value: "80"
- name: SERVICE_IP
value: "172.17.0.1"Для секретов используйте Kubernetes Secrets и ссылку на них (envFrom или valueFrom). Это даёт контроль доступа и интеграцию с системой RBAC.
Когда это не работает (примеры, когда способ неприменим)
- Если контейнер создаётся внешним оркестратором (managed service) через интерфейс, прямой доступ к docker run недоступен — используйте интерфейсы этого сервиса.
- Если приложение запускается внутри процесса init или обёртки, которая очищает окружение, переменные могут быть недоступны.
- При неправильной интерполяции переменных в compose или в shell (например, экспорт не выполнен) значения будут пустыми.
- Для долгосрочного хранения и ротации секретов лучше использовать менеджер секретов (HashiCorp Vault, AWS Secrets Manager) — .env и Secrets в Kubernetes не заменяют полноценный хранилище с ротацией.
Альтернативные подходы
- Менеджеры секретов: Vault, AWS Secrets Manager, Azure Key Vault — подходят для ротации, аудита и гранулярного доступа.
- Файлы конфигурации в хранилищах с ограниченным доступом (например, S3 с шифрованием). Приложение загружает конфиг при старте.
- Системы шаблонов и шифрование (SOPS): хранить зашифрованные файлы в репозитории и дешифровать при деплое.
- Kubernetes ConfigMap для не-секретных параметров и Secrets для секретов.
Ментальные модели и правила-эвристики
- Секреты ≠ конфигурация: думайте об этом отдельно. Секреты требуют контроля и ротации.
- Минимум прав: давайте контейнерам и файлам только те права, которые действительно нужны.
- Не доверяйте окружению по умолчанию: проверяйте, откуда пришла переменная (CI, локальная машина, оркестратор).
- Простейшая граница: CLI — удобно для ad-hoc; .env — удобно для локальной разработки; compose — для простых multi-service локальных стэков; Kubernetes — для production/масштабирования.
Мини-методология: безопасная передача переменных (шаги)
- Классифицируйте переменные: секрет/не-секрет.
- Для секретов выберите менеджер секретов или зашифрованный .env; для остального — .env или ConfigMap.
- Обновите CI/CD pipeline: подтяните секреты из хранилища на этапе деплоя, не в репозитории.
- Ограничьте доступ к файлам и логам (chmod, аудит).
- Проводите ротацию и тестируйте восстановление.
Чек-листы по ролям
Разработчик:
- Не коммитить .env с секретами.
- Использовать переменные для конфигурации среды.
- Документировать необходимые ключи и их форматы.
Оператор/DevOps:
- Настроить .env/.env.production, но не хранить в репозитории.
- Внедрить секрет-менеджер для production.
- Обеспечить права доступа и аудит.
Специалист по безопасности:
- Проверить логи на утечки секретов.
- Настроить ротацию ключей и мониторинг доступа.
Шаблоны и сниппеты (cheat sheet)
Docker CLI:
docker run -d \
--name mydb \
--env-file ./prod.env \
postgres:13docker-compose (фрагмент):
services:
web:
build: .
environment:
- DATABASE_URL=${DATABASE_URL}
env_file:
- ./web.envKubernetes Secret (создать из Literal):
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
POSTGRES_PASSWORD: cGFzc3dvcmQ=(замечание: value в data должно быть base64)
Риски и меры (security hardening)
Риски:
- Секреты в истории команд и process list.
- .env в репозитории.
- Плохой контроль доступа к секретам.
Митигаторы:
- chmod 600 и ограничение владельца для .env.
- Добавление .env в .gitignore и проверка pre-commit hooks.
- Использование менеджеров секретов с ротацией и аудитом.
- Шифрование секретов при хранении (SOPS, KMS).
Decision flow (выбор способа) — визуальная подсказка
flowchart TD
A{Где запускается?} -->|Локально/Ad-hoc| B[CLI '-e' или .env]
A -->|Много сервисов локально| C[docker-compose]
A -->|Production/Scale| D[Kubernetes или оркестратор]
D --> E{Нужна ли ротация и аудит?}
E -->|Да| F[Использовать Secret Manager]
E -->|Нет| G[Использовать Kubernetes Secrets]Краткое резюме
- Для быстрого запуска используйте docker run -e, но помните про видимость в истории.
- Для локальной безопасности применяйте –env-file и права на файл.
- Для multi-container use docker-compose и внешние .env файлы.
- В production используйте Kubernetes + Secrets или систему управления секретами.
FAQ
Как избежать попадания .env в git?
Добавьте .env в .gitignore и настройте pre-commit хуки, проверяющие наличие секретов в коммитах.
Можно ли хранить пароли в docker-compose.yml?
Технически можно, но это плохая практика — файл часто хранится в репозитории. Лучше ссылаться на внешние секреты или на .env вне репозитория.
Как безопасно передать секреты в Kubernetes?
Используйте Kubernetes Secrets и, при необходимости, интеграцию с внешним секрет-менеджером (Vault, KMS). Ограничьте доступ через RBAC.
Ключевые действия: классифицируйте переменные, избегайте коммита секретов, используйте .env локально, менеджер секретов в production.
Похожие материалы
Как использовать iCloud на Android
Facebook Messenger Rooms — полное руководство
Ошибка Windows 10 0x80070714 — способы исправления
Вирусные Reels в Instagram: 10 практических советов
Использовать Galaxy Watch без телефона