Docker 容器化部署最佳实践

一、引言

随着云原生技术的普及,Docker 已成为现代应用部署的标准工具。本文总结了一套完整的 Docker 容器化部署最佳实践,帮助运维团队构建高效、安全、可维护的容器化环境。

二、Dockerfile 编写规范

2.1 选择合适的基础镜像

1
2
3
4
5
# 推荐:使用精简版基础镜像
FROM node:18-alpine

# 不推荐:使用完整版镜像(体积过大)
FROM node:18

最佳实践:

  • 优先选择 alpine 版本,镜像体积可减少 70%+
  • 根据应用需求选择特定版本,避免使用 latest 标签
  • 对于生产环境,考虑使用 distrolessscratch 基础镜像

2.2 优化镜像层缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 推荐:将变化少的指令放在前面
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
CMD ["node", "dist/server.js"]

# 不推荐:每次代码变更都重新安装依赖
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "server.js"]

2.3 减少镜像层数

1
2
3
4
5
6
7
8
9
10
11
# 推荐:合并 RUN 指令
RUN apt-get update && \
apt-get install -y --no-install-recommends \
curl \
gnupg \
&& rm -rf /var/lib/apt/lists/*

# 不推荐:产生多个镜像层
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y gnupg

三、容器安全配置

3.1 非 root 用户运行

1
2
3
4
5
6
7
8
9
10
11
FROM node:18-alpine

# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001

WORKDIR /app
COPY --chown=nodejs:nodejs . .

USER nodejs
CMD ["node", "server.js"]

3.2 限制容器能力

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# docker-compose.yml
version: '3.8'
services:
app:
image: myapp:latest
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
read_only: true
tmpfs:
- /tmp

3.3 镜像漏洞扫描

1
2
3
4
5
# 使用 Trivy 扫描镜像漏洞
trivy image myapp:latest

# 使用 Docker Scout(Docker 官方工具)
docker scout cves myapp:latest

四、生产环境部署策略

4.1 健康检查配置

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

4.2 资源限制

1
2
3
4
5
6
7
8
9
10
11
12
# docker-compose.yml
services:
app:
image: myapp:latest
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M

4.3 日志管理

1
2
3
4
5
6
7
8
9
# docker-compose.yml
services:
app:
image: myapp:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

五、CI/CD 集成

5.1 GitHub Actions 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# .github/workflows/docker-build.yml
name: Docker Build and Push

on:
push:
branches: [main]
tags: ['v*']

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Registry
uses: docker/login-action@v3
with:
registry: ${{ secrets.REGISTRY_URL }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}

- name: Build and Push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ secrets.REGISTRY_URL }}/myapp:${{ github.sha }}
${{ secrets.REGISTRY_URL }}/myapp:latest
cache-from: type=registry,ref=${{ secrets.REGISTRY_URL }}/myapp:buildcache
cache-to: type=registry,ref=${{ secrets.REGISTRY_URL }}/myapp:buildcache,mode=max

5.2 多阶段构建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# 生产阶段
FROM node:18-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./

USER nodejs
CMD ["node", "dist/server.js"]

六、常见问题排查

6.1 容器无法启动

1
2
3
4
5
6
7
8
# 查看容器日志
docker logs <container_id>

# 进入容器调试
docker exec -it <container_id> /bin/sh

# 检查容器状态
docker inspect <container_id>

6.2 镜像构建失败

1
2
3
4
5
# 清理构建缓存
docker builder prune -a

# 重新构建(不使用缓存)
docker build --no-cache -t myapp:latest .

6.3 网络问题

1
2
3
4
5
6
# 查看网络配置
docker network ls
docker network inspect bridge

# 测试容器间连通性
docker exec <container_id> ping <other_container>

七、总结

Docker 容器化部署的最佳实践包括:

  1. 编写规范的 Dockerfile:选择合适基础镜像、优化缓存、减少层数
  2. 强化安全配置:非 root 运行、限制能力、漏洞扫描
  3. 生产环境优化:健康检查、资源限制、日志管理
  4. CI/CD 集成:自动化构建、多阶段构建、缓存优化

遵循这些实践可以显著提升容器化应用的可靠性、安全性和可维护性。

参考资源