Гид по технологиям

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

8 min read DevOps Обновлено 03 Dec 2025
Секреты в Docker Compose — безопасное управление
Секреты в Docker Compose — безопасное управление

Снимок контейнера Docker с секретными файлами, смонтированными в /run/secrets

Быстрые ссылки

  • 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: true

Compose попробует найти секрет в пространстве имен 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 для внедрения секретов

  1. Проведите инвентаризацию секретов: пароли БД, API-ключи, сертификаты.
  2. Решите модель хранения: Compose files + CI, или централизованный секретный менеджер.
  3. Перенесите секреты из переменных окружения в файлы, записываемые CI в безопасной среде.
  4. Обновите docker-compose.yml: объявите secrets и подключите их к сервисам.
  5. Протестируйте локально, затем на staging: запустите docker-compose up, убедитесь, что файлы доступны только внутри контейнера.
  6. Настройте процессы ротации и реагирования: как менять секрет, как откатываться.

Критерии приёмки:

  • Все чувствительные значения больше не в исходниках и не в переменных окружения в кодовой базе.
  • Секреты доступны только сервисам, которым они нужны.
  • 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. Для крупных систем рассмотрите интеграцию с централизованными секретными сервисами.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Action Button на iPhone: что это и как настроить
Гаджеты

Action Button на iPhone: что это и как настроить

Pokémon Go на Apple Watch — настройка и советы
Гайды

Pokémon Go на Apple Watch — настройка и советы

Опасные субтитры: как защититься
Кибербезопасность

Опасные субтитры: как защититься

Исправление ошибки Steam: Content file locked
Игры

Исправление ошибки Steam: Content file locked

Добавление друзей в Pokémon Sword и Shield
Игры

Добавление друзей в Pokémon Sword и Shield

Как удалить аккаунт Reddit и убрать посты
Социальные сети

Как удалить аккаунт Reddit и убрать посты