claude-help

11 - Deploy lên Production với Claude Code

Hướng dẫn toàn diện về triển khai ứng dụng lên production sử dụng Claude Code CLI. Từ VPS đến Cloud, từ SSL đến monitoring, tất cả các lệnh đều sẵn sàng để sao chép và chạy.


Mục lục

  1. Chuẩn bị trước khi deploy
  2. Deploy lên VPS (Ubuntu/Debian)
  3. Deploy lên Cloud
  4. Platform as a Service
  5. SSL/TLS và Domain
  6. Reverse Proxy và Load Balancing
  7. Auto-scaling
  8. Monitoring và Alerting
  9. Zero-downtime Deployment
  10. Rollback Strategies
  11. Sử dụng Claude Skills
  12. Các prompt mẫu deploy
  13. Checklist Deploy Production

1. Chuẩn bị trước khi deploy

Checklist pre-deployment

# Prompt cho Claude:
Kiểm tra dự án trước khi deploy production:
- Chạy tất cả test
- Kiểm tra lỗi TypeScript/lint
- Audit bảo mật dependencies
- Kiểm tra biến môi trường
- Build thử production

Kiểm tra code và test

# Chạy tất cả test
npm run test

# Chạy test với coverage
npm run test -- --coverage

# Kiểm tra lint
npm run lint

# Kiểm tra TypeScript
npx tsc --noEmit

# Build production
npm run build

Kiểm tra environment variables

# Prompt cho Claude:
Tạo script kiểm tra tất cả environment variables cần thiết trước khi deploy.
So sánh file .env.example với các biến thực tế trong code.
Báo lỗi nếu thiếu biến nào.
# Script kiểm tra env (check-env.sh)
#!/bin/bash
REQUIRED_VARS=(
  "DATABASE_URL"
  "REDIS_URL"
  "JWT_SECRET"
  "API_KEY"
  "NODE_ENV"
)

MISSING=0
for VAR in "${REQUIRED_VARS[@]}"; do
  if [ -z "${!VAR}" ]; then
    echo "THIẾU: $VAR"
    MISSING=$((MISSING + 1))
  else
    echo "OK: $VAR"
  fi
done

if [ $MISSING -gt 0 ]; then
  echo "Thiếu $MISSING biến môi trường. Dừng deploy."
  exit 1
fi
echo "Tất cả biến môi trường đã sẵn sàng."

Build optimization

# Prompt cho Claude:
Tối ưu build production cho ứng dụng Node.js/Next.js:
- Minify code
- Tree shaking
- Bundle analysis
- Tối ưu Docker image size
# Phân tích bundle size (Next.js)
npx @next/bundle-analyzer

# Build với report
ANALYZE=true npm run build

# Kiểm tra kích thước build
du -sh .next/
du -sh node_modules/

Security audit

# Kiểm tra lỗ hổng bảo mật dependencies
npm audit

# Tự động fix lỗ hổng (cẩn thận với breaking changes)
npm audit fix

# Kiểm tra chi tiết
npm audit --json | jq '.vulnerabilities | to_entries[] | select(.value.severity == "critical")'

# Quét bảo mật với Snyk
npx snyk test

# Kiểm tra secrets bị lộ trong code
npx secretlint "**/*"

2. Deploy lên VPS (Ubuntu/Debian)

Prompt tổng hợp cho Claude

Tạo script deploy ứng dụng Node.js lên VPS Ubuntu:
- Cài đặt Node.js, Nginx, PM2
- Setup reverse proxy
- SSL với Certbot
- Firewall (UFW)
- Systemd service

Bước 1: Kết nối SSH và cập nhật hệ thống

# Kết nối SSH đến VPS
ssh root@your-server-ip

# Hoặc dùng SSH key
ssh -i ~/.ssh/my-key.pem ubuntu@your-server-ip

# Cập nhật hệ thống
sudo apt update && sudo apt upgrade -y

# Cài đặt các công cụ cần thiết
sudo apt install -y curl git build-essential ufw

Bước 2: Tạo user deploy (không dùng root)

# Tạo user mới
sudo adduser deploy

# Thêm vào group sudo
sudo usermod -aG sudo deploy

# Copy SSH key sang user mới
sudo mkdir -p /home/deploy/.ssh
sudo cp ~/.ssh/authorized_keys /home/deploy/.ssh/
sudo chown -R deploy:deploy /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys

# Chuyển sang user deploy
su - deploy

Bước 3: Cài đặt Node.js

# Cài đặt Node.js 20 LTS qua NodeSource
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

# Kiểm tra phiên bản
node --version
npm --version

# Cài đặt PM2 globally
sudo npm install -g pm2

Bước 4: Clone và build ứng dụng

# Clone repository
cd /home/deploy
git clone https://github.com/your-org/your-app.git app
cd app

# Cài đặt dependencies (production only)
npm ci --production

# Copy file environment
cp .env.example .env
nano .env  # Chỉnh sửa biến môi trường

# Build ứng dụng
npm run build

Bước 5: Chạy với PM2

# Khởi chạy ứng dụng
pm2 start dist/main.js --name "my-app" -i max

# Hoặc dùng ecosystem file
cat > ecosystem.config.js << 'EOF'
module.exports = {
  apps: [{
    name: 'my-app',
    script: 'dist/main.js',
    instances: 'max',
    exec_mode: 'cluster',
    env_production: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    max_memory_restart: '500M',
    log_date_format: 'YYYY-MM-DD HH:mm:ss',
    error_file: '/home/deploy/logs/error.log',
    out_file: '/home/deploy/logs/out.log'
  }]
};
EOF

# Chạy với ecosystem
pm2 start ecosystem.config.js --env production

# Lưu cấu hình PM2 để tự khởi động lại
pm2 save
pm2 startup systemd

Bước 6: Cấu hình Nginx reverse proxy

# Cài đặt Nginx
sudo apt install -y nginx

# Tạo cấu hình Nginx
sudo tee /etc/nginx/sites-available/my-app << 'EOF'
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    # Giới hạn kích thước upload
    client_max_body_size 10M;

    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript text/xml;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        proxy_read_timeout 90;
    }

    # Cache static files
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        proxy_pass http://127.0.0.1:3000;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}
EOF

# Kích hoạt site
sudo ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default

# Kiểm tra cấu hình
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

Bước 7: SSL với Certbot

# Cài đặt Certbot
sudo apt install -y certbot python3-certbot-nginx

# Lấy SSL certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# Tự động gia hạn (certbot đã tạo cron tự động)
sudo certbot renew --dry-run

Bước 8: Firewall (UFW)

# Bật UFW
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Cho phép SSH, HTTP, HTTPS
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'

# Bật firewall
sudo ufw enable

# Kiểm tra trạng thái
sudo ufw status verbose

Script deploy tự động

# Prompt cho Claude:
Tạo script deploy.sh tự động:
- Pull code mới từ git
- Cài dependencies
- Build
- Restart PM2
- Kiểm tra health check
#!/bin/bash
# deploy.sh - Script deploy tự động
set -e

APP_DIR="/home/deploy/app"
LOG_FILE="/home/deploy/logs/deploy.log"

echo "$(date) - Bắt đầu deploy..." | tee -a "$LOG_FILE"

cd "$APP_DIR"

# Pull code mới
echo "Pulling code mới..."
git pull origin main

# Cài dependencies
echo "Cài đặt dependencies..."
npm ci --production

# Build
echo "Building..."
npm run build

# Restart PM2
echo "Khởi động lại ứng dụng..."
pm2 reload my-app

# Health check
echo "Kiểm tra health..."
sleep 3
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/health)
if [ "$HTTP_CODE" -eq 200 ]; then
  echo "Deploy thành công! Health check: $HTTP_CODE" | tee -a "$LOG_FILE"
else
  echo "CẢNH BÁO: Health check thất bại ($HTTP_CODE)" | tee -a "$LOG_FILE"
  pm2 logs my-app --lines 50
  exit 1
fi

3. Deploy lên Cloud

AWS

EC2 + RDS + S3

# Prompt cho Claude:
Tạo cấu hình Terraform cho hạ tầng AWS:
- EC2 instance (t3.medium) trong private subnet
- RDS PostgreSQL trong private subnet
- S3 bucket cho static assets
- ALB (Application Load Balancer)
- VPC với public/private subnets
- Security groups
# main.tf - Ví dụ cấu hình Terraform cơ bản
provider "aws" {
  region = "ap-southeast-1"
}

resource "aws_instance" "app" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.medium"
  key_name      = "my-key"

  vpc_security_group_ids = [aws_security_group.app.id]
  subnet_id              = aws_subnet.private.id

  user_data = <<-EOF
    #!/bin/bash
    curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
    apt-get install -y nodejs nginx
    npm install -g pm2
  EOF

  tags = {
    Name = "app-production"
  }
}

resource "aws_db_instance" "postgres" {
  identifier     = "app-db"
  engine         = "postgres"
  engine_version = "15"
  instance_class = "db.t3.micro"
  allocated_storage = 20

  db_name  = "appdb"
  username = "admin"
  password = var.db_password

  vpc_security_group_ids = [aws_security_group.db.id]
  db_subnet_group_name   = aws_db_subnet_group.main.name

  skip_final_snapshot = false
  backup_retention_period = 7
}

resource "aws_s3_bucket" "assets" {
  bucket = "my-app-assets-production"
}

ECS/Fargate

# Prompt cho Claude:
Tạo cấu hình deploy AWS ECS Fargate:
- Task definition
- Service
- ALB
- Auto-scaling
- CloudWatch logs
{
  "family": "my-app",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "executionRoleArn": "arn:aws:iam::role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "app",
      "image": "123456789.dkr.ecr.ap-southeast-1.amazonaws.com/my-app:latest",
      "portMappings": [
        {
          "containerPort": 3000,
          "protocol": "tcp"
        }
      ],
      "environment": [
        { "name": "NODE_ENV", "value": "production" }
      ],
      "secrets": [
        {
          "name": "DATABASE_URL",
          "valueFrom": "arn:aws:secretsmanager:ap-southeast-1::secret:db-url"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/my-app",
          "awslogs-region": "ap-southeast-1",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "healthCheck": {
        "command": ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
        "interval": 30,
        "timeout": 5,
        "retries": 3
      }
    }
  ]
}
# Deploy ECS bằng AWS CLI
aws ecs register-task-definition --cli-input-json file://task-definition.json

aws ecs create-service \
  --cluster my-cluster \
  --service-name my-app \
  --task-definition my-app:1 \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-xxx],securityGroups=[sg-xxx],assignPublicIp=ENABLED}" \
  --load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:...,containerName=app,containerPort=3000"

# Cập nhật service (deploy phiên bản mới)
aws ecs update-service \
  --cluster my-cluster \
  --service my-app \
  --force-new-deployment

Lambda (Serverless)

# Prompt cho Claude:
Tạo cấu hình serverless cho API bằng AWS Lambda + API Gateway:
- serverless.yml hoặc SAM template
- Các function handler
- DynamoDB table
- Cấu hình API Gateway
# serverless.yml
service: my-api

provider:
  name: aws
  runtime: nodejs20.x
  region: ap-southeast-1
  stage: production
  memorySize: 512
  timeout: 30
  environment:
    DATABASE_URL: ${ssm:/my-app/database-url}
    JWT_SECRET: ${ssm:/my-app/jwt-secret}

functions:
  api:
    handler: dist/lambda.handler
    events:
      - httpApi:
          path: /{proxy+}
          method: ANY
      - httpApi:
          path: /
          method: ANY

plugins:
  - serverless-offline
# Deploy với Serverless Framework
npx serverless deploy --stage production

# Xem logs
npx serverless logs -f api --stage production --tail

Google Cloud Platform

Cloud Run

# Prompt cho Claude:
Tạo cấu hình deploy Google Cloud Run:
- Dockerfile tối ưu
- cloudbuild.yaml
- Service configuration
- Cloud SQL kết nối
# Build và push Docker image
gcloud builds submit --tag gcr.io/my-project/my-app

# Deploy lên Cloud Run
gcloud run deploy my-app \
  --image gcr.io/my-project/my-app \
  --platform managed \
  --region asia-southeast1 \
  --allow-unauthenticated \
  --memory 512Mi \
  --cpu 1 \
  --min-instances 1 \
  --max-instances 10 \
  --set-env-vars "NODE_ENV=production" \
  --set-secrets "DATABASE_URL=db-url:latest,JWT_SECRET=jwt-secret:latest"

# Xem logs
gcloud run services logs read my-app --region asia-southeast1

GKE (Google Kubernetes Engine)

# Tạo cluster
gcloud container clusters create my-cluster \
  --region asia-southeast1 \
  --num-nodes 2 \
  --machine-type e2-medium

# Deploy ứng dụng
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml

Azure

App Service

# Tạo resource group và App Service
az group create --name my-rg --location southeastasia

az appservice plan create \
  --name my-plan \
  --resource-group my-rg \
  --sku B1 \
  --is-linux

az webapp create \
  --resource-group my-rg \
  --plan my-plan \
  --name my-app \
  --runtime "NODE:20-lts"

# Deploy từ GitHub
az webapp deployment source config \
  --name my-app \
  --resource-group my-rg \
  --repo-url https://github.com/your-org/your-app \
  --branch main

# Cấu hình biến môi trường
az webapp config appsettings set \
  --resource-group my-rg \
  --name my-app \
  --settings NODE_ENV=production DATABASE_URL=@Microsoft.KeyVault(...)

Container Apps

# Deploy lên Azure Container Apps
az containerapp create \
  --name my-app \
  --resource-group my-rg \
  --environment my-env \
  --image myregistry.azurecr.io/my-app:latest \
  --target-port 3000 \
  --ingress external \
  --min-replicas 1 \
  --max-replicas 5 \
  --cpu 0.5 \
  --memory 1.0Gi

4. Platform as a Service

Vercel (Next.js)

# Cài đặt Vercel CLI
npm i -g vercel

# Login
vercel login

# Deploy (lần đầu - tạo project)
vercel

# Deploy production
vercel --prod

Cấu hình vercel.json:

{
  "version": 2,
  "builds": [
    { "src": "package.json", "use": "@vercel/next" }
  ],
  "env": {
    "DATABASE_URL": "@database-url",
    "NEXT_PUBLIC_API_URL": "https://api.yourdomain.com"
  },
  "regions": ["sin1"],
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Cache-Control", "value": "no-store" }
      ]
    }
  ],
  "rewrites": [
    { "source": "/api/:path*", "destination": "/api/:path*" }
  ]
}
# Quản lý biến môi trường
vercel env add DATABASE_URL production
vercel env ls

# Custom domain
vercel domains add yourdomain.com

# Xem logs
vercel logs --follow

Railway

# Cài đặt Railway CLI
npm i -g @railway/cli

# Login
railway login

# Tạo project mới
railway init

# Link với project có sẵn
railway link

# Deploy
railway up

# Mở dashboard
railway open

# Xem logs
railway logs

# Thêm service (PostgreSQL, Redis, ...)
railway add

Render

Cấu hình render.yaml:

services:
  - type: web
    name: my-app
    runtime: node
    region: singapore
    plan: starter
    buildCommand: npm ci && npm run build
    startCommand: npm start
    envVars:
      - key: NODE_ENV
        value: production
      - key: DATABASE_URL
        fromDatabase:
          name: my-db
          property: connectionString
    autoDeploy: true
    healthCheckPath: /health

databases:
  - name: my-db
    plan: starter
    databaseName: appdb
    region: singapore
# Deploy tự động khi push lên GitHub
git push origin main

Fly.io

# Cài đặt Fly CLI
curl -L https://fly.io/install.sh | sh

# Login
fly auth login

# Tạo app mới (tự detect framework)
fly launch

# Deploy
fly deploy

# Xem trạng thái
fly status

# Xem logs
fly logs

# Scale
fly scale count 3
fly scale vm shared-cpu-2x

Cấu hình fly.toml:

app = "my-app"
primary_region = "sin"

[build]
  dockerfile = "Dockerfile"

[env]
  NODE_ENV = "production"
  PORT = "3000"

[http_service]
  internal_port = 3000
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 1

  [http_service.concurrency]
    type = "requests"
    hard_limit = 250
    soft_limit = 200

[[vm]]
  cpu_kind = "shared"
  cpus = 1
  memory_mb = 512

[checks]
  [checks.health]
    type = "http"
    port = 3000
    path = "/health"
    interval = "15s"
    timeout = "5s"
# Thêm secrets
fly secrets set DATABASE_URL="postgres://..." JWT_SECRET="..."

# Thêm database PostgreSQL
fly postgres create
fly postgres attach my-db

5. SSL/TLS và Domain

Certbot / Let’s Encrypt

# Cài đặt Certbot (Ubuntu/Debian)
sudo apt install -y certbot python3-certbot-nginx

# Lấy certificate cho Nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# Lấy certificate standalone (không có web server)
sudo certbot certonly --standalone -d yourdomain.com

# Gia hạn tất cả certificates
sudo certbot renew

# Kiểm tra lịch gia hạn tự động
sudo systemctl status certbot.timer

# Wildcard certificate (cần DNS challenge)
sudo certbot certonly --manual --preferred-challenges dns \
  -d "*.yourdomain.com" -d yourdomain.com

Cloudflare DNS + SSL

# Prompt cho Claude:
Cấu hình Cloudflare cho domain:
- DNS records (A, CNAME)
- SSL/TLS mode: Full (Strict)
- Page rules
- Firewall rules
- Cache rules
# Sử dụng Cloudflare API
CLOUDFLARE_TOKEN="your-api-token"
ZONE_ID="your-zone-id"

# Thêm DNS record
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
  -H "Authorization: Bearer $CLOUDFLARE_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "type": "A",
    "name": "yourdomain.com",
    "content": "your-server-ip",
    "ttl": 1,
    "proxied": true
  }'

Custom domain setup

# Kiểm tra DNS propagation
dig yourdomain.com A
dig yourdomain.com CNAME

# Kiểm tra SSL certificate
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com </dev/null 2>/dev/null | openssl x509 -noout -dates

# Kiểm tra HTTPS
curl -I https://yourdomain.com

6. Reverse Proxy và Load Balancing

Nginx nâng cao

# Prompt cho Claude:
Tạo cấu hình Nginx load balancing cho 3 instance Node.js:
- Upstream với health check
- Rate limiting
- Caching
- WebSocket support
- Security headers
# /etc/nginx/sites-available/my-app
upstream app_backend {
    least_conn;
    server 127.0.0.1:3001 weight=3;
    server 127.0.0.1:3002 weight=2;
    server 127.0.0.1:3003 weight=1;
    keepalive 32;
}

# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=3r/m;

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # Security headers
    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;

    # API routes với rate limiting
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        proxy_pass http://app_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Login route với rate limiting chặt hơn
    location /api/auth/login {
        limit_req zone=login burst=5 nodelay;
        proxy_pass http://app_backend;
    }

    # WebSocket support
    location /ws {
        proxy_pass http://app_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }

    # Cache static files
    location /static/ {
        proxy_pass http://app_backend;
        proxy_cache my_cache;
        proxy_cache_valid 200 30d;
        expires 30d;
    }
}

Traefik (phù hợp Docker/Kubernetes)

# docker-compose.yml với Traefik
version: '3.8'
services:
  traefik:
    image: traefik:v3.0
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.le.acme.email=admin@yourdomain.com"
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - letsencrypt:/letsencrypt

  app:
    image: my-app:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`yourdomain.com`)"
      - "traefik.http.routers.app.tls.certresolver=le"
      - "traefik.http.services.app.loadbalancer.server.port=3000"
    deploy:
      replicas: 3

volumes:
  letsencrypt:

7. Auto-scaling

Horizontal scaling (thêm instance)

# Prompt cho Claude:
Tạo cấu hình auto-scaling cho ứng dụng:
- Scale dựa trên CPU usage (>70%)
- Scale dựa trên memory (>80%)
- Scale dựa trên request count
- Min: 2 instances, Max: 10 instances
# Kubernetes HPA (Horizontal Pod Autoscaler)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80
# AWS Auto Scaling
aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name my-app-asg \
  --launch-template LaunchTemplateName=my-app-template,Version='$Latest' \
  --min-size 2 \
  --max-size 10 \
  --desired-capacity 2 \
  --vpc-zone-identifier "subnet-xxx,subnet-yyy"

# Tạo scaling policy dựa trên CPU
aws autoscaling put-scaling-policy \
  --auto-scaling-group-name my-app-asg \
  --policy-name cpu-scale-out \
  --policy-type TargetTrackingScaling \
  --target-tracking-configuration '{
    "TargetValue": 70.0,
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "ASGAverageCPUUtilization"
    }
  }'

Vertical scaling (tăng tài nguyên)

# PM2 - tăng memory limit
pm2 restart my-app --max-memory-restart 1G

# Docker - tăng tài nguyên container
docker update --memory=2g --cpus=2 my-app-container

# Kubernetes - cập nhật resource limits
kubectl set resources deployment my-app \
  --limits=cpu=2,memory=2Gi \
  --requests=cpu=500m,memory=512Mi

8. Monitoring và Alerting

Uptime monitoring

# Prompt cho Claude:
Tạo hệ thống monitoring cho production:
- Health check endpoint
- Uptime monitoring
- Response time tracking
- Error rate alerting
// health.controller.js - Health check endpoint
app.get('/health', async (req, res) => {
  const healthcheck = {
    status: 'ok',
    timestamp: new Date().toISOString(),
    uptime: process.uptime(),
    memory: process.memoryUsage(),
    checks: {}
  };

  try {
    // Kiểm tra database
    await db.query('SELECT 1');
    healthcheck.checks.database = 'ok';
  } catch (e) {
    healthcheck.checks.database = 'error';
    healthcheck.status = 'degraded';
  }

  try {
    // Kiểm tra Redis
    await redis.ping();
    healthcheck.checks.redis = 'ok';
  } catch (e) {
    healthcheck.checks.redis = 'error';
    healthcheck.status = 'degraded';
  }

  const statusCode = healthcheck.status === 'ok' ? 200 : 503;
  res.status(statusCode).json(healthcheck);
});

APM (Application Performance Monitoring)

# Cài đặt Prometheus + Grafana bằng Docker
cat > docker-compose.monitoring.yml << 'EOF'
version: '3.8'
services:
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3001:3000"
    volumes:
      - grafana_data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=secret

  node-exporter:
    image: prom/node-exporter:latest
    ports:
      - "9100:9100"

volumes:
  prometheus_data:
  grafana_data:
EOF

docker compose -f docker-compose.monitoring.yml up -d

Error tracking (Sentry)

# Cài đặt Sentry SDK
npm install @sentry/node @sentry/profiling-node
// sentry.js - Cấu hình Sentry
const Sentry = require('@sentry/node');

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV,
  tracesSampleRate: 0.1,       // 10% transactions
  profilesSampleRate: 0.1,      // 10% profiles
  integrations: [
    Sentry.httpIntegration(),
    Sentry.expressIntegration(),
    Sentry.prismaIntegration(),
  ],
});

Log aggregation

# Prompt cho Claude:
Tạo hệ thống log tập trung:
- Structured logging (JSON format)
- Log rotation
- Gửi logs đến ELK Stack hoặc Loki
# PM2 log rotation
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 30
pm2 set pm2-logrotate:compress true

# Xem logs real-time
pm2 logs my-app --lines 100

# Xem logs lỗi
pm2 logs my-app --err --lines 50

9. Zero-downtime Deployment

Blue-green deployment

# Prompt cho Claude:
Tạo script blue-green deployment:
- Chạy 2 môi trường (blue và green)
- Chuyển traffic sau khi health check thành công
- Rollback nhanh nếu có lỗi
#!/bin/bash
# blue-green-deploy.sh
set -e

CURRENT=$(readlink /home/deploy/current || echo "blue")
if [ "$CURRENT" = "blue" ]; then
  NEW="green"
else
  NEW="blue"
fi

echo "Triển khai lên môi trường: $NEW"

# Deploy phiên bản mới lên môi trường NEW
cd /home/deploy/$NEW
git pull origin main
npm ci --production
npm run build

# Khởi động môi trường mới
pm2 start ecosystem.config.js --name "app-$NEW" --env production

# Chờ và kiểm tra health
sleep 5
PORT=$([ "$NEW" = "blue" ] && echo "3001" || echo "3002")
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:$PORT/health)

if [ "$HTTP_CODE" -eq 200 ]; then
  # Chuyển Nginx sang môi trường mới
  sudo sed -i "s/127.0.0.1:300[12]/127.0.0.1:$PORT/" /etc/nginx/sites-available/my-app
  sudo nginx -t && sudo systemctl reload nginx

  # Cập nhật symlink
  ln -sfn /home/deploy/$NEW /home/deploy/current

  # Dừng môi trường cũ
  pm2 stop "app-$CURRENT" 2>/dev/null || true

  echo "Deploy thành công! Môi trường active: $NEW"
else
  pm2 stop "app-$NEW" 2>/dev/null || true
  echo "Health check thất bại. Rollback."
  exit 1
fi

Rolling update (PM2 cluster)

# PM2 rolling restart (zero-downtime khi chạy cluster mode)
pm2 reload my-app

# Reload với thời gian chờ
pm2 reload my-app --update-env --wait-ready --listen-timeout 10000

Canary deployment

# Prompt cho Claude:
Thiết lập canary deployment với Nginx:
- 10% traffic đến phiên bản mới
- 90% traffic đến phiên bản cũ
- Tăng dần nếu không có lỗi
# /etc/nginx/sites-available/my-app (canary)
upstream app_stable {
    server 127.0.0.1:3001;
}

upstream app_canary {
    server 127.0.0.1:3002;
}

# Chia traffic 90/10
split_clients "${remote_addr}" $app_version {
    90%   app_stable;
    *     app_canary;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    location / {
        proxy_pass http://$app_version;
        proxy_set_header Host $host;
        proxy_set_header X-Canary-Version $app_version;
    }
}

10. Rollback Strategies

Rollback nhanh

# Prompt cho Claude:
Tạo script rollback nhanh cho production:
- Rollback code về commit trước
- Rollback Docker image về tag trước
- Rollback database migration
#!/bin/bash
# rollback.sh - Rollback nhanh
set -e

APP_DIR="/home/deploy/app"
cd "$APP_DIR"

echo "=== ROLLBACK PRODUCTION ==="
echo "Commit hiện tại: $(git rev-parse HEAD)"

# Lấy commit trước đó
PREV_COMMIT=$(git rev-parse HEAD~1)
echo "Rollback về: $PREV_COMMIT"

# Rollback code
git checkout "$PREV_COMMIT"
npm ci --production
npm run build

# Restart ứng dụng
pm2 reload my-app

# Kiểm tra health
sleep 3
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/health)
if [ "$HTTP_CODE" -eq 200 ]; then
  echo "Rollback thành công!"
else
  echo "CẢNH BÁO: Health check thất bại sau rollback!"
  exit 1
fi
# Rollback Docker image
docker pull my-app:previous-tag
docker stop my-app
docker run -d --name my-app my-app:previous-tag

# Rollback Kubernetes
kubectl rollout undo deployment/my-app

# Xem lịch sử rollout
kubectl rollout history deployment/my-app

# Rollback về revision cụ thể
kubectl rollout undo deployment/my-app --to-revision=3

Database rollback

# Rollback migration (Prisma)
npx prisma migrate resolve --rolled-back "migration_name"

# Rollback migration (Knex)
npx knex migrate:rollback

# Rollback migration (TypeORM)
npx typeorm migration:revert

# LƯU Ý QUAN TRỌNG:
# - Luôn backup database TRƯỚC khi deploy
# - Viết migration có thể rollback (up/down)
# - Test rollback trên staging trước
# Script backup database trước khi deploy
pg_dump -h localhost -U postgres -d appdb -F c -f "backup_$(date +%Y%m%d_%H%M%S).dump"

# Restore từ backup
pg_restore -h localhost -U postgres -d appdb -c backup_20260311_100000.dump

11. Sử dụng Claude Skills

Các skill hữu ích cho deploy production:

# DevOps tổng hợp
/engineering-skills:senior-devops

# Kiến trúc AWS
/engineering-skills:aws-solution-architect

# Bảo mật hệ thống
/engineering-skills:senior-security

# Security Operations
/engineering-skills:senior-secops

# Backend performance
/engineering-skills:senior-backend

Ví dụ sử dụng skill

/engineering-skills:senior-devops

Review cấu hình deploy production của tôi:
- Nginx config tại /etc/nginx/sites-available/my-app
- PM2 ecosystem.config.js
- Dockerfile
- docker-compose.yml
Đề xuất cải thiện về performance và bảo mật.
/engineering-skills:aws-solution-architect

Thiết kế kiến trúc AWS cho ứng dụng SaaS:
- 10,000 users đồng thời
- Database PostgreSQL
- File storage (images, documents)
- Background jobs
- Real-time notifications
Budget: $500/tháng
/engineering-skills:senior-security

Kiểm tra bảo mật cho cấu hình production:
- Review Nginx headers
- Kiểm tra SSL configuration
- Audit firewall rules
- Kiểm tra environment variables
- Review Docker security

12. Các prompt mẫu deploy

Prompt 1: Deploy ứng dụng mới lên VPS

Tạo script deploy hoàn chỉnh cho ứng dụng NestJS lên VPS Ubuntu 22.04:
- Server IP: 103.xxx.xxx.xxx
- Domain: api.myapp.com
- Database: PostgreSQL (đã cài trên server)
- Bao gồm: Nginx, PM2, SSL, UFW
- Tạo CI/CD pipeline với GitHub Actions

Prompt 2: Dockerize ứng dụng

Tạo Dockerfile tối ưu cho ứng dụng Next.js:
- Multi-stage build
- Non-root user
- Health check
- Tối ưu layer caching
- .dockerignore
Kèm docker-compose.yml với PostgreSQL và Redis

Prompt 3: Setup monitoring

Thiết lập monitoring stack cho production:
- Prometheus thu thập metrics
- Grafana dashboard
- AlertManager gửi alert qua Telegram/Slack
- Node exporter cho system metrics
- Custom metrics cho ứng dụng Node.js
Tất cả chạy bằng Docker Compose

Prompt 4: Migration database an toàn

Tạo quy trình migration database an toàn cho production:
- Backup trước khi migrate
- Migration không downtime (online DDL)
- Script rollback cho mỗi migration
- Kiểm tra tương thích ngược
Sử dụng Prisma với PostgreSQL

Prompt 5: Setup CDN và caching

Cấu hình CDN và caching cho ứng dụng web:
- Cloudflare CDN setup
- Nginx cache cho static files
- Redis cache cho API responses
- Browser cache headers
- Cache invalidation strategy

Prompt 6: Kubernetes deployment

Tạo cấu hình Kubernetes hoàn chỉnh:
- Deployment với rolling update
- Service (ClusterIP + LoadBalancer)
- Ingress với TLS
- ConfigMap và Secrets
- HPA (auto-scaling)
- PersistentVolumeClaim cho database
- NetworkPolicy

Prompt 7: Serverless deployment

Chuyển đổi ứng dụng Express.js sang serverless:
- AWS Lambda + API Gateway
- Serverless Framework config
- DynamoDB thay PostgreSQL
- S3 cho file upload
- CloudWatch logs
- Ước tính chi phí cho 100K requests/ngày

Prompt 8: Multi-environment setup

Tạo cấu hình multi-environment:
- Development (local)
- Staging (giống production)
- Production
Bao gồm:
- Environment variables management
- Database per environment
- CI/CD pipeline cho mỗi environment
- Promotion flow: dev -> staging -> production

Prompt 9: Disaster recovery

Tạo kế hoạch disaster recovery cho production:
- Automated database backup (daily + hourly)
- Cross-region backup
- Recovery time objective (RTO): 30 phút
- Recovery point objective (RPO): 1 giờ
- Runbook cho từng loại sự cố
- Test recovery procedure

Prompt 10: Performance optimization

Tối ưu performance cho ứng dụng production:
- Analyze và fix slow queries (PostgreSQL)
- Redis caching strategy
- CDN configuration
- Gzip/Brotli compression
- Connection pooling
- Worker threads cho CPU-intensive tasks
Target: Response time < 200ms cho 95th percentile

Prompt 11: Security hardening

Hardening bảo mật cho server production Ubuntu:
- SSH hardening (disable root, key only, fail2ban)
- Kernel security parameters (sysctl)
- Automatic security updates
- File integrity monitoring
- Intrusion detection (AIDE/OSSEC)
- Log forwarding
- Firewall rules chi tiết

Prompt 12: Cost optimization

Tối ưu chi phí cloud cho ứng dụng đang chạy trên AWS:
- Phân tích usage hiện tại
- Reserved instances vs Spot instances
- Right-sizing instances
- S3 lifecycle policies
- CloudFront caching
- Unused resources cleanup
Budget hiện tại: $2000/tháng, target: giảm 30%

13. Checklist Deploy Production

Pre-deployment

[ ] Code đã được review và approve
[ ] Tất cả test pass (unit, integration, e2e)
[ ] Build production thành công
[ ] Dependencies audit (npm audit) - không có critical vulnerability
[ ] Environment variables đã cấu hình đầy đủ
[ ] Database migration đã test trên staging
[ ] Backup database production
[ ] Thông báo team về lịch deploy
[ ] Rollback plan đã sẵn sàng

Infrastructure

[ ] Server đã cập nhật OS và security patches
[ ] Firewall rules đã cấu hình (chỉ mở port cần thiết)
[ ] SSL certificate còn hạn (>30 ngày)
[ ] Disk space đủ (>20% free)
[ ] Memory đủ cho ứng dụng
[ ] DNS records đã cấu hình đúng
[ ] Load balancer health check hoạt động

Security

[ ] Không có secrets/credentials trong code
[ ] HTTPS enforced (redirect HTTP -> HTTPS)
[ ] Security headers đã cấu hình (HSTS, CSP, X-Frame-Options, ...)
[ ] Rate limiting đã bật
[ ] CORS đã cấu hình đúng
[ ] Input validation cho tất cả API endpoints
[ ] SQL injection protection
[ ] XSS protection
[ ] Authentication/Authorization hoạt động
[ ] Logs không chứa sensitive data

Application

[ ] Health check endpoint hoạt động (/health)
[ ] Graceful shutdown đã implement
[ ] Error handling và logging đúng
[ ] Database connection pooling
[ ] Cache strategy đã cấu hình
[ ] File upload limits đã set
[ ] Request timeout đã cấu hình
[ ] GZIP/Brotli compression bật

Monitoring

[ ] Uptime monitoring đã setup (UptimeRobot, Pingdom, ...)
[ ] Error tracking đã cấu hình (Sentry, Bugsnag, ...)
[ ] APM đã setup (Datadog, New Relic, ...)
[ ] Log aggregation hoạt động
[ ] Alert rules đã cấu hình (email, Slack, Telegram)
[ ] Dashboard monitoring đã tạo (Grafana)
[ ] Disk space alert (<10% free)
[ ] CPU/Memory alert (>90%)

Post-deployment

[ ] Health check pass
[ ] Smoke test thành công (test các luồng chính)
[ ] Response time bình thường
[ ] Error rate không tăng đột biến
[ ] Logs không có lỗi bất thường
[ ] Database connections ổn định
[ ] Thông báo team deploy thành công
[ ] Cập nhật changelog/release notes
[ ] Theo dõi metrics 30 phút sau deploy

Emergency rollback

[ ] Biết lệnh rollback (đã document)
[ ] Database backup có thể restore
[ ] Previous version image/build còn available
[ ] Team đã biết quy trình rollback
[ ] Hotline/contact list sẵn sàng

Tổng kết

Phương pháp deploy Phù hợp với Độ phức tạp Chi phí
VPS + PM2 + Nginx MVP, startup nhỏ Thấp $5-50/tháng
Docker + Docker Compose Team nhỏ-vừa Trung bình $10-100/tháng
Vercel/Railway/Render Frontend, JAMstack Rất thấp Free-$50/tháng
AWS ECS/Fargate Team vừa-lớn Cao $50-500/tháng
Kubernetes (GKE/EKS) Enterprise, scale lớn Rất cao $200-2000+/tháng
Serverless (Lambda) Event-driven, API nhẹ Trung bình Pay-per-use

Nguyên tắc vàng: Bắt đầu đơn giản (VPS hoặc PaaS), tối ưu khi cần thiết. Đừng over-engineer hạ tầng khi chưa có traffic thực tế.


Tài liệu thuộc bộ Claude Code CLI - Hướng dẫn tiếng Việt