deployment-documentation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Deployment Documentation

部署文档

Overview

概述

Create comprehensive deployment documentation covering infrastructure setup, CI/CD pipelines, deployment procedures, and rollback strategies.
创建涵盖基础设施搭建、CI/CD流水线、部署流程以及回滚策略的全面部署文档。

When to Use

适用场景

  • Deployment guides
  • Infrastructure documentation
  • CI/CD pipeline setup
  • Configuration management
  • Container orchestration
  • Cloud infrastructure docs
  • Release procedures
  • Rollback procedures
  • 部署指南
  • 基础设施文档
  • CI/CD流水线搭建
  • 配置管理
  • 容器编排
  • 云基础设施文档
  • 发布流程
  • 回滚流程

Deployment Guide Template

部署指南模板

markdown
undefined
markdown
undefined

Deployment Guide

部署指南

Overview

概述

This document describes the deployment process for [Application Name].
Deployment Methods:
  • Manual deployment (emergency only)
  • Automated CI/CD (preferred)
  • Blue-green deployment
  • Canary deployment
Environments:

本文档描述了[应用名称]的部署流程。
部署方式:
  • 手动部署(仅用于紧急情况)
  • 自动化CI/CD(推荐方式)
  • 蓝绿部署
  • 金丝雀部署
环境:

Prerequisites

前置条件

Required Tools

所需工具

bash
undefined
bash
undefined

Install required tools

安装所需工具

brew install node@18 brew install postgresql@14 brew install redis brew install docker brew install kubectl brew install helm brew install aws-cli
undefined
brew install node@18 brew install postgresql@14 brew install redis brew install docker brew install kubectl brew install helm brew install aws-cli
undefined

Access Requirements

访问权限要求

  • GitHub repository access
  • AWS console access (IAM user with deployment policy)
  • Kubernetes cluster access (kubeconfig)
  • Docker Hub credentials
  • Datadog API key (monitoring)
  • PagerDuty access (on-call)
  • GitHub仓库访问权限
  • AWS控制台访问权限(带有部署策略的IAM用户)
  • Kubernetes集群访问权限(kubeconfig)
  • Docker Hub凭证
  • Datadog API密钥(监控)
  • PagerDuty访问权限(值班)

Environment Variables

环境变量

bash
undefined
bash
undefined

.env.production

.env.production

NODE_ENV=production DATABASE_URL=postgresql://user:pass@db.example.com:5432/prod REDIS_URL=redis://cache.example.com:6379 API_KEY=your-api-key JWT_SECRET=your-jwt-secret AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=...

---
NODE_ENV=production DATABASE_URL=postgresql://user:pass@db.example.com:5432/prod REDIS_URL=redis://cache.example.com:6379 API_KEY=your-api-key JWT_SECRET=your-jwt-secret AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=...

---

CI/CD Pipeline

CI/CD流水线

GitHub Actions Workflow

GitHub Actions工作流

yaml
undefined
yaml
undefined

.github/workflows/deploy.yml

.github/workflows/deploy.yml

name: Deploy to Production
on: push: branches: [main] workflow_dispatch:
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '18' - run: npm ci - run: npm test - run: npm run lint
build: needs: test runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
  - name: Configure AWS credentials
    uses: aws-actions/configure-aws-credentials@v2
    with:
      aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
      aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      aws-region: us-east-1

  - name: Login to Amazon ECR
    uses: aws-actions/amazon-ecr-login@v1

  - name: Build and push Docker image
    env:
      ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
      IMAGE_TAG: ${{ github.sha }}
    run: |
      docker build -t $ECR_REGISTRY/app:$IMAGE_TAG .
      docker push $ECR_REGISTRY/app:$IMAGE_TAG
      docker tag $ECR_REGISTRY/app:$IMAGE_TAG $ECR_REGISTRY/app:latest
      docker push $ECR_REGISTRY/app:latest
deploy: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
  - name: Configure kubectl
    uses: azure/k8s-set-context@v3
    with:
      method: kubeconfig
      kubeconfig: ${{ secrets.KUBECONFIG }}

  - name: Deploy to Kubernetes
    env:
      IMAGE_TAG: ${{ github.sha }}
    run: |
      kubectl set image deployment/app \
        app=your-registry/app:$IMAGE_TAG \
        -n production

      kubectl rollout status deployment/app -n production

  - name: Notify Datadog
    run: |
      curl -X POST "https://api.datadoghq.com/api/v1/events" \
        -H "DD-API-KEY: ${{ secrets.DATADOG_API_KEY }}" \
        -d '{
          "title": "Deployment to Production",
          "text": "Deployed version ${{ github.sha }}",
          "tags": ["environment:production", "service:app"]
        }'

  - name: Notify Slack
    if: always()
    uses: slackapi/slack-github-action@v1
    with:
      payload: |
        {
          "text": "Deployment ${{ job.status }}: ${{ github.sha }}"
        }
    env:
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

---
name: Deploy to Production
on: push: branches: [main] workflow_dispatch:
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '18' - run: npm ci - run: npm test - run: npm run lint
build: needs: test runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
  - name: Configure AWS credentials
    uses: aws-actions/configure-aws-credentials@v2
    with:
      aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
      aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      aws-region: us-east-1

  - name: Login to Amazon ECR
    uses: aws-actions/amazon-ecr-login@v1

  - name: Build and push Docker image
    env:
      ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
      IMAGE_TAG: ${{ github.sha }}
    run: |
      docker build -t $ECR_REGISTRY/app:$IMAGE_TAG .
      docker push $ECR_REGISTRY/app:$IMAGE_TAG
      docker tag $ECR_REGISTRY/app:$IMAGE_TAG $ECR_REGISTRY/app:latest
      docker push $ECR_REGISTRY/app:latest
deploy: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
  - name: Configure kubectl
    uses: azure/k8s-set-context@v3
    with:
      method: kubeconfig
      kubeconfig: ${{ secrets.KUBECONFIG }}

  - name: Deploy to Kubernetes
    env:
      IMAGE_TAG: ${{ github.sha }}
    run: |
      kubectl set image deployment/app \
        app=your-registry/app:$IMAGE_TAG \
        -n production

      kubectl rollout status deployment/app -n production

  - name: Notify Datadog
    run: |
      curl -X POST "https://api.datadoghq.com/api/v1/events" \
        -H "DD-API-KEY: ${{ secrets.DATADOG_API_KEY }}" \
        -d '{
          "title": "Deployment to Production",
          "text": "Deployed version ${{ github.sha }}",
          "tags": ["environment:production", "service:app"]
        }'

  - name: Notify Slack
    if: always()
    uses: slackapi/slack-github-action@v1
    with:
      payload: |
        {
          "text": "Deployment ${{ job.status }}: ${{ github.sha }}"
        }
    env:
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

---

Docker Configuration

Docker配置

Dockerfile

Dockerfile

dockerfile
undefined
dockerfile
undefined

Multi-stage build for optimization

Multi-stage build for optimization

FROM node:18-alpine AS builder
WORKDIR /app
FROM node:18-alpine AS builder
WORKDIR /app

Copy package files

Copy package files

COPY package*.json ./
COPY package*.json ./

Install dependencies

Install dependencies

RUN npm ci --only=production
RUN npm ci --only=production

Copy source code

Copy source code

COPY . .
COPY . .

Build application

Build application

RUN npm run build
RUN npm run build

Production stage

Production stage

FROM node:18-alpine
FROM node:18-alpine

Security: Run as non-root user

Security: Run as non-root user

RUN addgroup -g 1001 -S nodejs &&
adduser -S nodejs -u 1001
WORKDIR /app
RUN addgroup -g 1001 -S nodejs &&
adduser -S nodejs -u 1001
WORKDIR /app

Copy built application from builder

Copy built application from builder

COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist COPY --from=builder --chown=nodejs:nodejs /app/package*.json ./
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist COPY --from=builder --chown=nodejs:nodejs /app/package*.json ./

Switch to non-root user

Switch to non-root user

USER nodejs
USER nodejs

Expose port

Expose port

EXPOSE 3000
EXPOSE 3000

Health check

Health check

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3
CMD node healthcheck.js
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3
CMD node healthcheck.js

Start application

Start application

CMD ["node", "dist/server.js"]
undefined
CMD ["node", "dist/server.js"]
undefined

docker-compose.yml

docker-compose.yml

yaml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://postgres:password@db:5432/app
      - REDIS_URL=redis://redis:6379
    depends_on:
      - db
      - redis
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "node", "healthcheck.js"]
      interval: 30s
      timeout: 3s
      retries: 3

  db:
    image: postgres:14-alpine
    environment:
      - POSTGRES_DB=app
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:

yaml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://postgres:password@db:5432/app
      - REDIS_URL=redis://redis:6379
    depends_on:
      - db
      - redis
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "node", "healthcheck.js"]
      interval: 30s
      timeout: 3s
      retries: 3

  db:
    image: postgres:14-alpine
    environment:
      - POSTGRES_DB=app
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:

Kubernetes Deployment

Kubernetes部署

Deployment Manifest

部署清单

yaml
undefined
yaml
undefined

k8s/deployment.yaml

k8s/deployment.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: app namespace: production labels: app: app version: v1 spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: app template: metadata: labels: app: app version: v1 spec: containers: - name: app image: your-registry/app:latest imagePullPolicy: Always ports: - containerPort: 3000 name: http env: - name: NODE_ENV value: "production" - name: DATABASE_URL valueFrom: secretKeyRef: name: app-secrets key: database-url - name: REDIS_URL valueFrom: secretKeyRef: name: app-secrets key: redis-url resources: requests: cpu: 500m memory: 512Mi limits: cpu: 1000m memory: 1Gi livenessProbe: httpGet: path: /health port: 3000 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 3 readinessProbe: httpGet: path: /ready port: 3000 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 2

apiVersion: v1 kind: Service metadata: name: app namespace: production spec: selector: app: app ports:
  • port: 80 targetPort: 3000 type: ClusterIP

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: app namespace: production annotations: kubernetes.io/ingress.class: nginx cert-manager.io/cluster-issuer: letsencrypt-prod spec: tls:
  • hosts:
    • example.com secretName: app-tls rules:
  • host: example.com http: paths:
    • path: / pathType: Prefix backend: service: name: app port: number: 80

---
apiVersion: apps/v1 kind: Deployment metadata: name: app namespace: production labels: app: app version: v1 spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: app template: metadata: labels: app: app version: v1 spec: containers: - name: app image: your-registry/app:latest imagePullPolicy: Always ports: - containerPort: 3000 name: http env: - name: NODE_ENV value: "production" - name: DATABASE_URL valueFrom: secretKeyRef: name: app-secrets key: database-url - name: REDIS_URL valueFrom: secretKeyRef: name: app-secrets key: redis-url resources: requests: cpu: 500m memory: 512Mi limits: cpu: 1000m memory: 1Gi livenessProbe: httpGet: path: /health port: 3000 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 3 readinessProbe: httpGet: path: /ready port: 3000 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 2

apiVersion: v1 kind: Service metadata: name: app namespace: production spec: selector: app: app ports:
  • port: 80 targetPort: 3000 type: ClusterIP

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: app namespace: production annotations: kubernetes.io/ingress.class: nginx cert-manager.io/cluster-issuer: letsencrypt-prod spec: tls:
  • hosts:
    • example.com secretName: app-tls rules:
  • host: example.com http: paths:
    • path: / pathType: Prefix backend: service: name: app port: number: 80

---

Deployment Procedures

部署流程

1. Pre-Deployment Checklist

1. 部署前检查清单

  • All tests passing
  • Code review approved
  • Security scan passed
  • Database migrations ready
  • Rollback plan documented
  • Monitoring dashboard ready
  • Team notified
  • Maintenance window scheduled (if needed)
  • 所有测试通过
  • 代码评审已批准
  • 安全扫描通过
  • 数据库迁移已准备好
  • 回滚计划已记录
  • 监控仪表板已就绪
  • 团队已收到通知
  • 维护窗口已安排(如有需要)

2. Deployment Steps

2. 部署步骤

bash
undefined
bash
undefined

1. Tag release

1. 标记版本

git tag -a v1.2.3 -m "Release v1.2.3" git push origin v1.2.3
git tag -a v1.2.3 -m "Release v1.2.3" git push origin v1.2.3

2. Build Docker image

2. 构建Docker镜像

docker build -t your-registry/app:v1.2.3 . docker tag your-registry/app:v1.2.3 your-registry/app:latest docker push your-registry/app:v1.2.3 docker push your-registry/app:latest
docker build -t your-registry/app:v1.2.3 . docker tag your-registry/app:v1.2.3 your-registry/app:latest docker push your-registry/app:v1.2.3 docker push your-registry/app:latest

3. Run database migrations

3. 运行数据库迁移

kubectl exec -it deployment/app -n production -- npm run db:migrate
kubectl exec -it deployment/app -n production -- npm run db:migrate

4. Deploy to Kubernetes

4. 部署到Kubernetes

kubectl apply -f k8s/ kubectl set image deployment/app app=your-registry/app:v1.2.3 -n production
kubectl apply -f k8s/ kubectl set image deployment/app app=your-registry/app:v1.2.3 -n production

5. Wait for rollout

5. 等待部署完成

kubectl rollout status deployment/app -n production
kubectl rollout status deployment/app -n production

6. Verify deployment

6. 验证部署

kubectl get pods -n production kubectl logs -f deployment/app -n production
kubectl get pods -n production kubectl logs -f deployment/app -n production

7. Smoke test

7. 冒烟测试

3. Post-Deployment Verification

3. 部署后验证

bash
undefined
bash
undefined

Check pod status

检查Pod状态

kubectl get pods -n production -l app=app
kubectl get pods -n production -l app=app

Check logs for errors

检查日志是否有错误

kubectl logs -f deployment/app -n production --tail=100
kubectl logs -f deployment/app -n production --tail=100

Check metrics

检查指标

Run smoke tests

运行冒烟测试

npm run test:smoke:production
npm run test:smoke:production

Verify in monitoring

在监控系统中验证

- Check Datadog dashboard

- 查看Datadog仪表板

- Check error rates

- 检查错误率

- Check response times

- 检查响应时间

- Check resource usage

- 检查资源使用情况


---

---

Rollback Procedures

回滚流程

Automatic Rollback

自动回滚

bash
undefined
bash
undefined

Rollback to previous version

回滚到上一个版本

kubectl rollout undo deployment/app -n production
kubectl rollout undo deployment/app -n production

Rollback to specific revision

回滚到指定版本

kubectl rollout undo deployment/app -n production --to-revision=2
kubectl rollout undo deployment/app -n production --to-revision=2

Check rollback status

检查回滚状态

kubectl rollout status deployment/app -n production
undefined
kubectl rollout status deployment/app -n production
undefined

Manual Rollback

手动回滚

bash
undefined
bash
undefined

1. Identify last working version

1. 确定最后可用版本

kubectl rollout history deployment/app -n production
kubectl rollout history deployment/app -n production

2. Deploy previous version

2. 部署上一个版本

kubectl set image deployment/app
app=your-registry/app:v1.2.2
-n production
kubectl set image deployment/app
app=your-registry/app:v1.2.2
-n production

3. Rollback database migrations (if needed)

3. 回滚数据库迁移(如有需要)

kubectl exec -it deployment/app -n production --
npm run db:migrate:undo
kubectl exec -it deployment/app -n production --
npm run db:migrate:undo

4. Verify rollback

4. 验证回滚

kubectl get pods -n production curl https://example.com/health

---
kubectl get pods -n production curl https://example.com/health

---

Blue-Green Deployment

蓝绿部署

bash
undefined
bash
undefined

1. Deploy green environment

1. 部署绿色环境

kubectl apply -f k8s/deployment-green.yaml
kubectl apply -f k8s/deployment-green.yaml

2. Wait for green to be ready

2. 等待绿色环境就绪

kubectl rollout status deployment/app-green -n production
kubectl rollout status deployment/app-green -n production

3. Test green environment

3. 测试绿色环境

4. Switch traffic to green

4. 将流量切换到绿色环境

kubectl patch service app -n production
-p '{"spec":{"selector":{"version":"green"}}}'
kubectl patch service app -n production
-p '{"spec":{"selector":{"version":"green"}}}'

5. Monitor for issues

5. 监控是否有问题

If issues: Switch back to blue

若出现问题:切换回蓝色环境

kubectl patch service app -n production
-p '{"spec":{"selector":{"version":"blue"}}}'
kubectl patch service app -n production
-p '{"spec":{"selector":{"version":"blue"}}}'

6. If successful: Remove blue deployment

6. 若部署成功:删除蓝色环境部署

kubectl delete deployment app-blue -n production

---
kubectl delete deployment app-blue -n production

---

Monitoring & Alerting

监控与告警

Health Check Endpoints

健康检查端点

javascript
// healthcheck.js
const http = require('http');

const options = {
  host: 'localhost',
  port: 3000,
  path: '/health',
  timeout: 2000
};

const healthCheck = http.request(options, (res) => {
  if (res.statusCode === 200) {
    process.exit(0);
  } else {
    process.exit(1);
  }
});

healthCheck.on('error', () => {
  process.exit(1);
});

healthCheck.end();
javascript
// healthcheck.js
const http = require('http');

const options = {
  host: 'localhost',
  port: 3000,
  path: '/health',
  timeout: 2000
};

const healthCheck = http.request(options, (res) => {
  if (res.statusCode === 200) {
    process.exit(0);
  } else {
    process.exit(1);
  }
});

healthCheck.on('error', () => {
  process.exit(1);
});

healthCheck.end();

Monitoring Checklist

监控检查清单

  • CPU usage < 70%
  • Memory usage < 80%
  • Error rate < 1%
  • Response time p95 < 500ms
  • Database connections healthy
  • Redis connections healthy
  • All pods running
  • No pending deployments

  • CPU使用率 < 70%
  • 内存使用率 < 80%
  • 错误率 < 1%
  • P95响应时间 < 500ms
  • 数据库连接正常
  • Redis连接正常
  • 所有Pod运行正常
  • 无待处理部署任务

Infrastructure as Code

基础设施即代码

Terraform Configuration

Terraform配置

hcl
undefined
hcl
undefined

main.tf

main.tf

provider "aws" { region = "us-east-1" }
resource "aws_ecs_cluster" "main" { name = "app-cluster" }
resource "aws_ecs_service" "app" { name = "app-service" cluster = aws_ecs_cluster.main.id task_definition = aws_ecs_task_definition.app.arn desired_count = 3
load_balancer { target_group_arn = aws_lb_target_group.app.arn container_name = "app" container_port = 3000 } }
resource "aws_ecs_task_definition" "app" { family = "app" network_mode = "awsvpc" requires_compatibilities = ["FARGATE"] cpu = "512" memory = "1024"
container_definitions = jsonencode([ { name = "app" image = "your-registry/app:latest" essential = true portMappings = [ { containerPort = 3000 protocol = "tcp" } ] environment = [ { name = "NODE_ENV" value = "production" } ] } ]) }
undefined
provider "aws" { region = "us-east-1" }
resource "aws_ecs_cluster" "main" { name = "app-cluster" }
resource "aws_ecs_service" "app" { name = "app-service" cluster = aws_ecs_cluster.main.id task_definition = aws_ecs_task_definition.app.arn desired_count = 3
load_balancer { target_group_arn = aws_lb_target_group.app.arn container_name = "app" container_port = 3000 } }
resource "aws_ecs_task_definition" "app" { family = "app" network_mode = "awsvpc" requires_compatibilities = ["FARGATE"] cpu = "512" memory = "1024"
container_definitions = jsonencode([ { name = "app" image = "your-registry/app:latest" essential = true portMappings = [ { containerPort = 3000 protocol = "tcp" } ] environment = [ { name = "NODE_ENV" value = "production" } ] } ]) }
undefined

Best Practices

最佳实践

✅ DO

✅ 推荐做法

  • Use infrastructure as code
  • Implement CI/CD pipelines
  • Use container orchestration
  • Implement health checks
  • Use rolling deployments
  • Have rollback procedures
  • Monitor deployments
  • Document emergency procedures
  • Use secrets management
  • Implement blue-green or canary deployments
  • 使用基础设施即代码
  • 实现CI/CD流水线
  • 使用容器编排
  • 配置健康检查
  • 使用滚动部署
  • 制定回滚流程
  • 监控部署过程
  • 记录应急流程
  • 使用密钥管理
  • 实现蓝绿或金丝雀部署

❌ DON'T

❌ 不推荐做法

  • Deploy directly to production
  • Skip testing before deploy
  • Forget to backup before migrations
  • Deploy without rollback plan
  • Skip monitoring after deployment
  • Hardcode credentials
  • Deploy during peak hours (unless necessary)
  • 直接部署到生产环境
  • 部署前跳过测试
  • 迁移前忘记备份
  • 部署时无回滚计划
  • 部署后跳过监控
  • 硬编码凭证
  • 在高峰时段部署(除非必要)

Resources

参考资源