docker 的 arg 指令支持构建时传参以实现动态编译,需在 from 后声明、run 前使用,配合 --build-arg 传入,可与 go/cmake/rust 等工具集成,但不保留于运行时,敏感信息应使用 buildkit secret。

通过 Docker 的 ARG 指令,你可以在构建镜像时传入变量,从而控制编译行为(比如指定版本、启用/禁用特性、切换编译目标等),实现“动态编译”。关键在于:把 ARG 值传递给构建系统(如 Make、CMake、Go、Rust 等),并在编译命令中实际使用它。
在 Dockerfile 中定义并使用 ARG 控制编译参数
ARG 必须在 FROM 之后、RUN 之前声明;若需在构建阶段后继续使用(例如运行时),需用 ENV 显式保留。常见用法:
- 在
Dockerfile开头声明:ARG BUILD_MODE=release(带默认值更健壮) - 在
RUN中调用:RUN make MODE=${BUILD_MODE} build - 跨阶段传递(多阶段构建中):每个
FROM后需重新声明ARG,或用--build-arg透传
与主流构建工具结合的典型示例
不同语言生态对构建变量的支持方式不同,需适配:
-
Go 项目:用
-ldflags "-X main.Version=${VERSION}"注入版本号,ARG VERSION=dev→RUN go build -ldflags "-X main.Version=${VERSION}" -o app . -
CMake 项目:用
-D传参,ARG ENABLE_GPU=OFF→RUN cmake -B build -S . -DENABLE_GPU=${ENABLE_GPU} -
Rust 项目:用
--cfg或环境变量,ARG FEATURES=sqlite→RUN FEATURES=${FEATURES} cargo build --features ${FEATURES} --release
构建时传入参数的正确方式
使用 docker build 的 --build-arg 选项,多个参数可重复使用该标志:
docker build --build-arg VERSION=v1.2.0 --build-arg BUILD_MODE=debug -t myapp .- 注意:未在 Dockerfile 中声明的
ARG会被忽略,不会报错;敏感值(如密钥)不应通过ARG传入,应改用BUILDKIT的 secret 机制 - 配合
.dockerignore避免误传本地文件影响确定性构建
避免常见陷阱
ARG 是构建期变量,不是运行时环境变量,这点极易混淆:
-
ARG在镜像层中不保留(除非显式用ENV赋值),容器启动后不可见 - 不要在
FROM行中直接引用未声明的ARG(Docker 20.10+ 支持,但需前置声明) - 多阶段构建中,前一阶段的
ARG不自动继承到下一阶段,必须在每个阶段开头重新声明 - 如果构建缓存导致参数未生效,加
--no-cache或调整ARG声明位置(靠近相关RUN)










