Files
docker_practice/07_dockerfile/7.7_arg.md
T
yeasy ef2625531d style: 含中文的括号统一为全角(336 处 / 110 文件)
全书此前是真·五五开:含中文的括号 336 处半角 : 336 处全角,而且**在同一文件
内混用**——`18_security/18.1_kernel_ns.md` 第 11/17/20 行写 `(如 runC)`,
第 31 行写 `(用户命名空间映射)`。这不是体例问题,是它自己跟自己不一致。

集群里其余 13 本都一边倒(llm_internals 5 : 1049、oc_guide 2 : 713、
forward_deployed_engineering_guide 0 : 108),blockchain_guide 已在 2026-08-05
按同一方向统一过 97 处,故取全角,而非另立新规。全角括号前后不留空格,
原先 `概念 (镜像、容器、仓库) 和` 两侧的空格一并收掉。

**纯拉丁内容的半角括号一个没动**——`新建一个层 (Layer)`、`项目 (project)`
保持原样:改动前后「半角且内容纯拉丁」的数量都是 **1163**,而「半角且含中文」
从 **336 变成 0**。

其余验证:改动前后各自抹掉全部空白与圆括号后**逐字节相同**(两侧均 19559 字符);
左右括号总数改动前后都是 399 : 399,证明没有吞括号也没有配错对。
`check_project_rules` 202/202、`check_emphasis` 202/202、37 tests OK、
根 `format_checker` 与 `validate_codeblocks` 干净、`git diff --check` 干净。
2026-08-24 13:13:23 -07:00

4.8 KiB

7.7 ARG 构建参数

7.7.1 基本语法

ARG <参数名>[=<默认值>]

ARG 指令定义构建时的变量,可以在 docker build 时通过 --build-arg 传入。


7.7.2 ARG vs ENV

特性 ARG ENV
生效时间 仅构建时 构建时 + 运行时
持久性 构建后消失 写入镜像
覆盖方式 docker build --build-arg docker run -e
适用场景 构建参数(版本号等) 应用配置
可见性 docker history 可见 docker inspect 可见
构建时                         运行时
├─ ARG VERSION=1.0             │ (ARG 已消失)
├─ ENV APP_ENV=prod            │ APP_ENV=prod(仍存在)
└─ RUN echo $VERSION           │

⚠️ 安全提示:不要用 ARG 传递密码等敏感信息,docker history 可以查看所有 ARG 值。


7.7.3 基本用法

定义和使用

## 定义有默认值的 ARG
## 建议使用主版本号,如 20 而非 20.10.0,这样可以自动获取最新的补丁版本

ARG NODE_VERSION=20

## 使用 ARG

FROM node:${NODE_VERSION}-alpine
RUN echo "Using Node.js $NODE_VERSION"

构建时覆盖

## 使用默认值

$ docker build -t myapp .

## 覆盖默认值

$ docker build --build-arg NODE_VERSION=18 -t myapp .

7.7.4 ARG 的作用域

FROM 之前的 ARG

## FROM 之前的 ARG 只能用于 FROM 指令

ARG REGISTRY=docker.io
ARG IMAGE_NAME=node

FROM ${REGISTRY}/${IMAGE_NAME}:20

## ❌ 这里无法使用上面的 ARG

RUN echo $REGISTRY  # 输出空

FROM 之后重新声明

ARG NODE_VERSION=20

FROM node:${NODE_VERSION}-alpine

## 需要再次声明才能使用

ARG NODE_VERSION
RUN echo "Node version: $NODE_VERSION"

多阶段构建中的 ARG

ARG BASE_VERSION=alpine

FROM node:22-${BASE_VERSION} AS builder

## 需要重新声明

ARG NODE_VERSION=20
RUN echo "Building with Node $NODE_VERSION"

FROM node:22-${BASE_VERSION}

## 每个阶段都需要重新声明

ARG NODE_VERSION=20
RUN echo "Running with Node $NODE_VERSION"

7.7.5 常见使用场景

1. 控制基础镜像版本

# 推荐使用主版本号(如 3),或指定次版本号(如 3.19),避免指定完整补丁版本
ARG ALPINE_VERSION=3
FROM alpine:${ALPINE_VERSION}
$ docker build --build-arg ALPINE_VERSION=3.19 .

2. 设置软件版本

# 使用次版本号 (1.30) 而非完整版本号 (1.30.0),以便自动更新到最新补丁版本
ARG NGINX_VERSION=1.30

RUN curl -fsSL https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz | tar -xz

3. 配置构建环境

ARG BUILD_ENV=production
ARG ENABLE_DEBUG=false

RUN if [ "$ENABLE_DEBUG" = "true" ]; then \
        npm install --include=dev; \
    else \
        npm install --production; \
    fi

4. 配置私有仓库

不要用 ARG 或 ENV 传递仓库 token。Docker 官方构建检查会把这类写法视为不安全,因为构建参数和环境变量可能进入镜像元数据或历史记录。使用 BuildKit secret mount 只在单条 RUN 指令期间暴露凭据:

RUN --mount=type=secret,id=npm_token \
    NPM_TOKEN="$(cat /run/secrets/npm_token)" && \
    printf "//registry.npmjs.org/:_authToken=%s\n" "$NPM_TOKEN" > ~/.npmrc && \
    npm install && \
    rm ~/.npmrc
## 构建时传入 token

$ docker build --secret id=npm_token,env=NPM_TOKEN .

7.7.6 将 ARG 传递给 ENV

如果需要在运行时使用 ARG 的值:

ARG VERSION=1.0.0

## 将 ARG 传递给 ENV

ENV APP_VERSION=$VERSION

## 运行时可用

CMD echo "App version: $APP_VERSION"

7.7.7 预定义 ARG

Docker 提供了一些预定义的 ARG,无需声明即可使用:

ARG 说明
HTTP_PROXY HTTP 代理
HTTPS_PROXY HTTPS 代理
NO_PROXY 不使用代理的地址
FTP_PROXY FTP 代理
## 构建时使用代理

$ docker build --build-arg HTTP_PROXY=http://proxy:8080 .

7.7.8 最佳实践

1. 为 ARG 提供合理默认值

## ✅ 好:有默认值,建议使用主或次版本号而非完整版本号

ARG NODE_VERSION=20

## ⚠️ 需要每次传入

ARG NODE_VERSION

2. 不要用 ARG 存储敏感信息

## ❌ 错误:密码会被记录在镜像历史中

ARG DB_PASSWORD
RUN echo "password=$DB_PASSWORD" > /app/.env

## ✅ 正确:使用 secrets 或运行时环境变量

...

3. 使用 ARG 提高构建灵活性

# 推荐使用次版本号标签,允许Docker自动拉取最新的补丁版本
ARG BASE_IMAGE=python:3.12-slim
FROM ${BASE_IMAGE}

## 可以构建不同基础镜像的版本

## docker build --build-arg BASE_IMAGE=python:3-slim .

...