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. 設定私有倉庫

不要用 ARGENV 傳遞倉庫 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 .

...

第 56 页,共 196 页
使用 mdPress 构建