Dockerfile 最佳实践
基础选择
选择合适的基础镜像
# 推荐:使用官方精简镜像
FROM node:20-alpine
# 不推荐:使用完整镜像增大攻击面
FROM node:20
原则: 选择体积小、安全性高的基础镜像。Alpine 版镜像通常比标准版小 5-10 倍。
多阶段构建
多阶段构建是减小镜像体积最有效的手段。
Go 应用示例
# 构建阶段
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 --no-cache add ca-certificates
WORKDIR /app
COPY --from=builder /app/server .
USER 1000:1000
EXPOSE 8080
CMD ["./server"]
前端应用示例
# 构建阶段
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Nginx 运行阶段
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
利用构建缓存
Docker 会逐层检查缓存。将变化频率低的指令放在前面。
# 好:先复制依赖文件,后复制源码
COPY package*.json ./
RUN npm ci # 只有 package.json 变化时才重跑
COPY . . # 源码频繁变化,放在后面
# 不好:先复制全部源码
COPY . .
RUN npm ci # 任何文件变化都导致重新安装依赖
安全最佳实践
避免以 root 运行
# 创建非 root 用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
最小化安装
# 只安装运行时需要的包
RUN apt-get update && apt-get install -y \
curl \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
使用 --chmod 和 COPY
# 明确文件权限
COPY --chmod=444 config.json /app/config.json
COPY --chmod=755 entrypoint.sh /app/entrypoint.sh
标签与元数据
# 使用 LABEL 记录镜像元信息
LABEL maintainer="team@example.com"
LABEL version="1.2.3"
LABEL description="生产环境 API 服务"
# 使用 ARG 实现构建时参数
ARG BUILD_DATE
ARG VCS_REF
LABEL org.opencontainers.image.created=$BUILD_DATE
LABEL org.opencontainers.image.revision=$VCS_REF
检查清单
- 使用官方基础镜像并锁定版本 tag
- 使用多阶段构建分离构建和运行环境
- 构建产物不以 root 用户运行
- 最小化安装,清理包管理器缓存
- 利用构建缓存优化构建速度
- 设置 HEALTHCHECK 指令
- 使用 .dockerignore 排除无关文件
- 合理设置环境变量默认值