目录

Dockerfile 最佳实践

一个写得好的 Dockerfile 能显著减小镜像体积、加快构建速度、提升安全性。本文总结日常工作中最实用的 Dockerfile 编写规范。

1. 使用多阶段构建 (Multi-stage Build)

将编译环境和运行环境分离,最终镜像只包含运行所需的产物:

# 编译阶段
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 server .

# 运行阶段
FROM alpine:3.19
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/server /usr/local/bin/
EXPOSE 8080
ENTRYPOINT ["server"]

效果:Go 编译镜像 ~1GB → 最终镜像 ~20MB。


2. 选择合适的基础镜像

场景 推荐镜像 大小
通用 alpine:3.19 ~7MB
静态二进制 scratch / gcr.io/distroless/static 0~2MB
Debian 需求 debian:bookworm-slim ~80MB
Python python:3.12-slim ~150MB

避免使用 latest 标签,始终锁定具体版本以保证构建可复现。


3. 合理利用构建缓存

Docker 按层缓存,变化频率低的指令放前面

FROM node:20-alpine
WORKDIR /app

# 先复制依赖文件(变化少)
COPY package.json package-lock.json ./
RUN npm ci --production

# 再复制源码(变化频繁)
COPY . .
RUN npm run build

如果先 COPY . .npm install,每次代码改动都会重新安装依赖。


4. 减少镜像层数和体积

# ❌ 多个 RUN 产生多层
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*

# ✅ 合并为一层,并清理缓存
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/*

关键点:

  • --no-install-recommends 避免安装不必要的包
  • 同一层内清理缓存,否则删除操作不会减小镜像体积

5. 不要以 root 运行

RUN addgroup -S app && adduser -S app -G app
USER app

以非 root 用户运行容器,降低容器逃逸后的攻击面。


6. 使用 .dockerignore

在项目根目录创建 .dockerignore,避免将无关文件发送到构建上下文:

.git
node_modules
*.md
.env
.DS_Store
dist
coverage

构建上下文越小,docker build 启动越快。


7. COPY vs ADD

# ✅ 优先使用 COPY(行为明确)
COPY app.tar.gz /app/

# ⚠️ ADD 会自动解压 tar 并支持 URL,行为隐式
ADD app.tar.gz /app/

只在需要自动解压 tar 时使用 ADD,其他场景一律用 COPY


8. ENTRYPOINT vs CMD

# ENTRYPOINT 定义容器的主进程
# CMD 提供默认参数,可被 docker run 覆盖
ENTRYPOINT ["python", "app.py"]
CMD ["--port", "8080"]
# 使用默认参数
docker run myapp
# 等价于: python app.py --port 8080

# 覆盖参数
docker run myapp --port 9090
# 等价于: python app.py --port 9090

始终使用 exec 格式 ["executable", "param"],避免 shell 格式导致信号无法正确传递。


9. 健康检查

HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD wget -qO- http://localhost:8080/health || exit 1

配合编排工具(Docker Compose / Kubernetes)实现自动重启不健康的容器。


10. 安全扫描

构建完成后扫描镜像漏洞:

# Trivy
trivy image myapp:latest

# Docker Scout
docker scout cves myapp:latest

建议集成到 CI/CD Pipeline 中,阻断含高危漏洞的镜像发布。