phase-9-deployment
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePhase 9: Deployment
第9阶段:部署
Production deployment
生产环境部署
Purpose
目的
Deliver the completed application to users.
将完成的应用交付给用户。
What to Do in This Phase
本阶段需执行的任务
- Prepare Deployment Environment: Infrastructure setup
- Build: Create production build
- Execute Deployment: Actual deployment
- Verification: Post-deployment operation check
- 部署环境准备:基础设施搭建
- 构建:生成生产环境构建包
- 执行部署:实际部署操作
- 验证:部署后运行状态检查
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 configurationdocs/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
分场景应用
| Level | Deployment Method |
|---|---|
| Starter | Static hosting (Netlify, GitHub Pages) |
| Dynamic | Vercel, Railway, etc. |
| Enterprise | Kubernetes, AWS ECS, etc. |
| 场景级别 | 部署方式 |
|---|---|
| 入门级 | 静态托管(Netlify、GitHub Pages) |
| 动态应用 | Vercel、Railway等 |
| 企业级 | Kubernetes、AWS ECS等 |
Starter Deployment (Static Hosting)
入门级部署(静态托管)
bash
undefinedbash
undefinedGitHub 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仓库
undefinedundefinedDynamic Deployment (Vercel)
动态应用部署(Vercel)
bash
undefinedbash
undefinedVercel CLI
Vercel CLI
npm i -g vercel
vercel
npm i -g vercel
vercel
Or auto-deploy via Git connection
或通过Git连接自动部署
undefinedundefinedEnterprise Deployment (Kubernetes)
企业级部署(Kubernetes)
yaml
undefinedyaml
undefinedk8s/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
环境分类
| Environment | Purpose | Data | Variable Source |
|---|---|---|---|
| Development | Local development | Test data | |
| Staging | Pre-deployment verification | Test data | CI/CD Secrets |
| Production | Live service | Real data | CI/CD Secrets + Vault |
| 环境 | 用途 | 数据 | 变量来源 |
|---|---|---|---|
| 开发环境 | 本地开发 | 测试数据 | |
| 预发布环境 | 部署前验证 | 测试数据 | CI/CD密钥 |
| 生产环境 | 线上服务 | 真实数据 | CI/CD密钥 + Vault |
CI/CD Environment Variable Configuration
CI/CD环境变量配置
GitHub Actions
GitHub Actions
yaml
undefinedyaml
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_TOKENundefinedname: 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_TOKENundefinedGitHub 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
分场景密钥管理
| Level | Secrets Management Method | Tools |
|---|---|---|
| Starter | CI/CD platform Secrets | GitHub Secrets, Vercel |
| Dynamic | CI/CD + environment separation | GitHub Environments |
| Enterprise | Dedicated Secrets Manager | Vault, AWS Secrets Manager |
| 场景级别 | 密钥管理方式 | 工具 |
|---|---|---|
| 入门级 | CI/CD平台密钥 | GitHub Secrets、Vercel |
| 动态应用 | CI/CD + 环境隔离 | GitHub Environments |
| 企业级 | 专属密钥管理器 | Vault、AWS Secrets Manager |
Starter/Dynamic: CI/CD Secrets
入门级/动态应用:CI/CD密钥
yaml
undefinedyaml
undefinedUsage in GitHub Actions
GitHub Actions中的使用示例
- name: Deploy env: DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
undefined- name: Deploy env: DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
undefinedEnterprise: HashiCorp Vault
企业级:HashiCorp Vault
yaml
undefinedyaml
undefinedFetch 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
undefinedEnterprise: 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
undefinedyaml
undefinedGitHub 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.mdAfter Completion
完成后
Project complete! Start new feature development cycle from Phase 1 as needed
项目交付完成!后续如需开发新功能,可从第1阶段开启新的开发周期