[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71EP99QJX0P787HHP89ZFAX":3,"skill-same:01M71EP99QJX0P787HHP89ZFAX":71},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":52,"repositoryHtmlUrl":53,"repositoryHomepageUrl":6,"ownerHtmlUrl":54,"ownerBlogUrl":6,"ownerDescription":55,"updatedAt":56,"install":57,"resources":70},"01M71EP99QJX0P787HHP89ZFAX","deployment-patterns",null,"Deployment workflows, CI\u002FCD pipeline patterns, Docker containerization, health checks, rollback strategies, and production readiness checklists for web applications.","ViewWay\u002Fhermes-by-everythings","ViewWay","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F57283862?v=4","01M71ENR60K309MXA64A23SEW5","01M71ENR6QYM7NQHP29W53HSXT",3,"MIT","https:\u002F\u002Fgithub.com\u002FViewWay\u002Fhermes-by-everythings\u002Fblob\u002Fmain\u002Fskills\u002Fdeployment-patterns\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],"deployment","deployment patterns","patterns","cd","Production","rollback","web","readiness","docker containerization","health","applications","docker","for","containerization","CI\u002FCD","strategies","workflows","ci","pipeline","production readiness","2026-11-10 10:12:30",false,"---\nname: deployment-patterns\ndescription: Deployment workflows, CI\u002FCD pipeline patterns, Docker containerization, health checks, rollback strategies, and production readiness checklists for web applications.\norigin: ECC\n---\n\n# Deployment Patterns\n\nProduction deployment workflows and CI\u002FCD best practices.\n\n## When to Activate\n\n- Setting up CI\u002FCD pipelines\n- Dockerizing an application\n- Planning deployment strategy (blue-green, canary, rolling)\n- Implementing health checks and readiness probes\n- Preparing for a production release\n- Configuring environment-specific settings\n\n## Deployment Strategies\n\n### Rolling Deployment (Default)\n\nReplace instances gradually — old and new versions run simultaneously during rollout.\n\n```\nInstance 1: v1 → v2  (update first)\nInstance 2: v1        (still running v1)\nInstance 3: v1        (still running v1)\n\nInstance 1: v2\nInstance 2: v1 → v2  (update second)\nInstance 3: v1\n\nInstance 1: v2\nInstance 2: v2\nInstance 3: v1 → v2  (update last)\n```\n\n**Pros:** Zero downtime, gradual rollout\n**Cons:** Two versions run simultaneously — requires backward-compatible changes\n**Use when:** Standard deployments, backward-compatible changes\n\n### Blue-Green Deployment\n\nRun two identical environments. Switch traffic atomically.\n\n```\nBlue  (v1) ← traffic\nGreen (v2)   idle, running new version\n\n# After verification:\nBlue  (v1)   idle (becomes standby)\nGreen (v2) ← traffic\n```\n\n**Pros:** Instant rollback (switch back to blue), clean cutover\n**Cons:** Requires 2x infrastructure during deployment\n**Use when:** Critical services, zero-tolerance for issues\n\n### Canary Deployment\n\nRoute a small percentage of traffic to the new version first.\n\n```\nv1: 95% of traffic\nv2:  5% of traffic  (canary)\n\n# If metrics look good:\nv1: 50% of traffic\nv2: 50% of traffic\n\n# Final:\nv2: 100% of traffic\n```\n\n**Pros:** Catches issues with real traffic before full rollout\n**Cons:** Requires traffic splitting infrastructure, monitoring\n**Use when:** High-traffic services, risky changes, feature flags\n\n## Docker\n\n### Multi-Stage Dockerfile (Node.js)\n\n```dockerfile\n# Stage 1: Install dependencies\nFROM node:22-alpine AS deps\nWORKDIR \u002Fapp\nCOPY package.json package-lock.json .\u002F\nRUN npm ci --production=false\n\n# Stage 2: Build\nFROM node:22-alpine AS builder\nWORKDIR \u002Fapp\nCOPY --from=deps \u002Fapp\u002Fnode_modules .\u002Fnode_modules\nCOPY . .\nRUN npm run build\nRUN npm prune --production\n\n# Stage 3: Production image\nFROM node:22-alpine AS runner\nWORKDIR \u002Fapp\n\nRUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001\nUSER appuser\n\nCOPY --from=builder --chown=appuser:appgroup \u002Fapp\u002Fnode_modules .\u002Fnode_modules\nCOPY --from=builder --chown=appuser:appgroup \u002Fapp\u002Fdist .\u002Fdist\nCOPY --from=builder --chown=appuser:appgroup \u002Fapp\u002Fpackage.json .\u002F\n\nENV NODE_ENV=production\nEXPOSE 3000\n\nHEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\\n  CMD wget --no-verbose --tries=1 --spider http:\u002F\u002Flocalhost:3000\u002Fhealth || exit 1\n\nCMD [\"node\", \"dist\u002Fserver.js\"]\n```\n\n### Multi-Stage Dockerfile (Go)\n\n```dockerfile\nFROM golang:1.22-alpine AS builder\nWORKDIR \u002Fapp\nCOPY go.mod go.sum .\u002F\nRUN go mod download\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o \u002Fserver .\u002Fcmd\u002Fserver\n\nFROM alpine:3.19 AS runner\nRUN apk --no-cache add ca-certificates\nRUN adduser -D -u 1001 appuser\nUSER appuser\n\nCOPY --from=builder \u002Fserver \u002Fserver\n\nEXPOSE 8080\nHEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http:\u002F\u002Flocalhost:8080\u002Fhealth || exit 1\nCMD [\"\u002Fserver\"]\n```\n\n### Multi-Stage Dockerfile (Python\u002FDjango)\n\n```dockerfile\nFROM python:3.12-slim AS builder\nWORKDIR \u002Fapp\nRUN pip install --no-cache-dir uv\nCOPY requirements.txt .\nRUN uv pip install --system --no-cache -r requirements.txt\n\nFROM python:3.12-slim AS runner\nWORKDIR \u002Fapp\n\nRUN useradd -r -u 1001 appuser\nUSER appuser\n\nCOPY --from=builder \u002Fusr\u002Flocal\u002Flib\u002Fpython3.12\u002Fsite-packages \u002Fusr\u002Flocal\u002Flib\u002Fpython3.12\u002Fsite-packages\nCOPY --from=builder \u002Fusr\u002Flocal\u002Fbin \u002Fusr\u002Flocal\u002Fbin\nCOPY . .\n\nENV PYTHONUNBUFFERED=1\nEXPOSE 8000\n\nHEALTHCHECK --interval=30s --timeout=3s CMD python -c \"import urllib.request; urllib.request.urlopen('http:\u002F\u002Flocalhost:8000\u002Fhealth\u002F')\" || exit 1\nCMD [\"gunicorn\", \"config.wsgi:application\", \"--bind\", \"0.0.0.0:8000\", \"--workers\", \"4\"]\n```\n\n### Docker Best Practices\n\n```\n# GOOD practices\n- Use specific version tags (node:22-alpine, not node:latest)\n- Multi-stage builds to minimize image size\n- Run as non-root user\n- Copy dependency files first (layer caching)\n- Use .dockerignore to exclude node_modules, .git, tests\n- Add HEALTHCHECK instruction\n- Set resource limits in docker-compose or k8s\n\n# BAD practices\n- Running as root\n- Using :latest tags\n- Copying entire repo in one COPY layer\n- Installing dev dependencies in production image\n- Storing secrets in image (use env vars or secrets manager)\n```\n\n## CI\u002FCD Pipeline\n\n### GitHub Actions (Standard Pipeline)\n\n```yaml\nname: CI\u002FCD\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - uses: actions\u002Fsetup-node@v4\n        with:\n          node-version: 22\n          cache: npm\n      - run: npm ci\n      - run: npm run lint\n      - run: npm run typecheck\n      - run: npm test -- --coverage\n      - uses: actions\u002Fupload-artifact@v4\n        if: always()\n        with:\n          name: coverage\n          path: coverage\u002F\n\n  build:\n    needs: test\n    runs-on: ubuntu-latest\n    if: github.ref == 'refs\u002Fheads\u002Fmain'\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - uses: docker\u002Fsetup-buildx-action@v3\n      - uses: docker\u002Flogin-action@v3\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n      - uses: docker\u002Fbuild-push-action@v5\n        with:\n          push: true\n          tags: ghcr.io\u002F${{ github.repository }}:${{ github.sha }}\n          cache-from: type=gha\n          cache-to: type=gha,mode=max\n\n  deploy:\n    needs: build\n    runs-on: ubuntu-latest\n    if: github.ref == 'refs\u002Fheads\u002Fmain'\n    environment: production\n    steps:\n      - name: Deploy to production\n        run: |\n          # Platform-specific deployment command\n          # Railway: railway up\n          # Vercel: vercel --prod\n          # K8s: kubectl set image deployment\u002Fapp app=ghcr.io\u002F${{ github.repository }}:${{ github.sha }}\n          echo \"Deploying ${{ github.sha }}\"\n```\n\n### Pipeline Stages\n\n```\nPR opened:\n  lint → typecheck → unit tests → integration tests → preview deploy\n\nMerged to main:\n  lint → typecheck → unit tests → integration tests → build image → deploy staging → smoke tests → deploy production\n```\n\n## Health Checks\n\n### Health Check Endpoint\n\n```typescript\n\u002F\u002F Simple health check\napp.get(\"\u002Fhealth\", (req, res) => {\n  res.status(200).json({ status: \"ok\" });\n});\n\n\u002F\u002F Detailed health check (for internal monitoring)\napp.get(\"\u002Fhealth\u002Fdetailed\", async (req, res) => {\n  const checks = {\n    database: await checkDatabase(),\n    redis: await checkRedis(),\n    externalApi: await checkExternalApi(),\n  };\n\n  const allHealthy = Object.values(checks).every(c => c.status === \"ok\");\n\n  res.status(allHealthy ? 200 : 503).json({\n    status: allHealthy ? \"ok\" : \"degraded\",\n    timestamp: new Date().toISOString(),\n    version: process.env.APP_VERSION || \"unknown\",\n    uptime: process.uptime(),\n    checks,\n  });\n});\n\nasync function checkDatabase(): Promise\u003CHealthCheck> {\n  try {\n    await db.query(\"SELECT 1\");\n    return { status: \"ok\", latency_ms: 2 };\n  } catch (err) {\n    return { status: \"error\", message: \"Database unreachable\" };\n  }\n}\n```\n\n### Kubernetes Probes\n\n```yaml\nlivenessProbe:\n  httpGet:\n    path: \u002Fhealth\n    port: 3000\n  initialDelaySeconds: 10\n  periodSeconds: 30\n  failureThreshold: 3\n\nreadinessProbe:\n  httpGet:\n    path: \u002Fhealth\n    port: 3000\n  initialDelaySeconds: 5\n  periodSeconds: 10\n  failureThreshold: 2\n\nstartupProbe:\n  httpGet:\n    path: \u002Fhealth\n    port: 3000\n  initialDelaySeconds: 0\n  periodSeconds: 5\n  failureThreshold: 30    # 30 * 5s = 150s max startup time\n```\n\n## Environment Configuration\n\n### Twelve-Factor App Pattern\n\n```bash\n# All config via environment variables — never in code\nDATABASE_URL=postgres:\u002F\u002Fuser:pass@host:5432\u002Fdb\nREDIS_URL=redis:\u002F\u002Fhost:6379\u002F0\nAPI_KEY=${API_KEY}           # injected by secrets manager\nLOG_LEVEL=info\nPORT=3000\n\n# Environment-specific behavior\nNODE_ENV=production          # or staging, development\nAPP_ENV=production           # explicit app environment\n```\n\n### Configuration Validation\n\n```typescript\nimport { z } from \"zod\";\n\nconst envSchema = z.object({\n  NODE_ENV: z.enum([\"development\", \"staging\", \"production\"]),\n  PORT: z.coerce.number().default(3000),\n  DATABASE_URL: z.string().url(),\n  REDIS_URL: z.string().url(),\n  JWT_SECRET: z.string().min(32),\n  LOG_LEVEL: z.enum([\"debug\", \"info\", \"warn\", \"error\"]).default(\"info\"),\n});\n\n\u002F\u002F Validate at startup — fail fast if config is wrong\nexport const env = envSchema.parse(process.env);\n```\n\n## Rollback Strategy\n\n### Instant Rollback\n\n```bash\n# Docker\u002FKubernetes: point to previous image\nkubectl rollout undo deployment\u002Fapp\n\n# Vercel: promote previous deployment\nvercel rollback\n\n# Railway: redeploy previous commit\nrailway up --commit \u003Cprevious-sha>\n\n# Database: rollback migration (if reversible)\nnpx prisma migrate resolve --rolled-back \u003Cmigration-name>\n```\n\n### Rollback Checklist\n\n- [ ] Previous image\u002Fartifact is available and tagged\n- [ ] Database migrations are backward-compatible (no destructive changes)\n- [ ] Feature flags can disable new features without deploy\n- [ ] Monitoring alerts configured for error rate spikes\n- [ ] Rollback tested in staging before production release\n\n## Production Readiness Checklist\n\nBefore any production deployment:\n\n### Application\n- [ ] All tests pass (unit, integration, E2E)\n- [ ] No hardcoded secrets in code or config files\n- [ ] Error handling covers all edge cases\n- [ ] Logging is structured (JSON) and does not contain PII\n- [ ] Health check endpoint returns meaningful status\n\n### Infrastructure\n- [ ] Docker image builds reproducibly (pinned versions)\n- [ ] Environment variables documented and validated at startup\n- [ ] Resource limits set (CPU, memory)\n- [ ] Horizontal scaling configured (min\u002Fmax instances)\n- [ ] SSL\u002FTLS enabled on all endpoints\n\n### Monitoring\n- [ ] Application metrics exported (request rate, latency, errors)\n- [ ] Alerts configured for error rate > threshold\n- [ ] Log aggregation set up (structured logs, searchable)\n- [ ] Uptime monitoring on health endpoint\n\n### Security\n- [ ] Dependencies scanned for CVEs\n- [ ] CORS configured for allowed origins only\n- [ ] Rate limiting enabled on public endpoints\n- [ ] Authentication and authorization verified\n- [ ] Security headers set (CSP, HSTS, X-Frame-Options)\n\n### Operations\n- [ ] Rollback plan documented and tested\n- [ ] Database migration tested against production-sized data\n- [ ] Runbook for common failure scenarios\n- [ ] On-call rotation and escalation path defined\n","# Deployment Patterns\n\nProduction deployment workflows and CI\u002FCD best practices.\n\n## When to Activate\n\n- Setting up CI\u002FCD pipelines\n- Dockerizing an application\n- Planning deployment strategy (blue-green, canary, rolling)\n- Implementing health checks and readiness probes\n- Preparing for a production release\n- Configuring environment-specific settings\n\n## Deployment Strategies\n\n### Rolling Deployment (Default)\n\nReplace instances gradually — old and new versions run simultaneously during rollout.\n\n```\nInstance 1: v1 → v2  (update first)\nInstance 2: v1        (still running v1)\nInstance 3: v1        (still running v1)\n\nInstance 1: v2\nInstance 2: v1 → v2  (update second)\nInstance 3: v1\n\nInstance 1: v2\nInstance 2: v2\nInstance 3: v1 → v2  (update last)\n```\n\n**Pros:** Zero downtime, gradual rollout\n**Cons:** Two versions run simultaneously — requires backward-compatible changes\n**Use when:** Standard deployments, backward-compatible changes\n\n### Blue-Green Deployment\n\nRun two identical environments. Switch traffic atomically.\n\n```\nBlue  (v1) ← traffic\nGreen (v2)   idle, running new version\n\n# After verification:\nBlue  (v1)   idle (becomes standby)\nGreen (v2) ← traffic\n```\n\n**Pros:** Instant rollback (switch back to blue), clean cutover\n**Cons:** Requires 2x infrastructure during deployment\n**Use when:** Critical services, zero-tolerance for issues\n\n### Canary Deployment\n\nRoute a small percentage of traffic to the new version first.\n\n```\nv1: 95% of traffic\nv2:  5% of traffic  (canary)\n\n# If metrics look good:\nv1: 50% of traffic\nv2: 50% of traffic\n\n# Final:\nv2: 100% of traffic\n```\n\n**Pros:** Catches issues with real traffic before full rollout\n**Cons:** Requires traffic splitting infrastructure, monitoring\n**Use when:** High-traffic services, risky changes, feature flags\n\n## Docker\n\n### Multi-Stage Dockerfile (Node.js)\n\n```dockerfile\n# Stage 1: Install dependencies\nFROM node:22-alpine AS deps\nWORKDIR \u002Fapp\nCOPY package.json package-lock.json .\u002F\nRUN npm ci --production=false\n\n# Stage 2: Build\nFROM node:22-alpine AS builder\nWORKDIR \u002Fapp\nCOPY --from=deps \u002Fapp\u002Fnode_modules .\u002Fnode_modules\nCOPY . .\nRUN npm run build\nRUN npm prune --production\n\n# Stage 3: Production image\nFROM node:22-alpine AS runner\nWORKDIR \u002Fapp\n\nRUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001\nUSER appuser\n\nCOPY --from=builder --chown=appuser:appgroup \u002Fapp\u002Fnode_modules .\u002Fnode_modules\nCOPY --from=builder --chown=appuser:appgroup \u002Fapp\u002Fdist .\u002Fdist\nCOPY --from=builder --chown=appuser:appgroup \u002Fapp\u002Fpackage.json .\u002F\n\nENV NODE_ENV=production\nEXPOSE 3000\n\nHEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\\n  CMD wget --no-verbose --tries=1 --spider http:\u002F\u002Flocalhost:3000\u002Fhealth || exit 1\n\nCMD [\"node\", \"dist\u002Fserver.js\"]\n```\n\n### Multi-Stage Dockerfile (Go)\n\n```dockerfile\nFROM golang:1.22-alpine AS builder\nWORKDIR \u002Fapp\nCOPY go.mod go.sum .\u002F\nRUN go mod download\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o \u002Fserver .\u002Fcmd\u002Fserver\n\nFROM alpine:3.19 AS runner\nRUN apk --no-cache add ca-certificates\nRUN adduser -D -u 1001 appuser\nUSER appuser\n\nCOPY --from=builder \u002Fserver \u002Fserver\n\nEXPOSE 8080\nHEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http:\u002F\u002Flocalhost:8080\u002Fhealth || exit 1\nCMD [\"\u002Fserver\"]\n```\n\n### Multi-Stage Dockerfile (Python\u002FDjango)\n\n```dockerfile\nFROM python:3.12-slim AS builder\nWORKDIR \u002Fapp\nRUN pip install --no-cache-dir uv\nCOPY requirements.txt .\nRUN uv pip install --system --no-cache -r requirements.txt\n\nFROM python:3.12-slim AS runner\nWORKDIR \u002Fapp\n\nRUN useradd -r -u 1001 appuser\nUSER appuser\n\nCOPY --from=builder \u002Fusr\u002Flocal\u002Flib\u002Fpython3.12\u002Fsite-packages \u002Fusr\u002Flocal\u002Flib\u002Fpython3.12\u002Fsite-packages\nCOPY --from=builder \u002Fusr\u002Flocal\u002Fbin \u002Fusr\u002Flocal\u002Fbin\nCOPY . .\n\nENV PYTHONUNBUFFERED=1\nEXPOSE 8000\n\nHEALTHCHECK --interval=30s --timeout=3s CMD python -c \"import urllib.request; urllib.request.urlopen('http:\u002F\u002Flocalhost:8000\u002Fhealth\u002F')\" || exit 1\nCMD [\"gunicorn\", \"config.wsgi:application\", \"--bind\", \"0.0.0.0:8000\", \"--workers\", \"4\"]\n```\n\n### Docker Best Practices\n\n```\n# GOOD practices\n- Use specific version tags (node:22-alpine, not node:latest)\n- Multi-stage builds to minimize image size\n- Run as non-root user\n- Copy dependency files first (layer caching)\n- Use .dockerignore to exclude node_modules, .git, tests\n- Add HEALTHCHECK instruction\n- Set resource limits in docker-compose or k8s\n\n# BAD practices\n- Running as root\n- Using :latest tags\n- Copying entire repo in one COPY layer\n- Installing dev dependencies in production image\n- Storing secrets in image (use env vars or secrets manager)\n```\n\n## CI\u002FCD Pipeline\n\n### GitHub Actions (Standard Pipeline)\n\n```yaml\nname: CI\u002FCD\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - uses: actions\u002Fsetup-node@v4\n        with:\n          node-version: 22\n          cache: npm\n      - run: npm ci\n      - run: npm run lint\n      - run: npm run typecheck\n      - run: npm test -- --coverage\n      - uses: actions\u002Fupload-artifact@v4\n        if: always()\n        with:\n          name: coverage\n          path: coverage\u002F\n\n  build:\n    needs: test\n    runs-on: ubuntu-latest\n    if: github.ref == 'refs\u002Fheads\u002Fmain'\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - uses: docker\u002Fsetup-buildx-action@v3\n      - uses: docker\u002Flogin-action@v3\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n      - uses: docker\u002Fbuild-push-action@v5\n        with:\n          push: true\n          tags: ghcr.io\u002F${{ github.repository }}:${{ github.sha }}\n          cache-from: type=gha\n          cache-to: type=gha,mode=max\n\n  deploy:\n    needs: build\n    runs-on: ubuntu-latest\n    if: github.ref == 'refs\u002Fheads\u002Fmain'\n    environment: production\n    steps:\n      - name: Deploy to production\n        run: |\n          # Platform-specific deployment command\n          # Railway: railway up\n          # Vercel: vercel --prod\n          # K8s: kubectl set image deployment\u002Fapp app=ghcr.io\u002F${{ github.repository }}:${{ github.sha }}\n          echo \"Deploying ${{ github.sha }}\"\n```\n\n### Pipeline Stages\n\n```\nPR opened:\n  lint → typecheck → unit tests → integration tests → preview deploy\n\nMerged to main:\n  lint → typecheck → unit tests → integration tests → build image → deploy staging → smoke tests → deploy production\n```\n\n## Health Checks\n\n### Health Check Endpoint\n\n```typescript\n\u002F\u002F Simple health check\napp.get(\"\u002Fhealth\", (req, res) => {\n  res.status(200).json({ status: \"ok\" });\n});\n\n\u002F\u002F Detailed health check (for internal monitoring)\napp.get(\"\u002Fhealth\u002Fdetailed\", async (req, res) => {\n  const checks = {\n    database: await checkDatabase(),\n    redis: await checkRedis(),\n    externalApi: await checkExternalApi(),\n  };\n\n  const allHealthy = Object.values(checks).every(c => c.status === \"ok\");\n\n  res.status(allHealthy ? 200 : 503).json({\n    status: allHealthy ? \"ok\" : \"degraded\",\n    timestamp: new Date().toISOString(),\n    version: process.env.APP_VERSION || \"unknown\",\n    uptime: process.uptime(),\n    checks,\n  });\n});\n\nasync function checkDatabase(): Promise\u003CHealthCheck> {\n  try {\n    await db.query(\"SELECT 1\");\n    return { status: \"ok\", latency_ms: 2 };\n  } catch (err) {\n    return { status: \"error\", message: \"Database unreachable\" };\n  }\n}\n```\n\n### Kubernetes Probes\n\n```yaml\nlivenessProbe:\n  httpGet:\n    path: \u002Fhealth\n    port: 3000\n  initialDelaySeconds: 10\n  periodSeconds: 30\n  failureThreshold: 3\n\nreadinessProbe:\n  httpGet:\n    path: \u002Fhealth\n    port: 3000\n  initialDelaySeconds: 5\n  periodSeconds: 10\n  failureThreshold: 2\n\nstartupProbe:\n  httpGet:\n    path: \u002Fhealth\n    port: 3000\n  initialDelaySeconds: 0\n  periodSeconds: 5\n  failureThreshold: 30    # 30 * 5s = 150s max startup time\n```\n\n## Environment Configuration\n\n### Twelve-Factor App Pattern\n\n```bash\n# All config via environment variables — never in code\nDATABASE_URL=postgres:\u002F\u002Fuser:pass@host:5432\u002Fdb\nREDIS_URL=redis:\u002F\u002Fhost:6379\u002F0\nAPI_KEY=${API_KEY}           # injected by secrets manager\nLOG_LEVEL=info\nPORT=3000\n\n# Environment-specific behavior\nNODE_ENV=production          # or staging, development\nAPP_ENV=production           # explicit app environment\n```\n\n### Configuration Validation\n\n```typescript\nimport { z } from \"zod\";\n\nconst envSchema = z.object({\n  NODE_ENV: z.enum([\"development\", \"staging\", \"production\"]),\n  PORT: z.coerce.number().default(3000),\n  DATABASE_URL: z.string().url(),\n  REDIS_URL: z.string().url(),\n  JWT_SECRET: z.string().min(32),\n  LOG_LEVEL: z.enum([\"debug\", \"info\", \"warn\", \"error\"]).default(\"info\"),\n});\n\n\u002F\u002F Validate at startup — fail fast if config is wrong\nexport const env = envSchema.parse(process.env);\n```\n\n## Rollback Strategy\n\n### Instant Rollback\n\n```bash\n# Docker\u002FKubernetes: point to previous image\nkubectl rollout undo deployment\u002Fapp\n\n# Vercel: promote previous deployment\nvercel rollback\n\n# Railway: redeploy previous commit\nrailway up --commit \u003Cprevious-sha>\n\n# Database: rollback migration (if reversible)\nnpx prisma migrate resolve --rolled-back \u003Cmigration-name>\n```\n\n### Rollback Checklist\n\n- [ ] Previous image\u002Fartifact is available and tagged\n- [ ] Database migrations are backward-compatible (no destructive changes)\n- [ ] Feature flags can disable new features without deploy\n- [ ] Monitoring alerts configured for error rate spikes\n- [ ] Rollback tested in staging before production release\n\n## Production Readiness Checklist\n\nBefore any production deployment:\n\n### Application\n- [ ] All tests pass (unit, integration, E2E)\n- [ ] No hardcoded secrets in code or config files\n- [ ] Error handling covers all edge cases\n- [ ] Logging is structured (JSON) and does not contain PII\n- [ ] Health check endpoint returns meaningful status\n\n### Infrastructure\n- [ ] Docker image builds reproducibly (pinned versions)\n- [ ] Environment variables documented and validated at startup\n- [ ] Resource limits set (CPU, memory)\n- [ ] Horizontal scaling configured (min\u002Fmax instances)\n- [ ] SSL\u002FTLS enabled on all endpoints\n\n### Monitoring\n- [ ] Application metrics exported (request rate, latency, errors)\n- [ ] Alerts configured for error rate > threshold\n- [ ] Log aggregation set up (structured logs, searchable)\n- [ ] Uptime monitoring on health endpoint\n\n### Security\n- [ ] Dependencies scanned for CVEs\n- [ ] CORS configured for allowed origins only\n- [ ] Rate limiting enabled on public endpoints\n- [ ] Authentication and authorization verified\n- [ ] Security headers set (CSP, HSTS, X-Frame-Options)\n\n### Operations\n- [ ] Rollback plan documented and tested\n- [ ] Database migration tested against production-sized data\n- [ ] Runbook for common failure scenarios\n- [ ] On-call rotation and escalation path defined\n",{"name":5,"origin":48,"description":7},"ECC","main","0446e11613ad1942de249b12f7deea3889c25af4","skills\u002Fdeployment-patterns",0,"https:\u002F\u002Fgithub.com\u002FViewWay\u002Fhermes-by-everythings","https:\u002F\u002Fgithub.com\u002FViewWay","rust can do everything","2026-06-19 23:27:05",{"source":8,"skillName":5,"commands":58,"prompt":68,"zipAvailable":69},[59,62,65],{"tool":60,"command":61},"npx","npx skills add ViewWay\u002Fhermes-by-everythings --skill deployment-patterns",{"tool":63,"command":64},"bunx","bunx skills add ViewWay\u002Fhermes-by-everythings --skill deployment-patterns",{"tool":66,"command":67},"pnpm","pnpm dlx skills add ViewWay\u002Fhermes-by-everythings --skill deployment-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FViewWay\u002Fhermes-by-everythings\u002Fblob\u002Fmain\u002Fskills\u002Fdeployment-patterns\u002FSKILL.md",true,[],[72,109,135,160,191,212],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":89,"publishedAt":43},"01M71EREGWXCCGBGDZ969RZQA7","ui-ux-pro-max","UI\u002FUX design intelligence and implementation guidance for building polished interfaces. Use when the user asks for UI design, UX flows, information architecture, visual style direction, design systems\u002Ftokens, component specs, copy\u002Fmicrocopy, accessibility, or to generate\u002Fcritique\u002Frefine frontend UI (HTML\u002FCSS\u002FJS, React, Next.js, Vue, Svelte, Tailwind). Includes workflows for (1) generating new UI layouts and styling, (2) improving existing UI\u002FUX, (3) producing design-system tokens and component guidelines, and (4) turning UX recommendations into concrete code changes.","https:\u002F\u002Fgithub.com\u002FViewWay\u002Fhermes-by-everythings\u002Fblob\u002Fmain\u002Fskills\u002Fui-ux-pro-max\u002FSKILL.md",[78,81,84],{"categoryNo":79,"categoryName":80,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":82,"categoryName":83,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":85,"categoryName":86,"taxonomyType":87,"taxonomyTypeDesc":88},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,39,108],"ux","max","ui ux","ui","ui ux pro max","pro","information architecture","css","microcopy","direction","Tailwind","flows","frontend","design","new","svelte","design systems","information","when",{"skillNo":110,"name":111,"nameZh":6,"description":112,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":113,"categories":114,"keywords":115,"publishedAt":43},"01M71ERBY797MAY4HTFMSHPXMY","springboot-verification","Verification loop for Spring Boot projects: build, static analysis, tests with coverage, security scans, and diff review before release or PR.","https:\u002F\u002Fgithub.com\u002FViewWay\u002Fhermes-by-everythings\u002Fblob\u002Fmain\u002Fskills\u002Fspringboot-verification\u002FSKILL.md",[],[116,117,118,119,120,121,122,35,123,124,125,126,127,128,129,130,131,132,133,134],"springboot verification","verification","coverage","projects","verification loop","pr","diff","static","tests","spring boot","diff review","spring","loop","boot","analysis","review","with","build","release",{"skillNo":136,"name":137,"nameZh":6,"description":138,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":144,"publishedAt":43},"01M71ER9TQGK9Y00JEEM6RW9RY","springboot-patterns","Spring Boot architecture patterns, REST API design, layered services, data access, caching, async processing, and logging. Use for Java Spring Boot backend work.","https:\u002F\u002Fgithub.com\u002FViewWay\u002Fhermes-by-everythings\u002Fblob\u002Fmain\u002Fskills\u002Fspringboot-patterns\u002FSKILL.md",[141],{"categoryNo":142,"categoryName":143,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口",[25,145,146,147,125,103,148,149,150,151,152,153,154,155,156,35,157,158,159,127],"springboot patterns","processing","rest api design","access","caching","architecture","api","spring boot architecture","work","data","architecture patterns","logging","async","java spring","use",{"skillNo":161,"name":162,"nameZh":6,"description":163,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":164,"categories":165,"keywords":173,"publishedAt":43},"01M71ER6XTWDJ0NVE5RFY28RE7","security-auditor","Use when reviewing code for security vulnerabilities, implementing authentication flows, auditing OWASP Top 10, configuring CORS\u002FCSP headers, handling secrets, input validation, SQL injection prevention, XSS protection, or any security-related code review.","https:\u002F\u002Fgithub.com\u002FViewWay\u002Fhermes-by-everythings\u002Fblob\u002Fmain\u002Fskills\u002Fsecurity-auditor\u002FSKILL.md",[166,169,170],{"categoryNo":167,"categoryName":168,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":142,"categoryName":143,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":171,"categoryName":172,"taxonomyType":87,"taxonomyTypeDesc":88},"01JBSEEDCAT000000000000033","数据分析师",[174,175,176,177,178,101,179,180,181,108,182,183,184,185,131,186,187,188,189,190],"security","security auditor","auditor","authentication","code review","implementing","csrf","Input Validation","encryption","code","vulnerability","xss","top","owasp top 10","audit","sql","secrets",{"skillNo":192,"name":193,"nameZh":6,"description":194,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":195,"categories":196,"keywords":200,"publishedAt":43},"01M71ER4PHRJ1EKXQTQPEPYQ6J","rust-testing","Rust testing patterns including unit tests, integration tests, async testing, property-based testing, mocking, and coverage. Follows TDD methodology.","https:\u002F\u002Fgithub.com\u002FViewWay\u002Fhermes-by-everythings\u002Fblob\u002Fmain\u002Fskills\u002Frust-testing\u002FSKILL.md",[197],{"categoryNo":198,"categoryName":199,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量",[201,202,203,118,204,205,25,206,157,207,124,208,209,210,211],"rust","testing","rust testing","unit","testing patterns","integration tests","mocking","unit tests","tdd","integration","methodology",{"skillNo":213,"name":214,"nameZh":6,"description":215,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":216,"categories":217,"keywords":218,"publishedAt":43},"01M71ER0XW3N4K7YTQSXXWW3M3","rust-patterns","Idiomatic Rust patterns, ownership, error handling, traits, concurrency, and best practices for building safe, performant applications.","https:\u002F\u002Fgithub.com\u002FViewWay\u002Fhermes-by-everythings\u002Fblob\u002Fmain\u002Fskills\u002Frust-patterns\u002FSKILL.md",[],[201,25,219,220,221,222,223,224,35,33,225,226,227],"rust patterns","error","traits","concurrency","safe","idiomatic","best practices","error handling","ownership"]