在Dockerfile中使用ENV指令定义环境变量,核心是区分构建与运行时作用域、避免硬编码敏感信息、注意变量展开规则;语法支持单变量(ENV KEY=value)和多变量一行(ENV KEY1=val1 KEY2=val2),等号无空格,值含空格需加引号;ENV变量持久存在于镜像及容器运行时,而ARG仅限构建阶段;变量可在后续指令中用$KEY引用,但exec格式CMD/ENTRYPOINT不自动展开;敏感信息严禁用ENV存储,应通过--secret、-e或配置中心注入。

在 Dockerfile 中写 ENV 变量,核心是用 ENV 指令声明环境变量,语法简单但细节影响运行时行为。关键在于区分构建时和运行时作用域、避免敏感信息硬编码、注意变量展开时机。
基本写法和两种语法格式
ENV 支持两种写法,效果相同,推荐第一种(更清晰):
-
单个变量:
ENV KEY=value,例如ENV NODE_ENV=production -
多变量一行:
ENV KEY1=value1 KEY2=value2,例如ENV TZ=Asia/Shanghai LANG=C.UTF-8
注意:等号=前后不能有空格;value 中含空格需用引号包裹,如 ENV APP_NAME="my app"。
ENV 和 ARG 的区别别搞混
ARG 是构建参数,只在 docker build 过程中有效;ENV 是镜像层的一部分,会保留在最终镜像里,容器启动后仍存在。
- 想让变量在容器运行时生效 → 用 ENV
- 只想在构建阶段传值(比如镜像 tag、源码分支)→ 用 ARG,必要时再用 ENV 赋值保留,例如:
ARG BUILD_VERSIONENV VERSION=$BUILD_VERSION
变量引用和展开规则
Dockerfile 中 ENV 定义的变量,可在后续的 RUN、CMD、ENTRYPOINT 等指令中用 $KEY 或 ${KEY} 引用。
- 支持嵌套展开:
ENV HOME=/root→ENV PATH=$HOME/bin:$PATH - 不支持反向引用或条件判断,纯文本替换
- 如果变量未定义,默认为空字符串,不会报错
注意:在 shell 形式 CMD/ENTRYPOINT 中能正常展开;在 exec 形式(数组写法)中,$VAR 不会自动展开,需显式调用 sh -c,例如:ENTRYPOINT ["sh", "-c", "echo $HOSTNAME"]
安全和最佳实践提醒
ENV 不适合存密码、密钥等敏感信息:
- 所有 ENV 都会成为镜像历史的一部分,用
docker history或解包可轻易查看 - 应改用 构建时挂载(--secret)、运行时注入(docker run -e)或配置中心
- 避免覆盖系统关键变量(如 PATH、HOME),除非明确知道后果
冗余 ENV 建议合并,减少镜像层数;常变变量(如版本号)优先通过 ARG + ENV 组合方式传入。


















