arg 实现构建期变量动态传递,需声明(如 arg app_env=production)、传入(--build-arg 或 .buildargs)、使用(run/label/env 引用)三步闭环;不支持运行时,敏感信息禁用,缓存问题需注意。

用 ARG 实现构建期变量动态传递,核心是声明、传入、使用三步闭环。它不是运行时配置,而是让同一个 Dockerfile 能适配不同版本、环境或编译选项的关键机制。
在 Dockerfile 中正确定义 ARG
ARG 必须显式声明才能被识别,建议都设默认值,避免构建中断:
- 写法示例:
ARG APP_ENV=production、ARG VERSION=0.1.0、ARG BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ) - 命令替换(如
$(date ...))只能在 RUN 中执行,ARG 行本身不支持 shell 执行 - 若需用于 FROM 指令(比如切换基础镜像),必须把 ARG 放在 FROM 之前声明
- 多阶段构建中,每个 FROM 后都是新阶段,ARG 不自动继承,需在每个阶段开头重新声明
通过 --build-arg 或文件传入值
构建命令是变量落地的入口,有三种常用方式:
- 单次构建:直接用
--build-arg,例如docker build --build-arg APP_ENV=staging --build-arg VERSION=2.3.0 -t myapp:staging . - 批量配置:新建
.buildargs文件,每行KEY=VALUE,再用$(cat .buildargs | xargs -I {} echo "--build-arg {}")展开传入 - CI/CD 集成:GitHub Actions 中写
--build-arg COMMIT_SHA=${{ github.sha }},GitLab CI 写--build-arg CI_PIPELINE_ID=$CI_PIPELINE_ID
在构建指令中真正用起来
ARG 声明后不会自动生效,必须显式引用:
- RUN 中使用:
RUN npm ci --only=${APP_ENV}、RUN go build -ldflags "-X main.Version=${VERSION}" -o app . - LABEL 中记录元数据:
LABEL org.opencontainers.image.version=${VERSION} - 转为 ENV 才能在容器里访问:
ENV APP_ENV=$APP_ENV(注意不能写成${APP_ENV:-dev},ENV 不支持这种语法)
避开几个高频坑
很多问题其实卡在细节上:
- 未声明的 ARG,即使传了也会被忽略;已声明但没默认值又没传参,构建会失败
- 敏感信息(如 token、密钥)别用 ARG,它会留在镜像历史层里,改用
buildx build --secret - 构建缓存可能让参数“不生效”,可加
--no-cache或调整 ARG 位置(靠近相关 RUN 指令) - ARG 和 ENV 是两回事:前者只在构建时存在,后者才进镜像并供运行时读取











