ref="/tag/2019/" style="color:#B2A89E;font-weight:bold;">Docker镜像环境变量设置:实用技巧与常见用法
在部署应用时,不同环境需要不同的配置,比如开发环境连本地数据库,生产环境连线上库。硬编码这些信息显然不现实,这时候环境变量就派上用场了。Docker 支持在构建镜像和运行容器时设置环境变量,灵活又安全。
使用 Dockerfile 设置环境变量
在构建镜像时,可以用 ENV 指令预设环境变量。比如你有个 Node.js 应用,依赖 NODE_ENV 来决定是否开启调试模式:
FROM node:16-alpine
WORKDIR /app
COPY . .
ENV NODE_ENV=production
ENV PORT=3000
RUN npm install
CMD ["npm", "start"]
这样构建出的镜像,默认就带上了这两个变量。启动容器时不用额外指定,适合那些基本不变的配置。
运行容器时传入环境变量
更常见的做法是在运行容器时动态传参。比如同一个镜像,开发时想临时切到测试环境:
docker run -d \
-e NODE_ENV=development \
-e DB_HOST=test-db.example.com \
-p 3000:3000 \
my-web-app
这里的 -e 参数可以多次使用,灵活注入。运维人员在上线前检查配置,改个参数就能切换数据库地址,不用重新打包镜像。
通过文件批量加载环境变量
当变量较多时,写命令行容易出错。Docker 支持用 --env-file 从文件读取:
docker run --env-file ./config/prod.env -d my-web-app
文件内容格式简单,每行一个 KEY=VALUE:
DB_HOST=prod-db.internal
DB_USER=admin
DB_PASS=secret123
REDIS_URL=redis://cache:6379
敏感信息如密码可以集中管理,配合权限控制,避免泄露。
环境变量的优先级问题
如果 Dockerfile 里用 ENV 设了 PORT=3000,运行时又用 -e PORT=80,最终生效的是运行时传入的值。也就是说,容器启动时传的变量会覆盖镜像中定义的同名变量。这个机制让配置更灵活,也减少了镜像数量。
在应用代码中读取环境变量
不管怎么传,最终还得程序自己去拿。以 Python 为例:
import os
port = int(os.getenv('PORT', 5000))
db_host = os.getenv('DB_HOST', 'localhost')
print(f"Starting server on port {port}, connecting to {db_host}")
这样代码兼容性强,本地跑用默认值,上 Docker 就自动适配传入的配置。
避免把敏感信息直接写进镜像
有人图省事,在 Dockerfile 里写 ENV API_KEY=abc123,这是大忌。镜像一旦推送,密钥就藏不住了。正确做法是运行时通过 -e 或 --env-file 注入,或者结合 Docker Secrets(适用于 Swarm)或外部配置中心。