Docker容器化Skill docker-containerization

本技能提供构建生产就绪 Docker 容器的最佳实践,涵盖安全性、性能和可维护性。适用于容器化应用程序、创建 Dockerfile、优化容器镜像、设置开发环境、构建 CI/CD 容器管道以及实施微服务。

Docker/K8s 0 次安装 0 次浏览 更新于 3/3/2026

Docker 容器化

概览

构建遵循安全、性能和可维护性最佳实践的生产就绪 Docker 容器。

何时使用

  • 部署时容器化应用程序
  • 为新服务创建 Dockerfile
  • 优化现有容器镜像
  • 设置开发环境
  • 构建 CI/CD 容器管道
  • 实施微服务

指令

1. 多阶段构建

# 多阶段构建 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
WORKDIR /app
# 仅复制生产依赖项和构建文件
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY package*.json ./

# 安全:以非根用户运行
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
USER nodejs

EXPOSE 3000
CMD ["node", "dist/index.js"]

2. 优化技术

层缓存

# ❌ 缓存不佳 - 源代码更改使依赖安装无效
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt

# ✅ 好的缓存 - 依赖项分别缓存
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

最小化镜像大小

# ❌ 大镜像 (~800MB)
FROM ubuntu:latest
RUN apt-get update && apt-get install -y python3 python3-pip

# ✅ 最小镜像 (~50MB)
FROM python:3.11-alpine

3. 安全最佳实践

FROM node:18-alpine

# 更新包以获取安全补丁
RUN apk update && apk upgrade

# 不要以 root 用户运行
RUN addgroup -g 1001 appgroup && adduser -S -u 1001 -G appgroup appuser
USER appuser

# 使用特定版本,而不是 'latest'
WORKDIR /app

# 扫描漏洞
# 运行:docker scan your-image:tag

4. 环境配置

# 使用构建参数以增加灵活性
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \
  CMD node healthcheck.js || exit 1

# 元数据标签
LABEL maintainer="team@example.com" \
      version="1.0.0" \
      description="生产 API 服务"

5. Docker Compose 用于多容器

# docker-compose.yml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        NODE_ENV: production
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    networks:
      - app-network
    volumes:
      - ./uploads:/app/uploads
    restart: unless-stopped

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_PASSWORD: password
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - app-network

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  postgres-data:
  redis-data:

6. .dockerignore 文件

# .dockerignore
node_modules
npm-debug.log
dist
.git
.env
.env.local
*.md
!README.md
.DS_Store
coverage
.vscode
.idea
__pycache__
*.pyc
.pytest_cache

最佳实践

✅ 执行

  • 使用官方基础镜像
  • 实施多阶段构建
  • 以非 root 用户运行
  • 使用 .dockerignore
  • 固定特定版本
  • 包括健康检查
  • 扫描漏洞
  • 最小化层数
  • 有效使用构建缓存

❌ 不要执行

  • 在生产中使用 ‘latest’ 标签
  • 以 root 用户运行
  • 在镜像中包含机密
  • 创建不必要的层
  • 安装不必要的包
  • 忽略安全更新
  • 在容器中存储数据

按语言示例

Python (Django/Flask)

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd -m appuser && chown -R appuser:appuser /app
USER appuser
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

Java (Spring Boot)

FROM eclipse-temurin:17-jdk-alpine AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN ./mvnw package -DskipTests

FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
RUN addgroup -S spring && adduser -S spring -G spring
USER spring
ENTRYPOINT ["java", "-jar", "app.jar"]

Go

FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]

有用命令

# 构建镜像
docker build -t myapp:1.0.0 .

# 禁用缓存构建
docker build --no-cache -t myapp:1.0.0 .

# 运行容器
docker run -d -p 3000:3000 --name myapp myapp:1.0.0

# 查看日志
docker logs -f myapp

# 在容器中执行命令
docker exec -it myapp sh

# 检查镜像层
docker history myapp:1.0.0

# 检查镜像大小
docker images myapp

# 清理
docker system prune -a

故障排除

容器立即退出:

docker logs container-name
docker inspect container-name

构建失败:

docker build --progress=plain -t myapp .

权限问题: 确保正确设置用户和卷权限。

大镜像大小:

  • 使用 alpine 基础镜像
  • 实施多阶段构建
  • 移除不必要的文件
  • 使用 .dockerignore