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)#
- 定义位置:在服务级别通过
environment或env_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。
- 避免泄露:不要将密钥写入
.env或env_file,避免提交到仓库。 - 权限控制:将 secrets 与 configs 文件权限限制在 600/640。
- 多环境策略:结合
override或profiles引入不同的 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。