Короткий ответ
Переменные окружения контейнера видны через docker inspect, попадают в логи ошибок и иногда в системы мониторинга процессов, а Docker secrets монтируются как файлы в tmpfs только тем сервисам, которым явно разрешён доступ, не отображаясь в обычном docker inspect сервиса.
Как это работает подробнее
любая переменная, заданная через -e/environment, хранится в метаданных контейнера в открытом виде и доступна любому, кто может выполнить docker inspect по этому контейнеру, а также наследуется всеми дочерними процессами внутри контейнера. Docker secrets (в режиме Swarm) передаются зашифрованными через Raft log менеджерам кластера и монтируются только в tmpfs конкретных сервисов, которым явно назначен секрет — после остановки сервиса файл секрета исчезает вместе с tmpfs.
Пример кода
Пример конфигурации
$ docker inspect app --format '{{.Config.Env}}'
[PATH=/usr/bin DB_PASSWORD=SuperSecret123]Что использовать на практике
- Практика. для production-данных (пароли БД, API-ключи) предпочтительнее механизмы, монтирующие секрет как файл, доступный только внутри контейнера и не отображаемый в общих метаданных — это могут быть Docker secrets, внешние secret-менеджеры (Vault, облачные Secrets Manager) с монтированием через volume/init-контейнер, но не обычные переменные окружения.
Подводные камни
- Риск. передают пароли БД через
-e DB_PASSWORD=...и считают это достаточно безопасным, не учитывая, что значение будет видно черезdocker inspectлюбому, у кого есть доступ к Docker API на хосте; логируют весь набор переменных окружения при старте приложения в целях диагностики, случайно публикуя секреты в логи.