Dockerfile中环境变量应只声明用途、不固化敏感值,区分构建时(ARG)与运行时(ENV);ENV设非敏感默认值,ARG传构建参数并可转为ENV,敏感配置须运行时注入。

在 Dockerfile 中写入环境变量,核心原则是:只声明用途、不固化敏感值,区分构建时和运行时用途。
ENV 指令:用于设置镜像级默认值
ENV 是最常用的方式,它把变量写入镜像层,容器启动时自动生效。适合非敏感、跨环境一致的配置,比如应用端口、日志级别:
-
推荐写法:给出安全默认值,不暴露真实配置
ENV NODE_ENV=productionENV APP_PORT=3000ENV LOG_LEVEL=info -
禁止写法:避免硬编码密码、密钥、生产数据库地址等
ENV DB_PASSWORD=prod123❌(会被docker inspect查看,且无法动态替换) -
变量引用:支持前序 ENV 变量展开,便于组合
ENV API_BASE_URL=https://api.example.comENV USER_API_URL=${API_BASE_URL}/users
ARG + ENV 组合:构建时传参,仅用于非运行时信息
ARG 只在构建阶段存在,适合版本号、Git 提交 ID、基础镜像标签等;若需保留在镜像中,再用 ENV 赋值:
-
ARG BUILD_VERSIONENV APP_VERSION=${BUILD_VERSION} - 构建命令:
docker build --build-arg BUILD_VERSION=2.4.1 -t myapp . - 注意:ARG 不会进入最终镜像,除非显式转为 ENV;也不该用来传数据库地址等运行时配置。
不推荐:直接从 .env 文件构建时注入(破坏可复现性)
虽然可用 ARG + cat .env | xargs 把本地 .env 值塞进镜像,但这样会导致:
- 同一份 Dockerfile 构建出不同镜像(违反“一次构建、处处运行”原则)
- 生产配置意外混入开发镜像
- CI/CD 流水线难以审计和回滚
真正需要按环境区分的配置,应交给运行时注入(docker run -e 或 --env-file),Dockerfile 只负责声明“我需要哪些变量”。
配套关键点:应用必须主动读取环境变量
Dockerfile 写了 ENV,不代表应用自动生效。代码里得显式读取:
- Python:
os.environ.get("APP_PORT", "3000") - Node.js:
process.env.APP_PORT || "3000" - Java/Spring Boot:
@Value("${APP_PORT:3000}")或System.getenv("APP_PORT") - 务必提供合理默认值,防止缺失变量导致启动失败


















