На локальной машине .env файл с паролем от базы данных — это нормально, удобно и никто не пострадает. В продакшене это же самое иногда превращается в проблему, о которой узнают только после утечки, потому что docker inspect любому, у кого есть доступ к хосту, покажет все переменные окружения контейнера открытым текстом.
Что видно через docker inspect
docker inspect my-container | grep -A 20 '"Env"'
Любая переменная окружения, переданная через environment в docker-compose.yml, полностью читаема этой командой. Это не баг Docker, а ожидаемое поведение — переменные окружения по дизайну не считаются защищенным местом хранения секретов.
Как выглядит Docker Secret вместо этого
services:
api:
image: myapp:latest
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txt
Секрет монтируется не как переменная окружения, а как файл внутри контейнера, обычно по пути /run/secrets/db_password. Приложение читает значение из файла при старте, а не получает его через process.env.
| Критерий | .env / environment | Docker Secrets |
|---|---|---|
| Видно через docker inspect | Да, полностью | Нет |
| Требует Swarm-режим для полной функциональности | Нет | Частично, для docker secret create |
| Подходит для локальной разработки | Да, привычно и просто | Избыточно для локали |
| Подходит для продакшна с чувствительными данными | Спорно | Да |
| Ротация значения без пересоздания контейнера | Неудобно | Проще через обновление файла |
Практичный средний путь для тех, кто не готов к Swarm
Далеко не каждая команда готова разворачивать Docker Swarm ради секретов. Промежуточный вариант — file-based secrets в обычном Docker Compose, как в примере выше: это работает без Swarm, секрет так же монтируется файлом, просто без команды docker secret create и центрального хранилища секретов демона.
Если проект уже держит .env и настало время мигрировать на секреты, .env to Docker Secrets Converter сгенерирует готовые команды docker secret create по каждой переменной, чтобы не переписывать их вручную одну за другой.
Когда .env всё еще нормальный выбор
Для локальной разработки, для CI с изолированными временными базами данных, для staging окружений с не самыми критичными данными .env остается разумным и куда более простым выбором. Проблема начинается там, где к хосту или к логам системы мониторинга имеет доступ кто-то, кто не должен видеть реальный пароль от продакшн базы.
Итоговый чеклист
.env и environment в docker-compose полностью читаемы через docker inspect любым, у кого есть доступ к Docker демону на этом хосте.
Docker Secrets монтируются файлом, а не переменной окружения, что решает проблему видимости, но требует небольшой правки кода приложения для чтения значения из файла.
Для локальной разработки .env остается нормальным выбором, переход на секреты имеет смысл именно на этапе, когда к продакшн хосту получает доступ больше одного человека.