docker构建传环境变量需分清build-time与run-time:用arg+--build-arg传构建参数(不固化镜像),env设运行时默认值,--env/-e运行时覆盖(敏感信息必选此方式)。

在 Docker 构建过程中传递环境变量,核心是区分两种场景:构建时(build-time)可用的变量,和容器运行时(run-time)才生效的变量。很多人混淆 ENV、ARG 和 --env 的用法,导致变量传不进去、镜像里没生效,或者敏感信息被意外固化到镜像层。下面讲清楚怎么在实战中正确传递。
用 ARG + --build-arg 传构建期参数
ARG 是唯一专为构建阶段设计的变量声明指令,它只在 docker build 过程中有效,不会留在最终镜像里(除非你用它赋值给 ENV)。适合传版本号、构建开关、非敏感配置等。
- 在 Dockerfile 开头或需要前声明:
ARG APP_VERSIONARG BUILD_ENV=prod - 可在 RUN 中直接使用:
RUN echo "Building $APP_VERSION for $BUILD_ENV" - 构建时传入:
docker build --build-arg APP_VERSION=1.2.3 --build-arg BUILD_ENV=staging -t myapp . - 支持默认值(如上例
BUILD_ENV=prod),未传参时自动回退
用 ENV 固化运行时环境变量
ENV 设置的变量会写入镜像元数据,所有后续层及容器启动后都可见。适合通用配置,比如 PATH、LANG、应用默认端口等。
- 写法:
ENV NODE_ENV=productionENV PORT=3000 - 也可用 ARG 赋值实现“构建时决定、运行时生效”:
ARG NODE_ENVENV NODE_ENV=${NODE_ENV:-development} - 注意:ENV 值在构建时就展开,不能动态读取宿主机文件或命令结果(要用 RUN + shell 实现)
运行时再覆盖:docker run --env 或 -e
构建好的镜像启动时,可用 --env 或 -e 覆盖 ENV 声明的值,或新增变量。这是最安全灵活的方式,尤其适合密钥、数据库地址等敏感/多环境配置。
- 例如:
docker run -e DB_HOST=10.0.1.5 -e DB_USER=admin myapp - 支持从文件加载:
docker run --env-file ./prod.env myapp(prod.env每行KEY=VALUE) - 注意:--env 传的变量 不会影响构建过程,只作用于容器运行时
避坑提醒:别把密码/密钥写进 ARG 或 ENV
虽然 ARG 不留痕,但如果在 RUN 中用它拼接 curl 下载、解密操作,命令历史可能被缓存层记录;而 ENV 值直接写在镜像配置里,docker inspect 就能看见——这等于把密钥打包发布。
- 正确做法:敏感信息一律通过
--env、--env-file或挂载/run/secrets(swarm)传递 - 避免写法:
ARG API_KEYRUN curl -H "X-Key: $API_KEY" https://api.example.com/data - 替代方案:构建时不依赖密钥,运行时由应用从环境变量读取并调用










