
关于
部署工作流、CI/CD 管道模式、Docker 容器化、健康检查、回滚策略和 Web 应用的生产就绪检查清单。
name: deployment-patterns description: 部署工作流、CI/CD 流水线模式、Docker 容器化、健康检查、回滚策略以及 Web 应用的生产就绪检查清单。 origin: ECC
部署模式
生产部署工作流与 CI/CD 最佳实践。
何时激活
- 搭建 CI/CD 流水线
- 将应用容器化(Docker)
- 规划部署策略(蓝绿部署、金丝雀部署、滚动部署)
- 实现健康检查和就绪探针
- 准备生产发布
- 配置环境特定设置
部署策略
滚动部署(默认)
逐步替换实例——新旧版本在发布期间同时运行。
Instance 1: v1 → v2 (首先更新)
Instance 2: v1 (仍在运行 v1)
Instance 3: v1 (仍在运行 v1)
Instance 1: v2
Instance 2: v1 → v2 (其次更新)
Instance 3: v1
Instance 1: v2
Instance 2: v2
Instance 3: v1 → v2 (最后更新)
优点: 零停机时间,渐进式发布 缺点: 两个版本同时运行——需要向后兼容的变更 适用场景: 标准部署、向后兼容的变更
蓝绿部署
运行两个相同的环境,原子性地切换流量。
Blue (v1) ← traffic
Green (v2) idle, running new version
# 验证通过后:
Blue (v1) idle (becomes standby)
Green (v2) ← traffic
优点: 即时回滚(切回蓝色环境),干净的切换 缺点: 部署期间需要 2 倍基础设施 适用场景: 关键服务、零容忍故障的场景
金丝雀部署
先将少量流量路由到新版本。
v1: 95% of traffic
v2: 5% of traffic (canary)
# 如果指标正常:
v1: 50% of traffic
v2: 50% of traffic
# 最终:
v2: 100% of traffic
优点: 在全量发布前用真实流量发现问题 缺点: 需要流量分割基础设施和监控 适用场景: 高流量服务、高风险变更、功能开关
Docker
多阶段 Dockerfile(Node.js)
# Stage 1: Install dependencies
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --production=false
# Stage 2: Build
FROM node:22-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
RUN npm prune --production
# Stage 3: Production image
FROM node:22-alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001
USER appuser
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/package.json ./
ENV NODE_ENV=production
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]
多阶段 Dockerfile(Go)
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /server ./cmd/server
FROM alpine:3.19 AS runner
RUN apk --no-cache add ca-certificates
RUN adduser -D -u 1001 appuser
USER appuser
COPY --from=builder /server /server
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:8080/health || exit 1
CMD ["/server"]
多阶段 Dockerfile(Python/Django)
FROM python:3.12-slim AS builder
WORKDIR /app
RUN pip install --no-cache-dir uv
COPY requirements.txt .
RUN uv pip install --system --no-cache -r requirements.txt
FROM python:3.12-slim AS runner
WORKDIR /app
RUN useradd -r -u 1001 appuser
USER appuser
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin
COPY . .
ENV PYTHONUNBUFFERED=1
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=3s CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health/')" || exit 1
CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]
Docker 最佳实践
# 好的做法
- 使用特定版本标签(node:22-alpine,而非 node:latest)
- 多阶段构建以最小化镜像大小
- 以非 root 用户运行
- 先复制依赖文件(利用层缓存)
- 使用 .dockerignore 排除 node_modules、.git、tests
- 添加 HEALTHCHECK 指令
- 在 docker-compose 或 k8s 中设置资源限制
# 不好的做法
- 以 root 身份运行
- 使用 :latest 标签
- 在一个 COPY 层中复制整个仓库
- 在生产镜像中安装开发依赖
- 在镜像中存储密钥(应使用环境变量或密钥管理器)
CI/CD 流水线
GitHub Actions(标准流水线)
name: CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm test
- run: npm run build
deploy:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy
run: ./scripts/deploy.sh
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
健康检查
Express.js 健康检查端点
app.get('/health', async (req, res) => {
const checks = {
uptime: process.uptime(),
timestamp: Date.now(),
database: 'unknown',
redis: 'unknown',
};
try {
await db.query('SELECT 1');
checks.database = 'healthy';
} catch (e) {
checks.database = 'unhealthy';
}
try {
await redis.ping();
checks.redis = 'healthy';
} catch (e) {
checks.redis = 'unhealthy';
}
const isHealthy = checks.database === 'healthy';
res.status(isHealthy ? 200 : 503).json(checks);
});
回滚策略
即时回滚检查清单
- 检测:监控告警触发
- 确认:验证问题与部署相关
- 回滚:恢复到上一个已知正常版本
- 验证:确认服务恢复
- 事后分析:记录发生了什么以及原因
回滚命令
# Docker/Kubernetes
kubectl rollout undo deployment/app-name
# 带版本号的回滚
kubectl rollout undo deployment/app-name --to-revision=3
# Docker Compose
docker compose up -d --force-recreate app
# PM2
pm2 deploy production revert 1
生产就绪检查清单
- [ ] 健康检查端点已实现
- [ ] 日志结构化(JSON 格式)
- [ ] 错误追踪已配置(Sentry 等)
- [ ] 环境变量已外部化
- [ ] 密钥存储在密钥管理器中
- [ ] 数据库迁移已自动化
- [ ] 备份策略已就位
- [ ] 监控和告警已配置
- [ ] 已设置速率限制
- [ ] CORS 已正确配置
- [ ] SSL/TLS 已启用
- [ ] 已设置资源限制(CPU/内存)
限制
- 仅在任务明确匹配上述范围时使用此技能。
- 不要将输出视为环境特定验证、测试或专家审查的替代品。
- 如果缺少必要的输入、权限、安全边界或成功标准,请停下来寻求澄清。
兼容工具
Claude CodeCursor
标签
运维部署

