返回
创建于
状态
公开

Docker 构建利器:深度解析 --build-arg 的正确姿势

在容器化流程中,我们经常需要根据不同的环境(开发、测试、生产)构建略有差异的镜像。--build-arg(配合 Dockerfile 中的 ARG 指令)正是为此而生的构建时变量工具。

1. 核心工作流:从命令行到 Dockerfile

--build-arg 的本质是在执行 docker build 时,向 Dockerfile 内部注入变量。

  • 第一步:在 Dockerfile 中声明 使用 ARG 指令定义变量名,可以赋初始值。
    dockerfile
    1ARG NODE_VERSION=18
    2FROM node:${NODE_VERSION}-slim
  • 第二步:在构建命令中注入 使用 --build-arg 覆盖默认值。
    bash
    1docker build --build-arg NODE_VERSION=20 -t my-app:v2 .

2. 进阶技巧:跨阶段传递

ARG 的作用域非常严苛。如果你使用多阶段构建 (Multi-stage builds),需要注意每个 FROM 之后都是一个新的阶段,之前的 ARG 会失效。

正确做法:

dockerfile
1# 1. 在第一个 FROM 之前声明,可全局使用(仅限 FROM 指令)
2ARG VERSION=3.11
3
4FROM python:${VERSION}-slim as builder
5# 2. 在每个阶段内部重新引入一次,才能在 RUN 中使用
6ARG VERSION
7RUN echo "Building with Python ${VERSION}"
8
9FROM python:${VERSION}-slim
10ARG VERSION
11COPY --from=builder /app /app

3. 避坑指南:正确做法 vs 错误做法

❌ 错误:用 ARG 传递敏感信息

原因: ARG 的值会明文记录在镜像的元数据中。任何能拿到镜像的人只需执行 docker history <image> 就能看到你的私钥或数据库密码。

✅ 正确:使用 --secret (推荐)

对于密钥、Token 等敏感数据,应使用 Docker 18.09+ 引入的 BuildKit 密钥挂载功能:

bash
1# 构建命令
2docker build --secret id=mytoken,src=~/.token -t my-app .
dockerfile
1# Dockerfile 中安全引用
2RUN --mount=type=secret,id=mytoken TOKEN=$(cat /run/secrets/mytoken) && ./install.sh

❌ 错误:在运行时依赖 ARG

原因: 镜像一旦构建完成,ARG 就“烟消云散”了。容器运行时无法直接访问它。

✅ 正确:将 ARG 转存为 ENV

如果你需要变量在构建和运行时都生效,请手动转存:

dockerfile
1ARG APP_MODE=production
2ENV APP_MODE=${APP_MODE}

4. 总结:什么时候用 --build-arg?

场景是否推荐替代方案
切换基础镜像版本⭐⭐⭐⭐⭐
设置构建时的代理 (HTTP_PROXY)⭐⭐⭐⭐⭐
区分编译环境 (Dev/Prod)⭐⭐⭐⭐-
传递数据库密码/API Key绝对禁止--secret
定义容器运行时的配置❌ 不建议ENV 或 挂载配置文件

一句话总结: ARG 是为了让 Dockerfile 模板化,而 ENV 是为了让应用配置化。