HESTUDY® HIRE ME ↗
开发者工具

Docker 容器化最佳实践

学习如何用 Docker 容器化应用,包括 Dockerfile 编写、多阶段构建和性能优化

Docker 是什么?

Docker 是一个开源容器化平台,可以把应用和依赖打包进轻量、可移植的容器里。

它解决的核心问题是:开发环境、测试环境和生产环境不一致时,应用行为很容易变得不可预测。

基础概念

Image

镜像是容器的模板,包含运行应用需要的文件、依赖和配置。

Container

容器是镜像的运行实例,提供隔离且轻量的运行环境。

Dockerfile

Dockerfile 是用来构建镜像的文本文件,也是容器化流程里最常被维护的部分。

编写高效 Dockerfile

基础结构

# Use official base image
FROM node:18-alpine

# Set working directory
WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy application code
COPY . .

# Expose port
EXPOSE 3000

# Start command
CMD ["node", "server.js"]

最佳实践

1. 使用多阶段构建

把构建环境和运行环境分开,可以显著减小最终镜像体积。

# Build stage
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Runtime stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm ci --only=production
CMD ["node", "dist/server.js"]

2. 优化层缓存

把不常变化的指令放在前面,可以更好利用 Docker 的层缓存。

# Good practice: Copy dependency files first
COPY package*.json ./
RUN npm ci

# Then copy application code (changes frequently)
COPY . .

3. 使用 .dockerignore

通过 .dockerignore 排除不需要进入镜像上下文的文件:

node_modules
npm-debug.log
.git
.env
*.md
.vscode

4. 减小镜像体积

  • 优先使用 Alpine 这类轻量基础镜像
  • 清理不必要的缓存和临时文件
  • 合并相关 RUN 指令
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/*

Docker Compose

多容器应用可以用 Docker Compose 管理服务编排、环境变量和依赖关系。

docker-compose.yml 示例

version: "3.8"

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://db:5432/myapp
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: postgres:15-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=myapp
    restart: unless-stopped

volumes:
  pgdata:

常用命令

# Start all services
docker-compose up -d

# View logs
docker-compose logs -f

# Stop services
docker-compose down

# Rebuild
docker-compose build

安全最佳实践

1. 不要使用 root 用户

RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

USER nodejs

2. 扫描漏洞

# Use Trivy to scan images
docker run aquasec/trivy image myapp:latest

3. 用 Secrets 管理敏感信息

不要把密码、Token 或密钥硬编码在 Dockerfile 里。

性能优化

1. 资源限制

services:
  web:
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
        reservations:
          memory: 256M

2. 健康检查

HEALTHCHECK --interval=30s --timeout=3s \
  CMD node healthcheck.js || exit 1

3. 日志管理

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

CI/CD

下面是一个 GitHub Actions 构建和推送镜像的例子:

name: Build and Push Docker Image

on:
  push:
    branches: [main]

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

      - name: Build Docker image
        run: docker build -t myapp:latest .

      - name: Push to Registry
        run: |
          docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASS }}
          docker push myapp:latest

常见问题排查

容器无法启动

# View container logs
docker logs <container-id>

# Enter container for debugging
docker exec -it <container-id> sh

网络问题

# Check network configuration
docker network ls
docker network inspect bridge

存储空间不足

# Clean up unused resources
docker system prune -a

# Check disk usage
docker system df

总结

Docker 提供了一种稳定、可复现的应用交付方式。写好 Dockerfile、控制镜像体积、避免 root 用户、做好日志和健康检查,是容器化实践里最容易带来收益的部分。

参考资料