← 返回首页

Docker容器化部署最佳实践指南

前言

Docker已成为现代应用部署的标准方式。本文总结在生产环境中使用Docker的最佳实践,涵盖镜像构建、容器编排、安全加固和性能优化等方面。

一、Dockerfile最佳实践

1.1 多阶段构建

多阶段构建可以显著减小最终镜像的体积,同时保证构建环境完整:

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

# 运行阶段
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/main.js"]

1.2 利用构建缓存

合理安排Dockerfile中指令的顺序,将变化频率低的内容放在前面,充分利用Docker的层缓存机制:

  • 先复制依赖文件(package.json),安装依赖
  • 再复制源代码,构建应用
  • 这样修改代码时不需要重新安装依赖

二、容器安全加固

2.1 非root用户运行

生产环境中应避免以root身份运行容器:

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

2.2 只读文件系统

将容器根文件系统设为只读,只挂载必要的可写目录:

docker run --read-only \
  --tmpfs /tmp \
  -v /data:/app/data \
  myapp:latest

2.3 资源限制

始终为容器设置CPU和内存限制,防止单个容器耗尽宿主机资源:

docker run \
  --memory="512m" \
  --memory-swap="1g" \
  --cpus="1.0" \
  myapp:latest

三、Docker Compose编排

对于多容器应用,使用Docker Compose管理容器间的依赖关系:

version: '3.8'
services:
  api:
    build: ./api
    ports:
      - "3000:3000"
    depends_on:
      mysql:
        condition: service_healthy
    environment:
      - DB_HOST=mysql
      - DB_PORT=3306

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: myapp
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  mysql_data:

四、日志与监控

容器的标准输出(stdout/stderr)是最简单的日志收集方式。配合Docker的日志驱动,可以将日志转发到集中式日志系统:

  • json-file:默认驱动,适合开发环境
  • syslog:转发到syslog服务器
  • fluentd:对接Fluentd日志收集
  • 建议使用结构化日志(JSON格式),便于后续分析

五、总结

Docker容器化部署的关键原则:

  1. 镜像尽可能小,使用Alpine基础镜像
  2. 容器以非root用户运行
  3. 始终设置资源限制
  4. 使用健康检查确保服务可用
  5. 日志输出到stdout,外部收集
  6. 敏感信息通过环境变量或Secret注入,不写入镜像
以上实践来自实际生产环境的经验总结,建议根据具体业务场景灵活调整。