Docker 已经成为现代软件部署的事实标准。它能消除"在我机器上能跑"的问题, 让开发、测试、生产环境保持一致。本文将从 Dockerfile 编写到多服务编排,提供完整的实践指南。
Dockerfile 最佳实践
多阶段构建(Multi-stage Build)
# ===== 构建阶段 =====
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /app/server .
# ===== 运行阶段 =====
FROM alpine:3.19
RUN apk add --no-cache ca-certificates tzdata
ENV TZ=Asia/Shanghai
# 创建非 root 用户
RUN adduser -D -g '' appuser
COPY --from=builder /app/server /app/server
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http://localhost:8080/health || exit 1
ENTRYPOINT ["/app/server"]
Python 项目 Dockerfile
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt
FROM python:3.12-slim
RUN useradd --create-home appuser
COPY --from=builder /root/.local /home/appuser/.local
WORKDIR /app
COPY --chown=appuser:appuser . .
USER appuser
ENV PATH=/home/appuser/.local/bin:$PATH
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
优化要点:使用轻量基础镜像(alpine/slim),合并 RUN 指令减少层数,
利用构建缓存(先 COPY 依赖文件再 COPY 源码),非 root 用户运行。
docker-compose 多服务编排
# docker-compose.yml
version: "3.9"
services:
app:
build: .
ports:
- "8000:8000"
environment:
- DB_HOST=db
- REDIS_HOST=redis
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
volumes:
- ./uploads:/app/uploads
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: myapp
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U myapp"]
interval: 5s
timeout: 3s
retries: 5
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redisdata:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 2s
retries: 5
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- app
volumes:
pgdata:
redisdata:
镜像优化策略
| 策略 | 效果 | 示例 |
|---|---|---|
| 选择轻量基础镜像 | 减少 60-80% 体积 | python:3.12-slim vs python:3.12 |
| 多阶段构建 | 避免构建工具入镜像 | golang:1.21 → alpine:3.19 |
| .dockerignore | 排除无关文件 | node_modules, .git, __pycache__ |
| 合并 RUN 指令 | 减少镜像层数 | RUN cmd1 && cmd2 && cmd3 |
| 清理包管理器缓存 | 减少 100-200MB | apt-get clean && rm -rf /var/lib/apt/lists/* |
常用调试命令
# 查看日志
docker logs -f --tail 100 container_name
# 进入运行中的容器
docker exec -it container_name sh
# 查看容器资源使用
docker stats
# 查看镜像层信息
docker history image_name
# 清理无用资源
docker system prune -a --volumes
# 导出/导入镜像
docker save -o app.tar myapp:latest
docker load -i app.tar
生产环境 Checklist
- 非 root 用户运行:容器内使用
USER切换到普通用户 - 配置健康检查:Docker 可以根据健康状态自动重启
- 限制资源使用:
--memory="512m" --cpus="1.0" - 日志管理:使用 json-file 驱动 + logrotate,避免日志撑满磁盘
- 密钥管理:敏感信息用 Docker Secrets 或环境变量注入,不要写到镜像中
- 版本固定:生产环境始终指定镜像的具体版本 Tag,不要用
latest
总结
Docker 的价值不仅在于容器化本身,更在于它带来的标准化部署流程。 掌握多阶段构建、合理的健康检查、安全的镜像配置,就能在生产环境中稳定运行容器化服务。 下一步可以学习 Kubernetes,将容器编排提升到集群级别。
← 返回首页