← 返回首页
🔧

Dockerfile编写:最佳实践

📂 devops ⏱ 3 min 401 words

Dockerfile编写:最佳实践

Dockerfile指令详解

FROM指令

# 指定基础镜像
FROM ubuntu:22.04

# 使用构建参数
ARG BASE_IMAGE=ubuntu:22.04
FROM ${BASE_IMAGE}

# 多平台构建
FROM --platform=linux/amd64 ubuntu:22.04

RUN指令

# 使用shell格式
RUN apt-get update && apt-get install -y curl

# 使用exec格式(推荐)
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "curl"]

# 合并RUN减少层数
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        curl \
        git \
        vim && \
    rm -rf /var/lib/apt/lists/*

COPY与ADD

# COPY(推荐)
COPY package.json /app/
COPY --chown=node:node . /app/

# ADD(自动解压tar,慎用)
ADD app.tar.gz /app/

# 从URL复制
ADD https://example.com/file.tar.gz /tmp/

CMD与ENTRYPOINT

# CMD:容器启动时的默认命令(可被覆盖)
CMD ["python3", "app.py"]
CMD python3 app.py

# ENTRYPOINT:容器启动时的入口(不易被覆盖)
ENTRYPOINT ["python3"]
CMD ["app.py"]

# exec格式(推荐)
ENTRYPOINT ["python3"]
CMD ["app.py"]

多阶段构建

Go应用示例

# 构建阶段
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server .

# 运行阶段
FROM alpine:latest
RUN apk --no-cache add ca-certificates tzdata
WORKDIR /app
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]

Node.js应用示例

# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# 运行阶段
FROM node:18-alpine
RUN addgroup -g 1001 -S appgroup && \
    adduser -S appuser -u 1001 -G appgroup
WORKDIR /app
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:appgroup /app/package.json .
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]

安全最佳实践

使用非root用户

# 创建专用用户
RUN groupadd -r appgroup && useradd -r -g appgroup appuser

# 切换用户
USER appuser

# 或者在COPY时设置所有权
COPY --chown=appuser:appgroup . /app

扫描和最小化

# 使用最小基础镜像
FROM alpine:3.18

# 只安装必要的包
RUN apk --no-cache add \
    ca-certificates \
    curl \
    && rm -rf /var/cache/apk/*

# 不安装文档和缓存
RUN apt-get install -y --no-install-recommends \
    --no-install-suggests \
    package-name

使用.dockerignore

# .dockerignore文件
.git
.gitignore
.dockerignore
Dockerfile
docker-compose*.yml
README.md
.env
.env.*
node_modules
__pycache__
*.pyc
*.pyo
.vscode
.idea

构建缓存优化

缓存层顺序

# 依赖层(变化少,放前面)
COPY package.json package-lock.json ./
RUN npm ci --only=production

# 源代码层(变化多,放后面)
COPY . .

使用BuildKit

# 启用BuildKit
export DOCKER_BUILDKIT=1

# 构建时指定缓存
docker build --cache-from myapp:latest -t myapp:new .

# 并行构建
docker buildx build --parallel .

高级技巧

使用ARG和ENV

# ARG:构建时变量
ARG NODE_VERSION=18
FROM node:${NODE_VERSION}-alpine

# ENV:运行时变量
ENV NODE_ENV=production
ENV APP_PORT=3000

# 使用多阶段ARG
ARG VERSION=latest
FROM node:${VERSION}-alpine AS builder
# ...构建过程...
FROM node:${VERSION}-alpine
# ...运行配置...

使用HEALTHCHECK

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

使用LABEL

LABEL maintainer="devops@example.com"
LABEL version="1.0"
LABEL description="Production web application"
LABEL org.opencontainers.image.source="https://github.com/example/app"

多平台构建

# 创建构建器实例
docker buildx create --name mybuilder --use

# 构建多平台镜像
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t myapp:latest \
  --push \
  .

镜像大小对比

基础镜像 大小 适用场景
scratch 0MB 静态二进制
alpine ~5MB 通用
debian:slim ~80MB 需要glibc
ubuntu:22.04 ~77MB 开发环境

总结

编写高质量的Dockerfile需要遵循最佳实践:使用多阶段构建、最小化镜像体积、确保安全性、优化构建缓存。这些技巧将帮助你构建出高效、安全的生产级容器镜像。