构建参数与变量

Dockerfile 中 ARG 和 ENV 的使用,构建参数传递


📋 目录


ARG 构建参数

定义 ARG

# 定义构建参数
ARG VERSION=latest
ARG BUILD_DATE
ARG NODE_ENV=production

使用 ARG

# 在 Dockerfile 中使用
ARG VERSION
LABEL version=$VERSION
 
ARG BUILD_DATE
LABEL build-date=$BUILD_DATE
 
# 在 RUN 指令中使用
ARG NODE_ENV
RUN echo "Building for $NODE_ENV"

ARG 作用域

# ARG 只在定义它的构建阶段有效
FROM node:16 AS builder
ARG VERSION
# VERSION 在这个阶段有效
 
FROM nginx:alpine
# VERSION 在这个阶段无效,需要重新定义
ARG VERSION

ENV 环境变量

定义 ENV

# 定义环境变量
ENV NODE_ENV=production
ENV PORT=3000
 
# 定义多个环境变量
ENV NODE_ENV=production \
    PORT=3000 \
    DEBUG=false

使用 ENV

# 在 Dockerfile 中使用
ENV PATH=$PATH:/usr/local/bin
 
# 在 RUN 指令中使用
ENV APP_NAME=myapp
RUN echo "App name: $APP_NAME"

ENV 持久性

ENV 定义的环境变量在容器运行时仍然存在。

ENV NODE_ENV=production
# 容器运行时,NODE_ENV 仍然可用

ARG 与 ENV 的区别

作用域

特性ARGENV
作用时间构建时构建时 + 运行时
作用范围单个构建阶段所有后续阶段和容器运行时
可覆盖是(构建时)是(运行时)
用途构建配置运行时配置

使用场景

ARG 适用于:

  • 构建时配置(版本号、构建日期)
  • 构建阶段特定的设置
  • 不需要在运行时使用的值

ENV 适用于:

  • 运行时配置(环境变量、路径)
  • 应用配置(数据库连接、API 密钥)
  • 需要在容器运行时使用的值

参数传递

传递 ARG

# 传递单个参数
docker build --build-arg VERSION=1.0.0 -t myapp:latest .
 
# 传递多个参数
docker build \
  --build-arg VERSION=1.0.0 \
  --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
  -t myapp:latest .
 
# 从环境变量传递
export VERSION=1.0.0
docker build --build-arg VERSION=$VERSION -t myapp:latest .

传递 ENV

# ENV 在 Dockerfile 中定义,运行时可以覆盖
docker run -e NODE_ENV=development myapp:latest
 
# 从文件读取环境变量
docker run --env-file .env myapp:latest

ARG 转 ENV

# 将构建参数转换为环境变量
ARG VERSION
ENV APP_VERSION=$VERSION
 
# 这样可以在运行时使用
# docker run -e APP_VERSION=1.0.0 myapp:latest

默认值设置

ARG 默认值

# 设置默认值
ARG VERSION=latest
ARG NODE_ENV=production
ARG BUILD_DATE
 
# 使用默认值或传递新值
# docker build -t myapp:latest .  # 使用默认值
# docker build --build-arg VERSION=1.0.0 -t myapp:latest .  # 覆盖默认值

ENV 默认值

# 设置默认值
ENV NODE_ENV=production
ENV PORT=3000
 
# 运行时可以覆盖
# docker run -e NODE_ENV=development myapp:latest

最佳实践

1. 合理使用 ARG 和 ENV

# ARG:构建时配置
ARG VERSION=latest
ARG BUILD_DATE
 
# ENV:运行时配置
ENV NODE_ENV=production
ENV PORT=3000

2. 使用 ARG 传递构建信息

ARG VERSION
ARG BUILD_DATE
ARG GIT_COMMIT
 
LABEL version=$VERSION
LABEL build-date=$BUILD_DATE
LABEL git-commit=$GIT_COMMIT

3. 使用 ENV 设置应用配置

ENV NODE_ENV=production
ENV DATABASE_URL=postgres://localhost/mydb
ENV REDIS_URL=redis://localhost:6379

4. 多阶段构建中的 ARG

# 在需要的阶段定义 ARG
FROM node:16 AS builder
ARG NODE_ENV=production
# ... 构建步骤
 
FROM nginx:alpine
# 如果需要,重新定义 ARG
ARG VERSION
ENV APP_VERSION=$VERSION

5. 安全性考虑

# 不要在 Dockerfile 中硬编码敏感信息
# 使用 ARG 或运行时环境变量
ARG DB_PASSWORD
ENV DATABASE_PASSWORD=$DB_PASSWORD
 
# 或使用 secrets(Docker BuildKit)
# RUN --mount=type=secret,id=db_password \
#   echo $DB_PASSWORD > /app/.env

实用示例

示例 1:版本化构建

ARG VERSION=latest
FROM node:16
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
LABEL version=$VERSION

构建:

docker build --build-arg VERSION=1.0.0 -t myapp:1.0.0 .

示例 2:环境特定构建

ARG BUILD_ENV=production
FROM node:16
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build:$BUILD_ENV
ENV NODE_ENV=$BUILD_ENV

构建:

docker build --build-arg BUILD_ENV=development -t myapp:dev .
docker build --build-arg BUILD_ENV=production -t myapp:prod .

示例 3:动态配置

ARG API_URL
ENV API_URL=$API_URL
 
ARG DATABASE_URL
ENV DATABASE_URL=$DATABASE_URL

构建:

docker build \
  --build-arg API_URL=https://api.example.com \
  --build-arg DATABASE_URL=postgres://db:5432/mydb \
  -t myapp:latest .

📚 参考资源


相关笔记