Skip to content

Docker 生产环境部署的 10 个实用技巧

Docker 很容易上手,但生产环境部署有很多细节需要注意。本文总结实际项目中踩过的坑。

1. 🏷️ 使用特定版本标签

不要用 latest,它指向的版本随时可能变化:

dockerfile
# ❌ 不推荐
FROM nginx:latest

# ✅ 推荐
FROM nginx:1.20.1-alpine

好处:

  • 版本固定,构建结果可复现
  • 遊免意外升级导致兼容问题
  • 方便问题排查和回滚

2. 📦 优化镜像大小

选择合适的基础镜像

dockerfile
# ❌ 600MB+
FROM openjdk:11

# ✅ ~200MB
FROM openjdk:11-jre-slim

# ✅ 更小,~50MB(需要 GraalVM)
FROM amazoncorretto:11-alpine

多阶段构建

dockerfile
# 构建阶段
FROM maven:3.8-openjdk-11 AS builder
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

# 运行阶段
FROM openjdk:11-jre-slim
COPY --from=builder /build/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

3. 🔒 安全最佳实践

不要以 root 运行

dockerfile
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

限制容器权限

yaml
# docker-compose.yml
services:
  app:
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE  # 只保留需要的权限

4. 📊 健康检查

让 Docker 自动监控容器状态:

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

配合 docker-compose:

yaml
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
  interval: 30s
  timeout: 3s
  retries: 3
  start_period: 10s

5. 🗂️ 合理使用 Volume

yaml
volumes:
  # 配置文件:只读挂载
  - ./config:/app/config:ro

  # 数据目录:持久化
  - data-volume:/app/data

  # 日志:宿主机直接访问
  - ./logs:/app/logs

6. 🌐 网络隔离

不同服务用不同网络:

yaml
networks:
  frontend:
  backend:

services:
  nginx:
    networks:
      - frontend
      - backend  # nginx 需要访问后端

  api:
    networks:
      - backend  # 后端不暴露到 frontend

  db:
    networks:
      - backend  # 数据库只能后端访问

7. ⚡ 资源限制

防止容器占用过多资源:

yaml
services:
  app:
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M

8. 📝 日志管理

限制日志大小

yaml
services:
  app:
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

标准输出到日志系统

yaml
logging:
  driver: fluentd
  options:
    fluentd-address: localhost:24224
    tag: app.service

9. 🔄 优雅停止

确保容器能正确处理停止信号:

dockerfile
# Spring Boot 应用
ENTRYPOINT ["java", "-jar", "app.jar"]

# 设置停止超时
STOPSIGNAL SIGTERM
yaml
# docker-compose.yml
services:
  app:
    stop_grace_period: 30s  # 给应用 30 秒优雅关闭

10. 🧪 本地与生产分离

yaml
# docker-compose.yml(本地开发)
services:
  app:
    build: .
    volumes:
      - ./src:/app/src  # 本地开发,代码热更新

# docker-compose.prod.yml(生产)
services:
  app:
    image: myregistry/app:v1.2.3  # 使用预构建镜像
    # 无 volume 挂载,代码内置

部署命令:

bash
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

📚 总结速查表

场景建议
镜像版本使用具体版本号,避免 latest
镜像大小多阶段构建 + slim/alpine 基础镜像
安全非 root 用户 + 限制 capabilities
健康检查添加 HEALTHCHECK 指令
日志设置 max-size/max-file 或对接日志系统
资源配置 limits/reservations
网络按服务隔离网络

Docker 很强大,用好这些技巧能让部署更稳定可靠。欢迎交流你的实践经验!🐳

🫐 BlueberryLab — 技术与生活记录