mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-10 11:54:37 +00:00
Add more content
This commit is contained in:
@@ -1,68 +1,238 @@
|
||||
# ARG 构建参数
|
||||
|
||||
格式:`ARG <参数名>[=<默认值>]`
|
||||
|
||||
构建参数和 `ENV` 的效果一样,都是设置环境变量。所不同的是,`ARG` 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用 `ARG` 保存密码之类的信息,因为 `docker history` 还是可以看到所有值的。
|
||||
|
||||
`Dockerfile` 中的 `ARG` 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 `docker build` 中用 `--build-arg <参数名>=<值>` 来覆盖。
|
||||
|
||||
灵活的使用 `ARG` 指令,能够在不修改 Dockerfile 的情况下,构建出不同的镜像。
|
||||
|
||||
ARG 指令有生效范围,如果在 `FROM` 指令之前指定,那么只能用于 `FROM` 指令中。
|
||||
## 基本语法
|
||||
|
||||
```docker
|
||||
ARG DOCKER_USERNAME=library
|
||||
|
||||
FROM ${DOCKER_USERNAME}/alpine
|
||||
|
||||
RUN set -x ; echo ${DOCKER_USERNAME}
|
||||
ARG <参数名>[=<默认值>]
|
||||
```
|
||||
|
||||
使用上述 Dockerfile 会发现无法输出 `${DOCKER_USERNAME}` 变量的值,要想正常输出,你必须在 `FROM` 之后再次指定 `ARG`
|
||||
`ARG` 指令定义构建时的变量,可以在 `docker build` 时通过 `--build-arg` 传入。
|
||||
|
||||
---
|
||||
|
||||
## 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 值。
|
||||
|
||||
---
|
||||
|
||||
## 基本用法
|
||||
|
||||
### 定义和使用
|
||||
|
||||
```docker
|
||||
# 只在 FROM 中生效
|
||||
ARG DOCKER_USERNAME=library
|
||||
# 定义有默认值的 ARG
|
||||
ARG NODE_VERSION=20
|
||||
|
||||
FROM ${DOCKER_USERNAME}/alpine
|
||||
|
||||
# 要想在 FROM 之后使用,必须再次指定
|
||||
ARG DOCKER_USERNAME=library
|
||||
|
||||
RUN set -x ; echo ${DOCKER_USERNAME}
|
||||
# 使用 ARG
|
||||
FROM node:${NODE_VERSION}-alpine
|
||||
RUN echo "Using Node.js $NODE_VERSION"
|
||||
```
|
||||
|
||||
对于多阶段构建,尤其要注意这个问题
|
||||
### 构建时覆盖
|
||||
|
||||
```bash
|
||||
# 使用默认值
|
||||
$ docker build -t myapp .
|
||||
|
||||
# 覆盖默认值
|
||||
$ docker build --build-arg NODE_VERSION=18 -t myapp .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ARG 的作用域
|
||||
|
||||
### FROM 之前的 ARG
|
||||
|
||||
```docker
|
||||
# 这个变量在每个 FROM 中都生效
|
||||
ARG DOCKER_USERNAME=library
|
||||
# FROM 之前的 ARG 只能用于 FROM 指令
|
||||
ARG REGISTRY=docker.io
|
||||
ARG IMAGE_NAME=node
|
||||
|
||||
FROM ${DOCKER_USERNAME}/alpine
|
||||
FROM ${REGISTRY}/${IMAGE_NAME}:20
|
||||
|
||||
RUN set -x ; echo 1
|
||||
|
||||
FROM ${DOCKER_USERNAME}/alpine
|
||||
|
||||
RUN set -x ; echo 2
|
||||
# ❌ 这里无法使用上面的 ARG
|
||||
RUN echo $REGISTRY # 输出空
|
||||
```
|
||||
|
||||
对于上述 Dockerfile 两个 `FROM` 指令都可以使用 `${DOCKER_USERNAME}`,对于在各个阶段中使用的变量都必须在每个阶段分别指定:
|
||||
### FROM 之后重新声明
|
||||
|
||||
```docker
|
||||
ARG DOCKER_USERNAME=library
|
||||
ARG NODE_VERSION=20
|
||||
|
||||
FROM ${DOCKER_USERNAME}/alpine
|
||||
FROM node:${NODE_VERSION}-alpine
|
||||
|
||||
# 在FROM 之后使用变量,必须在每个阶段分别指定
|
||||
ARG DOCKER_USERNAME=library
|
||||
|
||||
RUN set -x ; echo ${DOCKER_USERNAME}
|
||||
|
||||
FROM ${DOCKER_USERNAME}/alpine
|
||||
|
||||
# 在FROM 之后使用变量,必须在每个阶段分别指定
|
||||
ARG DOCKER_USERNAME=library
|
||||
|
||||
RUN set -x ; echo ${DOCKER_USERNAME}
|
||||
# 需要再次声明才能使用
|
||||
ARG NODE_VERSION
|
||||
RUN echo "Node version: $NODE_VERSION"
|
||||
```
|
||||
|
||||
### 多阶段构建中的 ARG
|
||||
|
||||
```docker
|
||||
ARG BASE_VERSION=alpine
|
||||
|
||||
FROM node:20-${BASE_VERSION} AS builder
|
||||
# 需要重新声明
|
||||
ARG NODE_VERSION=20
|
||||
RUN echo "Building with Node $NODE_VERSION"
|
||||
|
||||
FROM node:20-${BASE_VERSION}
|
||||
# 每个阶段都需要重新声明
|
||||
ARG NODE_VERSION=20
|
||||
RUN echo "Running with Node $NODE_VERSION"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常见使用场景
|
||||
|
||||
### 1. 控制基础镜像版本
|
||||
|
||||
```docker
|
||||
ARG ALPINE_VERSION=3.19
|
||||
FROM alpine:${ALPINE_VERSION}
|
||||
```
|
||||
|
||||
```bash
|
||||
$ docker build --build-arg ALPINE_VERSION=3.18 .
|
||||
```
|
||||
|
||||
### 2. 设置软件版本
|
||||
|
||||
```docker
|
||||
ARG NGINX_VERSION=1.25.0
|
||||
|
||||
RUN curl -fsSL https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz | tar -xz
|
||||
```
|
||||
|
||||
### 3. 配置构建环境
|
||||
|
||||
```docker
|
||||
ARG BUILD_ENV=production
|
||||
ARG ENABLE_DEBUG=false
|
||||
|
||||
RUN if [ "$ENABLE_DEBUG" = "true" ]; then \
|
||||
npm install --include=dev; \
|
||||
else \
|
||||
npm install --production; \
|
||||
fi
|
||||
```
|
||||
|
||||
### 4. 配置私有仓库
|
||||
|
||||
```docker
|
||||
ARG NPM_TOKEN
|
||||
|
||||
RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc && \
|
||||
npm install && \
|
||||
rm ~/.npmrc
|
||||
```
|
||||
|
||||
```bash
|
||||
# 构建时传入 token
|
||||
$ docker build --build-arg NPM_TOKEN=xxx .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 将 ARG 传递给 ENV
|
||||
|
||||
如果需要在运行时使用 ARG 的值:
|
||||
|
||||
```docker
|
||||
ARG VERSION=1.0.0
|
||||
|
||||
# 将 ARG 传递给 ENV
|
||||
ENV APP_VERSION=$VERSION
|
||||
|
||||
# 运行时可用
|
||||
CMD echo "App version: $APP_VERSION"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 预定义 ARG
|
||||
|
||||
Docker 提供了一些预定义的 ARG,无需声明即可使用:
|
||||
|
||||
| ARG | 说明 |
|
||||
|-----|------|
|
||||
| `HTTP_PROXY` | HTTP 代理 |
|
||||
| `HTTPS_PROXY` | HTTPS 代理 |
|
||||
| `NO_PROXY` | 不使用代理的地址 |
|
||||
| `FTP_PROXY` | FTP 代理 |
|
||||
|
||||
```bash
|
||||
# 构建时使用代理
|
||||
$ docker build --build-arg HTTP_PROXY=http://proxy:8080 .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 为 ARG 提供合理默认值
|
||||
|
||||
```docker
|
||||
# ✅ 好:有默认值
|
||||
ARG NODE_VERSION=20
|
||||
|
||||
# ⚠️ 需要每次传入
|
||||
ARG NODE_VERSION
|
||||
```
|
||||
|
||||
### 2. 不要用 ARG 存储敏感信息
|
||||
|
||||
```docker
|
||||
# ❌ 错误:密码会被记录在镜像历史中
|
||||
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.11-alpine .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 本章小结
|
||||
|
||||
| 要点 | 说明 |
|
||||
|------|------|
|
||||
| **作用** | 定义构建时变量 |
|
||||
| **语法** | `ARG NAME=value` |
|
||||
| **覆盖** | `docker build --build-arg NAME=value` |
|
||||
| **作用域** | FROM 之后需要重新声明 |
|
||||
| **vs ENV** | ARG 仅构建时,ENV 构建+运行时 |
|
||||
| **安全** | 不要存储敏感信息 |
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [ENV 设置环境变量](env.md):运行时环境变量
|
||||
- [FROM 指令](../../image/build.md):基础镜像指定
|
||||
- [多阶段构建](../multistage-builds.md):复杂构建场景
|
||||
|
||||
Reference in New Issue
Block a user