Docker Compose 如何使用 secrets 管理敏感密码信息

文章导读
Docker Compose 从 version 3.1 开始支持 secrets 机制,可将敏感密码以加密形式存储并在运行时挂载到容器的/run/secrets/目录,避免明文泄露风险。
📋 目录
  1. 原因分析
  2. 解决方案
  3. 注意事项
  4. 参考来源
A A

Docker Compose 如何使用 secrets 管理敏感密码信息

Docker Compose 从 version 3.1 开始支持 secrets 机制,可将敏感密码以加密形式存储并在运行时挂载到容器的/run/secrets/目录,避免明文泄露风险。

原因分析

传统使用环境变量存储敏感信息存在三大安全隐患:环境变量对所有进程可见、调试时可能无意打印到日志、缺乏细粒度访问控制。Docker Secret 通过加密存储于 Raft 日志、运行时以只读文件挂载至/run/secrets/、不落盘不入镜像的方式解决这些问题。Secret 内容大小限制为 500KB,超限需拆分或改用外部密钥管理服务如 HashiCorp Vault。

解决方案

步骤一:定义 Secrets

在 Docker Compose 文件顶级 secrets 部分声明,支持从本地文件创建:

version: "3.1"
services:
  mysql:
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
    secrets:
      - db_root_password
secrets:
  db_root_password:
    file: ./db_root_password.txt

本地文件 db_root_password.txt 内容仅为密码明文,如 mydbpass123,无需换行符。

Docker Compose 如何使用 secrets 管理敏感密码信息

步骤二:在 Service 中引用 Secret

服务配置中通过 secrets 列表指定需要访问的 Secret,容器内默认以只读文件形式出现在/run/secrets/<name>:

wordpress:
  image: wordpress:latest
  environment:
    WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_password
  secrets:
    - db_password

自定义目标路径与权限可使用高级语法:source=db_password,target=passwd,uid=101,gid=101,mode=0400。

步骤三:容器内读取 Secret

应用应直接读取/run/secrets/<name>文件内容,而非通过环境变量传递。Shell 脚本示例:DB_PASS=$(cat /run/secrets/db_password)。Python 示例:with open('/run/secrets/db_password', 'r') as f: password = f.read().strip()。务必检查文件权限默认 0444,避免写入或误删。

Docker Compose 如何使用 secrets 管理敏感密码信息

注意事项

Secret 是 Swarm 特性,非 Swarm 环境如单机 docker-compose up 无法使用,需确保 Docker Compose 版本支持 3.1 及以上。Secret 名称不能含下划线 (_),建议用短横线 (-) 分隔,否则可能创建失败。Secret 不支持动态重载,应用需自行监听文件变更或重启任务,更新需先 docker secret rm 再重建并滚动更新服务。Swarm 节点必须启用 TLS 加密通信,否则 Raft 日志中的 Secret 加密可能被绕过。删除需谨慎:docker secret rm 后所有使用它的服务将无法启动新任务。

参考来源

来源:Docker 官方文档 - Docker Compose version 3.1 secrets 配置规范

Docker Compose 如何使用 secrets 管理敏感密码信息

来源:阿里云开发者社区 - 每天 5 分钟玩转 Docker 容器技术 (108)(109)

来源:技术博客 - 优雅地实现安全的容器编排 - Docker Secrets(2017 年 5 月 29 日)

来源:Docker 知识库 - 如何使用 Docker Secret 管理容器敏感配置信息实战 (2026 年 4 月 9 日)