15.8.6 环境变量与配置管理(env_file、configs、secrets)

在 Compose 中,环境变量用于参数化镜像与运行时行为,配置与密钥用于分离配置数据与敏感信息,避免将凭证写入镜像或代码仓库。本节重点掌握 env_file 的加载机制、configs 与 secrets 的作用范围、挂载方式与安全边界。

原理草图:

文章图片

前置安装与验证:

# 安装 Docker Compose v2(示例以 Ubuntu 为例)
sudo apt-get update
sudo apt-get install -y docker-compose-plugin

# 验证
docker compose version
# 预期输出:Docker Compose version v2.x

1. 环境变量管理(env_file)#

  • 定义位置:在服务级别通过 environmentenv_file 引入。
  • 优先级environment > env_file > 宿主机环境变量 > .env 文件(用于变量替换)。
  • 使用场景:统一管理数据库连接、端口、运行模式等非敏感参数。

示例项目结构:

compose-env/
├── docker-compose.yml
├── .env
└── env/
    └── app.env

示例文件:

# .env (用于变量替换)
APP_IMAGE=myapp:1.0
APP_PORT=8080
# env/app.env (用于容器环境变量)
APP_ENV=prod
LOG_LEVEL=info
DB_HOST=db
DB_PORT=3306
# docker-compose.yml
services:
  app:
    image: ${APP_IMAGE}
    ports:
      - "${APP_PORT}:8080"
    env_file:
      - ./env/app.env
    environment:
      - LOG_LEVEL=debug   # 覆盖 env_file 中的 LOG_LEVEL

启动与验证:

cd compose-env
docker compose up -d

# 验证容器环境变量(明确命令解释:exec 进入容器,env 打印)
docker compose exec app env | grep -E 'APP_ENV|LOG_LEVEL|DB_HOST'
# 预期:APP_ENV=prod, LOG_LEVEL=debug, DB_HOST=db

常见排错:

# 1) 路径错误:查看解析后的配置
docker compose config

# 2) 变量未替换:确认 .env 文件位置在 compose 文件同级目录
ls -la .env

# 3) env_file 编码/换行问题
file env/app.env
# 预期:ASCII/UTF-8,换行 LF

2. 配置管理(configs)#

  • 用途:注入非敏感配置文件,如 Nginx 配置、应用配置模板。
  • 特点:以只读文件挂载到容器中,便于统一管理与版本控制。
  • 适用:Docker Swarm 原生支持;普通 Compose 中可用 bind/volume 替代,但 configs 语义更清晰。

示例(Swarm 语义写法,Compose 也可用于开发验证):

# docker-compose.yml
configs:
  nginx_conf:
    file: ./conf/nginx.conf

services:
  web:
    image: nginx:alpine
    configs:
      - source: nginx_conf
        target: /etc/nginx/nginx.conf

示例配置文件:

# conf/nginx.conf
events {}
http {
  server {
    listen 80;
    location / {
      return 200 "nginx config ok\n";
    }
  }
}

启动与验证:

docker compose up -d

# 验证配置是否挂载为只读(ls -l 查看权限)
docker compose exec web ls -l /etc/nginx/nginx.conf
# 预期权限:-r--r--r-- 或类似只读权限

# 验证配置生效
curl -s http://localhost:80/
# 预期输出:nginx config ok

排错要点:

# 1) 配置未生效:检查容器内实际文件内容
docker compose exec web cat /etc/nginx/nginx.conf

# 2) 修改配置后未生效:需要重建或重启
docker compose up -d --force-recreate

3. 密钥管理(secrets)#

  • 用途:注入敏感信息,如数据库密码、证书、API Key。
  • 特点:以只读文件方式挂载,避免进入环境变量或镜像层。
  • 适用:Swarm 中更完整;普通 Compose 可结合外部密钥服务或挂载文件。

示例文件结构:

compose-secret/
├── docker-compose.yml
└── secrets/
    └── db_pass.txt

示例配置:

# docker-compose.yml
secrets:
  db_pass:
    file: ./secrets/db_pass.txt

services:
  app:
    image: alpine:3.19
    secrets:
      - db_pass
    command: ["/bin/sh", "-c", "cat /run/secrets/db_pass && sleep 3600"]

启动与验证:

docker compose up -d

# 读取密钥文件
docker compose exec app cat /run/secrets/db_pass
# 预期输出:db_pass.txt 中的内容

排错要点:

# 1) 密钥未挂载:查看 compose 渲染
docker compose config | sed -n '/secrets:/,/services:/p'

# 2) 文件权限导致读取失败:确保 secrets 文件权限
chmod 600 secrets/db_pass.txt

4. 最佳实践与常见问题#

  • 分层管理:参数使用 env_file,配置使用 configs,敏感信息使用 secrets。
  • 避免泄露:不要将密钥写入 .envenv_file,避免提交到仓库。
  • 权限控制:将 secrets 与 configs 文件权限限制在 600/640。
  • 多环境策略:结合 overrideprofiles 引入不同的 env/configs/secrets 文件。
  • 排查加载问题:检查 env 文件路径、文件编码、换行格式(LF)及变量名大小写。

综合示例(多环境与覆盖):

# docker-compose.yml
services:
  app:
    image: myapp:latest
    env_file:
      - ./env/app.env
    environment:
      - APP_ENV=prod

# docker-compose.override.yml (开发环境)
services:
  app:
    env_file:
      - ./env/app.dev.env
    environment:
      - APP_ENV=dev

常用命令解释与排错:

# 查看最终合并后的配置(排错首选)
docker compose config

# 强制重建并替换容器(配置变更后)
docker compose up -d --force-recreate

# 查看容器运行环境变量(确认加载)
docker compose exec app env | sort

练习:
1. 在 env/app.env 中添加 FEATURE_X=true,并通过 docker compose exec app env 验证加载。
2. 将 configs 挂载到 /etc/app/app.conf,修改配置后使用 --force-recreate 使其生效。
3. 将数据库密码移出 env 文件,改用 secrets 注入,并在容器内读取 /run/secrets/db_pass