Deployment Workflow
Tổng quan quy trình
┌─────────────────────────────────────────────────────────────┐
│ DEPLOYMENT PIPELINE │
├─────────────────────────────────────────────────────────────┤
│ │
│ Developer ──▶ Git Push ──▶ GitHub Actions ──▶ Cloudflare │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Local │───▶│ Build │───▶│ Deploy │ │
│ │ Dev │ │ & Test │ │ Worker │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Manual Deployment
Deploy trực tiếp từ local
# 1. Build Next.js
npm run build
# 2. Build for Cloudflare
npm run build:worker
# 3. Deploy to production
wrangler deploy
# Output:
# Uploaded my-app (1.23 sec)
# Published my-app (0.45 sec)
# https://my-app.username.workers.dev
Deploy với environment
# Deploy to staging
wrangler deploy --env staging
# Deploy to production
wrangler deploy --env production
Multi-environment Setup
wrangler.toml với environments
name = "my-nextjs-app"
main = ".open-next/worker.js"
compatibility_date = "2024-09-23"
compatibility_flags = ["nodejs_compat"]
[assets]
directory = ".open-next/assets"
binding = "ASSETS"
# ==================
# Development (default)
# ==================
[vars]
ENVIRONMENT = "development"
NEXT_PUBLIC_API_URL = "http://localhost:3000"
[[kv_namespaces]]
binding = "CACHE"
id = "dev-kv-id"
# ==================
# Staging
# ==================
[env.staging]
name = "my-app-staging"
routes = [{ pattern = "staging.myapp.com", custom_domain = true }]
[env.staging.vars]
ENVIRONMENT = "staging"
NEXT_PUBLIC_API_URL = "https://staging.myapp.com"
[[env.staging.kv_namespaces]]
binding = "CACHE"
id = "staging-kv-id"
# ==================
# Production
# ==================
[env.production]
name = "my-app-production"
routes = [{ pattern = "myapp.com", custom_domain = true }]
[env.production.vars]
ENVIRONMENT = "production"
NEXT_PUBLIC_API_URL = "https://myapp.com"
[[env.production.kv_namespaces]]
binding = "CACHE"
id = "production-kv-id"
Secrets Management
Set secrets via CLI
# Development (default)
wrangler secret put SUPABASE_SERVICE_KEY
# Enter value: sk_xxx
# Staging
wrangler secret put SUPABASE_SERVICE_KEY --env staging
# Production
wrangler secret put SUPABASE_SERVICE_KEY --env production
List secrets
wrangler secret list
wrangler secret list --env production
Delete secret
wrangler secret delete SECRET_NAME
GitHub Actions CI/CD
Workflow file
# .github/workflows/deploy.yml
name: Deploy to Cloudflare
on:
push:
branches:
- main # Production
- staging # Staging
pull_request:
branches:
- main
env:
NODE_VERSION: '20'
jobs:
# ================
# Build & Test
# ================
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linting
run: npm run lint
- name: Run tests
run: npm run test
- name: Build Next.js
run: npm run build
- name: Build for Cloudflare
run: npm run build:worker
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-output
path: .open-next/
# ================
# Deploy Staging
# ================
deploy-staging:
needs: build
if: github.ref == 'refs/heads/staging'
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build-output
path: .open-next/
- name: Deploy to Cloudflare (Staging)
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --env staging
# ================
# Deploy Production
# ================
deploy-production:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build-output
path: .open-next/
- name: Deploy to Cloudflare (Production)
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --env production
GitHub Secrets Setup
Required secrets
| Secret |
Description |
How to get |
CLOUDFLARE_API_TOKEN |
API token với Workers permissions |
Cloudflare Dashboard → Profile → API Tokens |
CLOUDFLARE_ACCOUNT_ID |
Account ID |
Cloudflare Dashboard → Workers → Account ID |
Tạo API Token
1. Cloudflare Dashboard → Profile → API Tokens
2. Create Token
3. Use template: "Edit Cloudflare Workers"
4. Account Resources: Include → Your Account
5. Zone Resources: Include → All zones
6. Create Token
7. Copy token → Add to GitHub Secrets
Preview Deployments (Pull Requests)
Thêm preview deployment
# .github/workflows/preview.yml
name: Preview Deployment
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install & Build
run: |
npm ci
npm run build
npm run build:worker
- name: Deploy Preview
id: deploy
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --env preview
- name: Comment Preview URL
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '🚀 Preview deployed: ${{ steps.deploy.outputs.deployment-url }}'
})
Rollback Strategy
Quick rollback
# List recent deployments
wrangler deployments list --env production
# Rollback to previous version
wrangler rollback --env production
# Rollback to specific version
wrangler rollback <deployment-id> --env production
Via Dashboard
1. Cloudflare Dashboard → Workers
2. Select your worker
3. Deployments tab
4. Click "Rollback" on previous deployment
Deployment Best Practices
Checklist trước deploy
- [ ] Tất cả tests pass
- [ ] Environment variables đã set
- [ ] Secrets đã set cho environment
- [ ] Database migrations đã chạy
- [ ] Build thành công locally
Monitoring sau deploy
# Watch logs
wrangler tail --env production
# Check metrics
# Cloudflare Dashboard → Workers → Analytics
Tổng kết
Deployment Flow
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Dev │────▶│ Staging │────▶│Production│
│ Branch │ │ Branch │ │ Branch │
└──────────┘ └──────────┘ └──────────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Preview │ │ Staging │ │Production│
│ URL │ │ URL │ │ URL │
└──────────┘ └──────────┘ └──────────┘
Key Commands
# Local preview
npm run preview
# Deploy to staging
wrangler deploy --env staging
# Deploy to production
wrangler deploy --env production
# Rollback
wrangler rollback --env production
# View logs
wrangler tail --env production
Q&A
- Team bạn đang dùng CI/CD tool nào?
- Có cần preview deployments không?
- Rollback strategy hiện tại là gì?