Tier: POWERFUL
Category: Engineering
Domain: DevOps / Site Reliability Engineering
Analyze a codebase and generate production-grade operational runbooks. Detects your stack (CI/CD, database, hosting, containers), then produces step-by-step runbooks with copy-paste commands, verification checks, rollback procedures, escalation paths, and time estimates. Keeps runbooks fresh with staleness detection linked to config file modification dates.
Use when:
Skip when:
When given a repo, scan for these signals before writing a single runbook line:
# CI/CD
ls .github/workflows/ → GitHub Actions
ls .gitlab-ci.yml → GitLab CI
ls Jenkinsfile → Jenkins
ls .circleci/ → CircleCI
ls bitbucket-pipelines.yml → Bitbucket Pipelines
# Database
grep -r "postgresql\|postgres\|pg" package.json pyproject.toml → PostgreSQL
grep -r "mysql\|mariadb" package.json → MySQL
grep -r "mongodb\|mongoose" package.json → MongoDB
grep -r "redis" package.json → Redis
ls prisma/schema.prisma → Prisma ORM (check provider field)
ls drizzle.config.* → Drizzle ORM
# Hosting
ls vercel.json → Vercel
ls railway.toml → Railway
ls fly.toml → Fly.io
ls .ebextensions/ → AWS Elastic Beanstalk
ls terraform/ ls *.tf → Custom AWS/GCP/Azure (check provider)
ls kubernetes/ ls k8s/ → Kubernetes
ls docker-compose.yml → Docker Compose
# Framework
ls next.config.* → Next.js
ls nuxt.config.* → Nuxt
ls svelte.config.* → SvelteKit
cat package.json | jq '.scripts' → Check build/start commands
Map detected stack → runbook templates. A Next.js + PostgreSQL + Vercel + GitHub Actions repo needs:
# Deployment Runbook — [App Name]
**Stack:** Next.js 14 + PostgreSQL 15 + Vercel
**Last verified:** 2025-03-01
**Source configs:** vercel.json (modified: git log -1 --format=%ci -- vercel.json)
**Owner:** Platform Team
**Est. total time:** 15–25 min
---
## Pre-deployment Checklist
- [ ] All PRs merged to main
- [ ] CI passing on main (GitHub Actions green)
- [ ] Database migrations tested in staging
- [ ] Rollback plan confirmed
## Steps
### Step 1 — Run CI checks locally (3 min)
pnpm test
pnpm lint
pnpm build
✅ Expected: All pass with 0 errors. Build output in `.next/`
### Step 2 — Apply database migrations (5 min)
DATABASE_URL=$STAGING_DATABASE_URL npx prisma migrate deploy
✅ Expected: `All migrations have been successfully applied.`
psql $STAGING_DATABASE_URL -c "\d" | grep -i migration
✅ Expected: Migration table shows new entry with today's date
### Step 3 — Deploy to production (5 min)
git push origin main
vercel --prod
✅ Expected: Vercel dashboard shows deployment in progress. URL format:
`https://app-name-<hash>-team.vercel.app`
### Step 4 — Smoke test production (5 min)
curl -sf https://your-app.vercel.app/api/health | jq .
curl -sf https://your-app.vercel.app/api/users/me \
-H "Authorization: Bearer $TEST_TOKEN" | jq '.id'
✅ Expected: health returns `{"status":"ok","db":"connected"}`. Users API returns valid ID.
### Step 5 — Monitor for 10 min
- Check Vercel Functions log for errors: `vercel logs --since=10m`
- Check error rate in Vercel Analytics: < 1% 5xx
- Check DB connection pool: `SELECT count(*) FROM pg_stat_activity;` (< 80% of max_connections)
---
## Rollback
If smoke tests fail or error rate spikes:
vercel rollback [previous-deployment-url]
DATABASE_URL=$PROD_DATABASE_URL npx prisma migrate reset --skip-seed
✅ Expected after rollback: Previous deployment URL becomes active. Verify with smoke test.
---
## Escalation
- **L1 (on-call engineer):** Check Vercel logs, run smoke tests, attempt rollback
- **L2 (platform lead):** DB issues, data loss risk, rollback failed — Slack: @platform-lead
- **L3 (CTO):** Production down > 30 min, data breach — PagerDuty: #critical-incidents
# Incident Response Runbook
**Severity levels:** P1 (down), P2 (degraded), P3 (minor)
**Est. total time:** P1: 30–60 min, P2: 1–4 hours
## Phase 1 — Triage (5 min)
### Confirm the incident
curl -sw "%{http_code}" https://your-app.vercel.app/api/health -o /dev/null
vercel logs --since=15m | grep -i "error\|exception\|5[0-9][0-9]"
✅ 200 = app up. 5xx or timeout = incident confirmed.
Declare severity:
- Site completely down → P1 — page L2/L3 immediately
- Partial degradation / slow responses → P2 — notify team channel
- Single feature broken → P3 — create ticket, fix in business hours
---
## Phase 2 — Diagnose (10–15 min)
vercel ls --limit=5
psql $DATABASE_URL -c "SELECT pid, state, wait_event, query FROM pg_stat_activity WHERE state != 'idle' LIMIT 20;"
psql $DATABASE_URL -c "SELECT pid, now() - pg_stat_activity.query_start AS duration, query FROM pg_stat_activity WHERE state = 'active' AND now() - pg_stat_activity.query_start > interval '30 seconds';"
psql $DATABASE_URL -c "SELECT count(*), max_conn FROM pg_stat_activity, (SELECT setting::int AS max_conn FROM pg_settings WHERE name='max_connections') t GROUP BY max_conn;"
Diagnostic decision tree:
- Recent deploy + new errors → rollback (see Deployment Runbook)
- DB query timeout / pool saturation → kill long queries, scale connections
- External dependency failing → check status pages, add circuit breaker
- Memory/CPU spike → check Vercel function logs for infinite loops
---
## Phase 3 — Mitigate (variable)
psql $DATABASE_URL -c "SELECT pg_terminate_backend(
vercel env add MAINTENANCE_MODE true production
vercel --prod # redeploy with flag
---
## Phase 4 — Resolve & Postmortem
After incident is resolved, within 24 hours:
1. Write incident timeline (what happened, when, who noticed, what fixed it)
2. Identify root cause (5-Whys)
3. Define action items with owners and due dates
4. Update this runbook if a step was missing or wrong
5. Add monitoring/alert that would have caught this earlier
**Postmortem template:** `docs/postmortems/YYYY-MM-DD-incident-title.md`
---
## Escalation Path
| Level | Who | When | Contact |
|-------|-----|------|---------|
| L1 | On-call engineer | Always first | PagerDuty rotation |
| L2 | Platform lead | DB issues, rollback needed | Slack @platform-lead |
| L3 | CTO/VP Eng | P1 > 30 min, data loss | Phone + PagerDuty |
# Database Maintenance Runbook — PostgreSQL
**Schedule:** Weekly vacuum (automated), monthly manual review
## Backup
pg_dump $DATABASE_URL \
--format=custom \
--compress=9 \
--file="backup-$(date +%Y%m%d-%H%M%S).dump"
✅ Expected: File created, size > 0. `pg_restore --list backup.dump | head -20` shows tables.
Verify backup is restorable (test monthly):
pg_restore --dbname=$STAGING_DATABASE_URL backup.dump
psql $STAGING_DATABASE_URL -c "SELECT count(*) FROM users;"
✅ Expected: Row count matches production.
## Migration
DATABASE_URL=$STAGING_DATABASE_URL npx prisma migrate deploy
DATABASE_URL=$PROD_DATABASE_URL npx prisma migrate deploy
✅ Expected: `All migrations have been successfully applied.`
⚠️ For large table migrations (> 1M rows), use `pg_repack` or add column with DEFAULT separately to avoid table locks.
## Vacuum & Reindex
psql $DATABASE_URL -c "
SELECT schemaname, tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS total_size,
n_dead_tup, n_live_tup,
ROUND(n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0) * 100, 1) AS dead_ratio
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC LIMIT 10;"
psql $DATABASE_URL -c "VACUUM ANALYZE users;"
psql $DATABASE_URL -c "VACUUM ANALYZE events;"
psql $DATABASE_URL -c "REINDEX INDEX CONCURRENTLY users_email_idx;"
✅ Expected: dead_ratio drops below 5% after vacuum.
Add a staleness header to every runbook:
## Staleness Check
This runbook references the following config files. If they've changed since the
"Last verified" date, review the affected steps.
| Config File | Last Modified | Affects Steps |
|-------------|--------------|---------------|
| vercel.json | `git log -1 --format=%ci -- vercel.json` | Step 3, Rollback |
| prisma/schema.prisma | `git log -1 --format=%ci -- prisma/schema.prisma` | Step 2, DB Maintenance |
| .github/workflows/deploy.yml | `git log -1 --format=%ci -- .github/workflows/deploy.yml` | Step 1, Step 3 |
| docker-compose.yml | `git log -1 --format=%ci -- docker-compose.yml` | All scaling steps |
Automation: Add a CI job that runs weekly and comments on the runbook doc if any referenced file was modified more recently than the runbook's "Last verified" date.
Before trusting a runbook in production, validate every step in staging:
# 1. Create a staging environment mirror
vercel env pull .env.staging
source .env.staging
# 2. Run each step with staging credentials
# Replace all $DATABASE_URL with $STAGING_DATABASE_URL
# Replace all production URLs with staging URLs
# 3. Verify expected outputs match
# Document any discrepancies and update the runbook
# 4. Time each step — update estimates in the runbook
time npx prisma migrate deploy
Schedule a 1-hour review every quarter:
| Pitfall | Fix |
|---|---|
| --- | --- |
| Commands that require manual copy of dynamic values | Use env vars — $DATABASE_URL not postgres://user:pass@host/db |
| No expected output specified | Add ✅ with exact expected string after every verification step |
| Rollback steps missing | Every destructive step needs a corresponding undo |
| Runbooks that never get tested | Schedule quarterly staging dry-runs in team calendar |
| L3 escalation contact is the former CTO | Review contact info every quarter |
| Migration runbook doesn't mention table locks | Call out lock risk for large table operations explicitly |
docs/runbooks/, versioned with the code they describe共 1 个版本