Docker compose环境变量管理
在 Docker Compose 中,如果直接把数据库密码、API 密钥等敏感信息写进 docker-compose.yml,一旦文件被提交到代码仓库或分享给他人,凭据就会直接泄露。
更稳妥的做法是利用 Docker Compose 的原生环境变量机制,把配置与代码分离,让密码和密钥只在部署时注入。
本文会从零开始演示如何管理环境变量,避免硬编码密码与密钥。
为什么要用环境变量替代硬编码
硬编码密码的危害不只是泄露风险。
当你的应用需要部署到开发、测试、生产等多套环境时,每次修改密码都要去改动 compose 文件,容易改错或漏改。
使用环境变量后,同一份 docker-compose.yml 可以原样用于不同环境,只需在每台服务器上放置不同的 .env 文件即可。
对于零基础用户来说,理解环境变量可以这样想:docker-compose.yml 是“菜谱”,而 .env 是“食材清单”。
菜谱本身不写具体用哪种酱油,而是写“生抽适量”,实际放多少由清单决定。
这样同一份菜谱,在不同地方可以做出不同口味,而且不会把祖传秘方泄露出去。
准备:创建测试项目结构
先创建一个演示目录,例如 env-demo,并在其中新建 docker-compose.yml 和 .env 两个文件。
这是最基础的准备工作。
mkdir env-demo && cd env-demo
touch docker-compose.yml .env
核心操作:定义 .env 并在 compose 文件中引用
第一步:在 .env 中写入变量
编辑 .env 文件,这里存放所有需要变动的配置项,尤其是密码和密钥。
注意:不要给值加引号,除非值本身包含特殊字符。
# 数据库配置
MYSQL_ROOT_PASSWORD=my_secret_password
MYSQL_DATABASE=wordpress
# 应用密钥
APP_SECRET=super_secret_key_change_me
第二步:在 docker-compose.yml 中引用变量
打开 docker-compose.yml,使用 ${VAR_NAME} 语法引用 .env 中的变量。
version: '3.8'
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
web:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: ${MYSQL_ROOT_PASSWORD}
WORDPRESS_SECRET: ${APP_SECRET}
当你在项目目录下执行 docker compose up -d 时,Compose 会自动读取同目录下的 .env 文件,完成变量替换。
第三步:使用 shell 环境变量覆盖默认值
有时需要临时修改变量,比如在 CI/CD 流水线中。
你可以在执行命令前直接定义环境变量,它比 .env 文件中的值优先级更高。
MYSQL_ROOT_PASSWORD=temp_password docker compose up -d
这种做法的原理是:Compose 会先读取 .env,但如果 shell 中已有同名变量,则使用 shell 中的值。
避坑指南:常见错误与安全建议
.env 文件务必加入 .gitignore
如果你的项目使用 Git,一定记得把 .env 加入 .gitignore,否则一旦提交,密码就直接暴露在仓库历史中了。
# .gitignore 内容
.env
不要使用默认的变量名
很多人图省事,直接使用 Docker 官方镜像文档中示例的变量名,如 MYSQL_ROOT_PASSWORD=root。
攻击者往往先尝试这些默认值,所以务必修改为强密码。
不要在 Dockerfile 中硬编码密钥
环境变量管理不仅适用于 compose 文件,在 Dockerfile 中也应避免 ENV 指令直接写入密钥,因为镜像层会缓存这些值,导致密钥被泄露。
推荐使用 ARG 或构建时传入。
验证变量是否生效
启动容器后,可以通过以下命令检查容器内的环境变量是否正确注入:
docker compose exec db env | grep MYSQL_ROOT_PASSWORD
如果输出显示的是你设置的密码,说明配置成功。
另外,不要使用 docker inspect 查看,因为环境变量对任何能访问 Docker socket 的人都是可见的,这并不安全。
进阶:使用 env_file 管理多个环境
当你的服务数量很多时,可以把所有环境变量写在一个文件里,然后在 compose 中通过 env_file 直接引入,这样更清晰。
services:
web:
image: wordpress:latest
env_file:
- ./web.env
注意,env_file 中的变量会覆盖 .env 文件中的同名变量,但不会覆盖 shell 环境变量。
小结与验证
通过以上步骤,你已经学会了如何将密码和密钥从 compose 文件中抽离,集中到 .env 文件中动态管理。
这样不仅提升了安全性,也让配置变得可移植。
最后,请务必检查:你的仓库中没有包含 .env 文件,并且容器环境变量已正确设置。
如果发现任何遗漏,及时修正。
如果你在操作过程中遇到变量不生效的情况,先检查文件名是否为 .env、格式是否正确,以及是否在同一个目录下执行命令。
如果你正在处理 Docker Compose 环境变量管理,不要硬编码密码密钥,建议先按本文步骤完整执行,再根据自己的环境做微调;
遇到异常时优先回看避坑和高频问题部分。