Docker 镜像构建
本章将介绍如何使用 Dockerfile 构建自定义 Docker 镜像,包括构建流程、多阶段构建和优化技巧。
镜像构建基础
docker build 命令
bash
# 基本构建
docker build -t myapp:v1.0 .
# 指定 Dockerfile 路径
docker build -t myapp:v1.0 -f Dockerfile.prod .
# 不使用缓存构建
docker build --no-cache -t myapp:v1.0 .
# 构建时传递参数
docker build --build-arg VERSION=1.0 -t myapp:v1.0 .构建上下文
. 表示构建上下文目录,Docker 会将该目录下的所有文件发送给 Docker Daemon。
使用 .dockerignore 排除不需要的文件:
# .dockerignore
node_modules
.git
*.md
.env
dist构建实例
Node.js 应用
dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]Python 应用
dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "app.py"]Go 应用
dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o main .
FROM alpine:3.19
COPY --from=builder /app/main /main
EXPOSE 8080
CMD ["/main"]Java 应用
dockerfile
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests
FROM eclipse-temurin:21-jre-alpine
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]多阶段构建
多阶段构建可以显著减小最终镜像体积,将构建环境和运行环境分离:
dockerfile
# 阶段一:构建
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 阶段二:运行
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]对比效果:
| 构建方式 | 镜像大小 |
|---|---|
| 单阶段(包含 Node.js) | ~1.2 GB |
| 多阶段(仅 Nginx + 静态文件) | ~30 MB |
镜像优化技巧
1. 选择合适的基础镜像
dockerfile
# ❌ 完整镜像(约 900MB)
FROM node:20
# ✅ Alpine 版本(约 130MB)
FROM node:20-alpine
# ✅ Slim 版本(约 200MB)
FROM node:20-slim2. 合并 RUN 指令减少层数
dockerfile
# ❌ 多个 RUN 指令,产生多个层
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean
# ✅ 合并为一个 RUN 指令
RUN apt-get update && \
apt-get install -y curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*3. 利用构建缓存
将变化频率低的指令放在前面:
dockerfile
FROM node:20-alpine
WORKDIR /app
# 先复制依赖文件(变化少)
COPY package*.json ./
RUN npm ci
# 再复制源代码(变化多)
COPY . .
RUN npm run build4. 使用非 root 用户
dockerfile
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm ci
# 创建非 root 用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
CMD ["node", "server.js"]构建缓存管理
bash
# 查看构建缓存
docker builder prune --all
# 清理构建缓存
docker builder prune
# 使用 BuildKit 构建(更高效的缓存)
DOCKER_BUILDKIT=1 docker build -t myapp .镜像标签管理
bash
# 构建时打标签
docker build -t myapp:v1.0 -t myapp:latest .
# 给已有镜像打标签
docker tag myapp:v1.0 myregistry.com/myapp:v1.0
# 推送到仓库
docker push myregistry.com/myapp:v1.0本章小结
镜像构建是 Docker 的核心技能之一。通过合理编写 Dockerfile、使用多阶段构建和优化技巧,可以构建出体积小、安全性高、构建速度快的镜像。
关键要点:
- 使用
.dockerignore排除不必要的文件 - 多阶段构建分离构建环境和运行环境
- 选择 Alpine 或 Slim 基础镜像减小体积
- 合理利用构建缓存加速构建
- 使用非 root 用户提升安全性