为什么选择 Docker?
Docker 提供了轻量级、可移植的容器化方案,解决了"在我机器上能跑"的问题。本文分享我在生产环境中使用 Docker 的最佳实践。
Dockerfile 优化
1. 多阶段构建
使用多阶段构建可以显著减小镜像体积:
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 运行阶段
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/main.js"]2. 合理使用缓存
将不常变化的层放在前面:
# 好的做法
COPY package*.json ./
RUN npm ci
COPY . .
# 不好的做法
COPY . .
RUN npm ci3. 使用 .dockerignore
node_modules
.git
*.md
.env*安全加固
1. 非 root 用户运行
FROM node:18-alpine
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs2. 只读文件系统
services:
app:
image: myapp:latest
read_only: true
tmpfs:
- /tmp3. 限制资源
services:
app:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M网络配置
使用自定义网络
networks:
app-network:
driver: bridge
services:
app:
networks:
- app-network
db:
networks:
- app-network健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1日志管理
services:
app:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"生产环境部署
Docker Compose
version: '3.8'
services:
app:
image: myapp:latest
restart: always
environment:
- NODE_ENV=production
depends_on:
- db
- redis
db:
image: postgres:15-alpine
restart: always
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
restart: always
volumes:
pgdata:监控与调试
常用命令
# 查看日志
docker logs -f container_name
# 进入容器
docker exec -it container_name sh
# 查看资源使用
docker stats
# 清理无用资源
docker system prune -a总结
Docker 部署的最佳实践包括:
记住,Docker 不是银弹,需要配合其他工具(如 K8s、监控、CI/CD)才能发挥最大价值。