phase-9-deployment

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Phase 9: Deployment

第9阶段:部署

Production deployment
生产环境部署

Purpose

目的

Deliver the completed application to users.
将完成的应用交付给用户。

What to Do in This Phase

本阶段需执行的任务

  1. Prepare Deployment Environment: Infrastructure setup
  2. Build: Create production build
  3. Execute Deployment: Actual deployment
  4. Verification: Post-deployment operation check
  1. 部署环境准备:基础设施搭建
  2. 构建:生成生产环境构建包
  3. 执行部署:实际部署操作
  4. 验证:部署后运行状态检查

Deliverables

交付物

docs/02-design/
└── deployment-spec.md          # Deployment specification

docs/04-report/
└── deployment-report.md        # Deployment report

(Infrastructure config files)
├── vercel.json                 # Vercel configuration
├── Dockerfile                  # Docker configuration
└── k8s/                        # Kubernetes configuration
docs/02-design/
└── deployment-spec.md          # 部署规格说明文档

docs/04-report/
└── deployment-report.md        # 部署报告

(基础设施配置文件)
├── vercel.json                 # Vercel配置文件
├── Dockerfile                  # Docker配置文件
└── k8s/                        # Kubernetes配置目录

PDCA Application

PDCA循环应用

  • Plan: Establish deployment plan
  • Design: Design deployment configuration
  • Do: Execute deployment
  • Check: Verify deployment
  • Act: Problem resolution and completion report
  • Plan(计划):制定部署方案
  • Design(设计):设计部署配置
  • Do(执行):实施部署操作
  • Check(检查):验证部署结果
  • Act(改进):问题排查与完成报告

Level-wise Application

分场景应用

LevelDeployment Method
StarterStatic hosting (Netlify, GitHub Pages)
DynamicVercel, Railway, etc.
EnterpriseKubernetes, AWS ECS, etc.
场景级别部署方式
入门级静态托管(Netlify、GitHub Pages)
动态应用Vercel、Railway等
企业级Kubernetes、AWS ECS等

Starter Deployment (Static Hosting)

入门级部署(静态托管)

bash
undefined
bash
undefined

GitHub Pages

GitHub Pages

npm run build
npm run build

Deploy dist/ folder to gh-pages branch

将dist/文件夹部署到gh-pages分支

Netlify

Netlify

Configure netlify.toml then connect Git

配置netlify.toml后连接Git仓库

undefined
undefined

Dynamic Deployment (Vercel)

动态应用部署(Vercel)

bash
undefined
bash
undefined

Vercel CLI

Vercel CLI

npm i -g vercel vercel
npm i -g vercel vercel

Or auto-deploy via Git connection

或通过Git连接自动部署

undefined
undefined

Enterprise Deployment (Kubernetes)

企业级部署(Kubernetes)

yaml
undefined
yaml
undefined

k8s/deployment.yaml

k8s/deployment.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 3 template: spec: containers: - name: app image: my-app:latest

---
apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 3 template: spec: containers: - name: app image: my-app:latest

---

Environment Management

环境管理

Environment Configuration Overview

环境变量配置概览

┌─────────────────────────────────────────────────────────────┐
│                     Environment Variable Flow                 │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│   Development                                                │
│   └── .env.local → Developer local machine                  │
│                                                              │
│   Staging                                                    │
│   └── CI/CD Secrets → Preview/Staging environment           │
│                                                              │
│   Production                                                 │
│   └── CI/CD Secrets → Production environment                │
│       └── Vault/Secrets Manager (Enterprise)                │
│                                                              │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│                     环境变量流转流程                         │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│   开发环境                                                  │
│   └── .env.local → 开发者本地机器                            │
│                                                              │
│   预发布环境                                                │
│   └── CI/CD密钥 → 预览/预发布环境                           │
│                                                              │
│   生产环境                                                  │
│   └── CI/CD密钥 → 生产环境                                  │
│       └── Vault/密钥管理器(企业级)                        │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Environment Classification

环境分类

EnvironmentPurposeDataVariable Source
DevelopmentLocal developmentTest data
.env.local
StagingPre-deployment verificationTest dataCI/CD Secrets
ProductionLive serviceReal dataCI/CD Secrets + Vault

环境用途数据变量来源
开发环境本地开发测试数据
.env.local
预发布环境部署前验证测试数据CI/CD密钥
生产环境线上服务真实数据CI/CD密钥 + Vault

CI/CD Environment Variable Configuration

CI/CD环境变量配置

GitHub Actions

GitHub Actions

yaml
undefined
yaml
undefined

.github/workflows/deploy.yml

.github/workflows/deploy.yml

name: Deploy
on: push: branches: [main, staging]
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
  - name: Set environment
    run: |
      if [ "${{ github.ref }}" == "refs/heads/main" ]; then
        echo "DEPLOY_ENV=production" >> $GITHUB_ENV
      else
        echo "DEPLOY_ENV=staging" >> $GITHUB_ENV
      fi

  - name: Build
    env:
      # General environment variables (can be exposed)
      NEXT_PUBLIC_APP_URL: ${{ vars.APP_URL }}
      NEXT_PUBLIC_API_URL: ${{ vars.API_URL }}

      # Secrets (sensitive info)
      DATABASE_URL: ${{ secrets.DATABASE_URL }}
      AUTH_SECRET: ${{ secrets.AUTH_SECRET }}
      API_STRIPE_SECRET: ${{ secrets.API_STRIPE_SECRET }}
    run: npm run build

  - name: Deploy to Vercel
    env:
      VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
    run: |
      npx vercel --prod --token=$VERCEL_TOKEN
undefined
name: Deploy
on: push: branches: [main, staging]
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
  - name: Set environment
    run: |
      if [ "${{ github.ref }}" == "refs/heads/main" ]; then
        echo "DEPLOY_ENV=production" >> $GITHUB_ENV
      else
        echo "DEPLOY_ENV=staging" >> $GITHUB_ENV
      fi

  - name: Build
    env:
      # General environment variables (can be exposed)
      NEXT_PUBLIC_APP_URL: ${{ vars.APP_URL }}
      NEXT_PUBLIC_API_URL: ${{ vars.API_URL }}

      # Secrets (sensitive info)
      DATABASE_URL: ${{ secrets.DATABASE_URL }}
      AUTH_SECRET: ${{ secrets.AUTH_SECRET }}
      API_STRIPE_SECRET: ${{ secrets.API_STRIPE_SECRET }}
    run: npm run build

  - name: Deploy to Vercel
    env:
      VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
    run: |
      npx vercel --prod --token=$VERCEL_TOKEN
undefined

GitHub Secrets Configuration Guide

GitHub密钥配置指南

Repository Settings → Secrets and variables → Actions

1. Repository secrets (sensitive info)
   ├── DATABASE_URL
   ├── AUTH_SECRET
   ├── API_STRIPE_SECRET
   └── VERCEL_TOKEN

2. Repository variables (general settings)
   ├── APP_URL
   ├── API_URL
   └── NODE_ENV

3. Environment-specific secrets
   ├── production/
   │   ├── DATABASE_URL (production DB)
   │   └── API_STRIPE_SECRET (live key)
   └── staging/
       ├── DATABASE_URL (staging DB)
       └── API_STRIPE_SECRET (test key)
仓库设置 → 密钥与变量 → Actions

1. 仓库密钥(敏感信息)
   ├── DATABASE_URL
   ├── AUTH_SECRET
   ├── API_STRIPE_SECRET
   └── VERCEL_TOKEN

2. 仓库变量(通用设置)
   ├── APP_URL
   ├── API_URL
   └── NODE_ENV

3. 环境专属密钥
   ├── production/
   │   ├── DATABASE_URL(生产环境数据库)
   │   └── API_STRIPE_SECRET(正式密钥)
   └── staging/
       ├── DATABASE_URL(预发布环境数据库)
       └── API_STRIPE_SECRET(测试密钥)

Vercel Environment Variable Configuration

Vercel环境变量配置

Project Settings → Environment Variables

┌─────────────────┬─────────────┬─────────────┬─────────────┐
│ Variable Name   │ Development │ Preview     │ Production  │
├─────────────────┼─────────────┼─────────────┼─────────────┤
│ DATABASE_URL    │ dev-db      │ staging-db  │ prod-db     │
│ AUTH_SECRET     │ dev-secret  │ stg-secret  │ prod-secret │
│ API_STRIPE_*    │ test key    │ test key    │ live key    │
└─────────────────┴─────────────┴─────────────┴─────────────┘

Configuration steps:
1. Project Settings → Environment Variables
2. Add New Variable
3. Select environment (Development / Preview / Production)
4. Check Sensitive (if sensitive info)

项目设置 → 环境变量

┌─────────────────┬─────────────┬─────────────┬─────────────┐
│ 变量名称        │ 开发环境     │ 预览环境     │ 生产环境     │
├─────────────────┼─────────────┼─────────────┼─────────────┤
│ DATABASE_URL    │ dev-db      │ staging-db  │ prod-db     │
│ AUTH_SECRET     │ dev-secret  │ stg-secret  │ prod-secret │
│ API_STRIPE_*    │ 测试密钥     │ 测试密钥     │ 正式密钥     │
└─────────────────┴─────────────┴─────────────┴─────────────┘

配置步骤:
1. 进入项目设置 → 环境变量
2. 添加新变量
3. 选择环境(开发/预览/生产)
4. 若为敏感信息,勾选「Sensitive」

Secrets Management Strategy

密钥管理策略

Level-wise Secrets Management

分场景密钥管理

LevelSecrets Management MethodTools
StarterCI/CD platform SecretsGitHub Secrets, Vercel
DynamicCI/CD + environment separationGitHub Environments
EnterpriseDedicated Secrets ManagerVault, AWS Secrets Manager
场景级别密钥管理方式工具
入门级CI/CD平台密钥GitHub Secrets、Vercel
动态应用CI/CD + 环境隔离GitHub Environments
企业级专属密钥管理器Vault、AWS Secrets Manager

Starter/Dynamic: CI/CD Secrets

入门级/动态应用:CI/CD密钥

yaml
undefined
yaml
undefined

Usage in GitHub Actions

GitHub Actions中的使用示例

  • name: Deploy env: DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
undefined
  • name: Deploy env: DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
undefined

Enterprise: HashiCorp Vault

企业级:HashiCorp Vault

yaml
undefined
yaml
undefined

Fetch Secrets from Vault

从Vault拉取密钥

  • name: Import Secrets from Vault uses: hashicorp/vault-action@v2 with: url: https://vault.company.com token: ${{ secrets.VAULT_TOKEN }} secrets: | secret/data/myapp/production db_password | DB_PASSWORD ; secret/data/myapp/production api_key | API_KEY
undefined
  • name: Import Secrets from Vault uses: hashicorp/vault-action@v2 with: url: https://vault.company.com token: ${{ secrets.VAULT_TOKEN }} secrets: | secret/data/myapp/production db_password | DB_PASSWORD ; secret/data/myapp/production api_key | API_KEY
undefined

Enterprise: AWS Secrets Manager

企业级:AWS Secrets Manager

typescript
// lib/secrets.ts
import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";

const client = new SecretsManagerClient({ region: "ap-northeast-2" });

export async function getSecret(secretName: string): Promise<Record<string, string>> {
  const command = new GetSecretValueCommand({ SecretId: secretName });
  const response = await client.send(command);

  if (response.SecretString) {
    return JSON.parse(response.SecretString);
  }
  throw new Error(`Secret ${secretName} not found`);
}

// Usage
const dbSecrets = await getSecret("myapp/production/database");
// { host: "...", password: "...", ... }

typescript
// lib/secrets.ts
import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";

const client = new SecretsManagerClient({ region: "ap-northeast-2" });

export async function getSecret(secretName: string): Promise<Record<string, string>> {
  const command = new GetSecretValueCommand({ SecretId: secretName });
  const response = await client.send(command);

  if (response.SecretString) {
    return JSON.parse(response.SecretString);
  }
  throw new Error(`Secret ${secretName} not found`);
}

// 使用示例
const dbSecrets = await getSecret("myapp/production/database");
// { host: "...", password: "...", ... }

Environment-specific Build Configuration

环境专属构建配置

Next.js Environment Configuration

Next.js环境配置

javascript
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  // Environment-specific settings
  env: {
    NEXT_PUBLIC_ENV: process.env.NODE_ENV,
  },

  // Environment-specific redirects
  async redirects() {
    if (process.env.NODE_ENV === 'production') {
      return [
        { source: '/debug', destination: '/', permanent: false },
      ];
    }
    return [];
  },
};

module.exports = nextConfig;
javascript
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  // Environment-specific settings
  env: {
    NEXT_PUBLIC_ENV: process.env.NODE_ENV,
  },

  // Environment-specific redirects
  async redirects() {
    if (process.env.NODE_ENV === 'production') {
      return [
        { source: '/debug', destination: '/', permanent: false },
      ];
    }
    return [];
  },
};

module.exports = nextConfig;

Environment-specific API Endpoints

环境专属API端点配置

typescript
// lib/config.ts
const config = {
  development: {
    apiUrl: 'http://localhost:3001',
    debug: true,
  },
  staging: {
    apiUrl: 'https://api-staging.myapp.com',
    debug: true,
  },
  production: {
    apiUrl: 'https://api.myapp.com',
    debug: false,
  },
} as const;

type Environment = keyof typeof config;

const env = (process.env.NODE_ENV || 'development') as Environment;
export const appConfig = config[env];

typescript
// lib/config.ts
const config = {
  development: {
    apiUrl: 'http://localhost:3001',
    debug: true,
  },
  staging: {
    apiUrl: 'https://api-staging.myapp.com',
    debug: true,
  },
  production: {
    apiUrl: 'https://api.myapp.com',
    debug: false,
  },
} as const;

type Environment = keyof typeof config;

const env = (process.env.NODE_ENV || 'development') as Environment;
export const appConfig = config[env];

Environment Variable Validation (Pre-deployment)

环境变量校验(部署前)

Required Variable Check Script

必填变量检查脚本

javascript
#!/usr/bin/env node
// scripts/check-env.js

const REQUIRED_VARS = [
  'DATABASE_URL',
  'AUTH_SECRET',
  'NEXT_PUBLIC_APP_URL'
];

const missing = REQUIRED_VARS.filter(v => !process.env[v]);

if (missing.length > 0) {
  console.error('❌ Missing required environment variables:');
  missing.forEach(v => console.error(`  - ${v}`));
  process.exit(1);
}

console.log('✅ All required environment variables are set');
javascript
#!/usr/bin/env node
// scripts/check-env.js

const REQUIRED_VARS = [
  'DATABASE_URL',
  'AUTH_SECRET',
  'NEXT_PUBLIC_APP_URL'
];

const missing = REQUIRED_VARS.filter(v => !process.env[v]);

if (missing.length > 0) {
  console.error('❌ 缺少必填环境变量:');
  missing.forEach(v => console.error(`  - ${v}`));
  process.exit(1);
}

console.log('✅ 所有必填环境变量已配置完成');

Validation in CI/CD

CI/CD中的校验

yaml
undefined
yaml
undefined

GitHub Actions

GitHub Actions

  • name: Validate Environment run: node scripts/check-env.js env: DATABASE_URL: ${{ secrets.DATABASE_URL }} AUTH_SECRET: ${{ secrets.AUTH_SECRET }} NEXT_PUBLIC_APP_URL: ${{ vars.APP_URL }}

---
  • name: Validate Environment run: node scripts/check-env.js env: DATABASE_URL: ${{ secrets.DATABASE_URL }} AUTH_SECRET: ${{ secrets.AUTH_SECRET }} NEXT_PUBLIC_APP_URL: ${{ vars.APP_URL }}

---

Environment Variable Management Checklist

环境变量管理检查清单

Pre-deployment

部署前

  • Secrets Registration
    • DATABASE_URL (per environment)
    • AUTH_SECRET (per environment)
    • External API keys (per environment)
  • Environment Separation
    • Development / Staging / Production distinction
    • Per-environment database separation
    • Per-environment external service key separation (test/live)
  • Validation
    • Run required variable check script
    • Build test
  • 密钥注册
    • DATABASE_URL(分环境配置)
    • AUTH_SECRET(分环境配置)
    • 外部API密钥(分环境配置)
  • 环境隔离
    • 开发/预发布/生产环境区分明确
    • 分环境数据库隔离
    • 分环境外部服务密钥隔离(测试/正式)
  • 校验
    • 运行必填变量检查脚本
    • 构建测试

Post-deployment

部署后

  • Operation Check
    • Verify environment variables are injected correctly
    • External service integration test
  • Security Check
    • Verify no sensitive info in logs
    • Verify no server-only variables exposed to client

  • 运行状态检查
    • 验证环境变量注入正确
    • 外部服务集成测试
  • 安全检查
    • 验证日志中无敏感信息
    • 验证服务端专属变量未暴露给客户端

Deployment Checklist

部署检查清单

Preparation

准备工作

  • Environment variable configuration (see checklist above)
  • Domain connection
  • SSL certificate
  • 环境变量配置(参考上述检查清单)
  • 域名绑定
  • SSL证书配置

Deployment

部署执行

  • Build successful
  • Deployment complete
  • Health check passed
  • 构建成功
  • 部署完成
  • 健康检查通过

Verification

验证确认

  • Major feature operation check
  • Error log review
  • Performance monitoring
  • 核心功能运行检查
  • 错误日志排查
  • 性能监控

Rollback Plan

回滚方案

If problems occur:
1. Immediately rollback to previous version
2. Analyze root cause
3. Fix and redeploy
若出现问题:
1. 立即回滚至上一版本
2. 分析问题根源
3. 修复后重新部署

Template

模板

See
templates/pipeline/phase-9-deployment.template.md
详见
templates/pipeline/phase-9-deployment.template.md

After Completion

完成后

Project complete! Start new feature development cycle from Phase 1 as needed
项目交付完成!后续如需开发新功能,可从第1阶段开启新的开发周期