Управление секретами в Docker Compose: безопасный подход

Быстрые ссылки
How Do Secrets Work?
Defining Secrets in Compose Files
Using Existing Docker Secrets
Extended Secret Syntax
Secrets and Image Authorship
Conclusion
Как работают секреты?
Docker CLI содержит команды для управления секретами, но эти команды работают только в контексте Docker Swarm. В среде без Swarm вы не сможете добавить секреты через стандартный docker CLI для одиночных контейнеров.
Docker Compose реализует «поддельные» секреты (fake secrets), которые дают возможность применять модель секретов в окружениях без кластера. Compose создает секрет как обычный текстовый файл и затем монтирует этот файл внутрь контейнера (обычно в /run/secrets/
Важно: файл секрета не эквивалентен защищенному секретному хранилищу (Vault, AWS Secrets Manager и т.д.). Compose даёт удобство и изоляцию на уровне файловой системы контейнера, но не заменяет централизованное хранилище и ротацию секретов.
Определение секретов в файлах Compose
Процесс состоит из двух шагов: объявить секрет в верхнем уровне поля secrets, затем подключить его к сервису, которому он нужен.
Простой пример безопасной передачи пароля в сервис:
version: "3"
services:
app:
image: example-app:latest
secrets:
- db_password
secrets:
db_password:
file: ./db_password.txtПояснения:
- Compose прочитает значение из файла
./db_password.txtв рабочей директории при запускеdocker-compose up. - Внутри контейнера файл будет смонтирован по пути
/run/secrets/db_password. - Приложение получает пароль, прочитав содержимое этого файла.
Важно: не коммитьте файлы с секретами (db_password.txt) в систему контроля версий. Храните такие значения в безопасном месте и используйте CI/секретные менеджеры для записи на этапе сборки или деплоя.
Использование существующих Docker Secrets
Если вы уже используете Docker Swarm и создали секреты через docker secret, Compose может ссылаться на них вместо файлов. В этом случае секреты нужно создать заранее — команда docker secret работает только на менеджерах Swarm.
Примеры создания секрета через CLI:
# взять значение из стандартного ввода
echo P@55w0rd | docker secret create db_password -ИЛИ
# взять значение из файла
docker secret create db_password ./db_password.txtИ затем в docker-compose.yml вы указываете, что секрет внешний:
version: "3"
services:
app:
image: example-app:latest
secrets:
- db_password
secrets:
db_password:
external: trueCompose попробует найти секрет в пространстве имен Docker. Если секрет не существует, стек не запустится и вы получите ошибку. Это полезно для гарантии, что перед запуском инфраструктуры все секреты создаются централизованно.
Расширённый синтаксис секретов
Если нужно гибко управлять тем, как и куда монтируется секрет, Compose поддерживает расширённую форму записи. Доступны пять опциональных полей:
source— имя источника секрета (должно присутствовать в секцииsecrets).target— имя файла внутри контейнера, в который будет смонтирован секрет.uid— UID владельца для смонтированного файла (по умолчанию 0).gid— GID владельца (по умолчанию 0).mode— права доступа в восьмеричном формате (по умолчанию 0444). Файлы секретов всегда монтируются как доступные только для чтения.
Пример, который меняет имя и права:
version: "3"
services:
app:
image: example-app:latest
secrets:
- source: db_password
target: database_password_secret
mode: 0440
secrets:
db_password:
external: trueПримечания:
- Простая форма (
- db_password) достаточна в большинстве случаев. Комбинировать простую и расширенную формы в одномdocker-compose.ymlможно. modeзаписывается в виде восьмеричного литерала (например, 0440). Убедитесь, что YAML не трактует ведущий ноль как восьмеричное число в нестандартных конвертациях — обычно в строковом виде проблем нет.
Секреты и авторство образов
Многие официальные и общедоступные образы поддерживают использование секретов. При написании образа рекомендуется:
- Поддерживать оба варианта: переменную окружения или путь к файлу. Например,
DB_PASSWORDможет содержать либо сам пароль, либо путь/run/secrets/db_password. - При старте контейнера проверять: если значение переменной указывает на существующий файл — читать файл и использовать его содержимое как секрет. Если файла нет — считать, что переменная содержит фактическое значение.
Пример алгоритма внутри entrypoint (псевдокод):
- Если ENV(DB_PASSWORD) существует и это путь к файлу — прочитать и заменить переменную на содержимое файла.
- Иначе использовать значение переменной как есть.
Это даёт гибкость пользователю и позволяет постепенно внедрять секреты без ломки обратной совместимости.
Когда модель секретов в Compose не подходит (примеры отказа)
- У вас распределённая инфраструктура с централизованной ротацией и аудитом — лучше использовать специализированный менеджер секретов (HashiCorp Vault, AWS Secrets Manager).
- Нужна динамическая ротация секретов с нотификацией потребителей в реальном времени — файловая модель Compose не предоставляет механизма push-уведомлений.
- Вы запускаете контейнеры на платформе, где смонтированные файлы работают некорректно (редкие кастомные рантаймы) — проверяйте совместимость.
Альтернативные подходы
- Переменные окружения: просты, но постоянно доступны и часто попадают в логи и дампы процессов.
- Файловая модель Compose: удобна для простых случаев и локальных деплоев, лучше, чем переменные окружения.
- Централизованные сервисы (Vault, AWS Secrets Manager): сильнее в безопасности, аудитах и ротации, но сложнее в настройке.
- KMS + зашифрованные файлы в репозитории: компромисс, пригоден для защищённого CI/CD.
Выбор зависит от требований к аудиту, частоте ротации и уровню угроз.
Практическое руководство — мини-SOP для внедрения секретов
- Проведите инвентаризацию секретов: пароли БД, API-ключи, сертификаты.
- Решите модель хранения: Compose files + CI, или централизованный секретный менеджер.
- Перенесите секреты из переменных окружения в файлы, записываемые CI в безопасной среде.
- Обновите docker-compose.yml: объявите
secretsи подключите их к сервисам. - Протестируйте локально, затем на staging: запустите
docker-compose up, убедитесь, что файлы доступны только внутри контейнера. - Настройте процессы ротации и реагирования: как менять секрет, как откатываться.
Критерии приёмки:
- Все чувствительные значения больше не в исходниках и не в переменных окружения в кодовой базе.
- Секреты доступны только сервисам, которым они нужны.
- CI-пайплайн пишет секреты во фалы, доступные Compose, и эти файлы не коммитятся.
Роли и чек-листы
Администратор/DevOps:
- Инвентаризация всех секретов.
- Выбор хранилища и политики ротации.
- Настройка CI для записи секретов в файлы.
- Обновление docker-compose.yml и тестирование.
Разработчик образа:
- [ ] Поддержка сценария чтения секрета из
/run/secrets. - Поддержка fallback — переменная окружения.
- Документация для пользователей образа.
Безопасность/комплаенс:
- Проверка, что секретные файлы не попадают в логи.
- Аудит доступа к репозиторию и CI.
Тестовые случаи и приёмочные критерии
- Запуск сервиса с секретом: приложение успешно читает секрет из /run/secrets.
- Попытка доступа из другого сервиса: файл недоступен (проверяется на уровне Compose/изоляции).
- Отсутствие секрета: стек не стартует и выводит понятную ошибку.
- Ротация секрета в Swarm: новый секрет применяется и сервис обновлён согласно процедуре.
Безопасность: рекомендации по ужесточению
- Не храните файлы секретов в репозитории.
- Ограничьте доступ к CI-переменным, где хранятся значения.
- Используйте минимальные права (
mode: 0440или 0400) и назначайте владельца (uid/gid) там, где это необходимо. - Убедитесь, что логирование приложений не выводит содержимое файлов секретов.
- Планируйте ротацию секретов и метод отката на случай компрометации.
Конфиденциальность и соответствие (GDPR)
Секреты — персональные данные только опосредованно (например, ключи, дающие доступ к персональным данным). Тем не менее:
- Храните доступы и секреты по принципу минимального доступа.
- Логи, содержащие секреты или ключи, должны быть удалены/зашифрованы.
- Документируйте, кто и когда имеет доступ к секретам для целей аудита.
Совместимость и переход с переменных окружения
- Пошаговый переход: сначала поддерживайте оба способа в образе, позже переключайтесь на файловую модель в продакшене.
- Если используете Swarm, рассмотрите централизованный
docker secretи пометьте их как external: true в Compose. - Для платформ, где Compose не поддерживает секреты нативно, используйте CI для записи файлов в директорию и убедитесь, что runtime защищает эти файлы.
Примеры отказов и способы их обхода
Сценарий: У вас хостовая система случайно сохраняет снимок контейнера или временные файлы. Риск: секреты могут попасть в бэкап. Митигирование:
- Настройте исключения для директорий с секретами в системных бэкапах.
- Используйте шифрование томов/файловой системы там, где это возможно.
Сценарий: Пользователь по привычке указывает секрет в переменной окружения при деплое. Митигирование:
- Добавьте pre-deploy проверки в CI, которые валидируют отсутствие секретов в кодовой базе и предупреждают при использовании plain-text переменных.
Заключение
Передача секретов через Docker Compose как файловая модель — простой и безопасный шаг по сравнению с хранением секретов в переменных окружения. Это не универсальное решение: для сложных распределённых систем и требований к аудиту стоит рассмотреть специализированные менеджеры секретов. Однако для большинства приложений Compose-стек с правильно настроенным CI и политиками доступа снижает риск утечек и упрощает управление.
Важно: секреты должны оставаться секретными на всех этапах жизненного цикла — от хранения в CI до монтирования в контейнере. Автоматизируйте процесс, документируйте и тестируйте ротацию и сценарии восстановления.
Краткая сводка
- Секреты в Compose монтируются как файлы (обычно в /run/secrets).
- Объявляйте секреты в секции
secrets, подключайте их к нужным сервисам. - Для Swarm можно ссылаться на внешние секреты (
external: true). - Используйте расширённый синтаксис для контроля прав и имени файла.
- Не храните реальные файлы секретов в системе контроля версий; размещайте их через CI или секретный менеджер.
Notes: Этот материал даёт практический набор приемов и чек-листов для безопасной работы с секретами в Docker Compose. Для крупных систем рассмотрите интеграцию с централизованными секретными сервисами.
Похожие материалы
Action Button на iPhone: что это и как настроить
Pokémon Go на Apple Watch — настройка и советы
Опасные субтитры: как защититься
Исправление ошибки Steam: Content file locked
Добавление друзей в Pokémon Sword и Shield