Phase 04 — Operations
CI/CD, GMUD, SLOs, DORA metrics, infrastructure and A/B testing.
CI/CD Pipeline
Domain: food.ecportilho.com
Process Manager: PM2 (zero-downtime reload)
Reverse Proxy: Nginx
SSL: Let’s Encrypt via Certbot
Build Pipeline — 7 Steps
| Step | Command | Description |
|---|---|---|
| 1. pull_latest | git pull origin main | Update source code |
| 2. install_dependencies | npm ci --production=false | Install dependencies (including devDeps for build) |
| 3. build_frontend | npm run build | Build React SPA via Vite → client/dist/ |
| 4. run_seed | npm run seed | Populate SQLite with initial data (idempotent) |
| 5. register_webhook | npm run register-webhook | Register webhook in ecp-digital-bank (idempotent) |
| 6. restart | pm2 reload ecosystem.config.cjs | Graceful reload (zero-downtime) |
| 7. verify_health | curl -sf http://127.0.0.1:3000/api/categories | Application health check |
Rollback
Trigger: Health check fails after deploy OR critical payment error in the first 2 hours.
Command: git checkout HEAD~1 && npm ci && npm run build && pm2 reload ecosystem.config.cjs
Estimated time: 5 minutes
GMUD
Type: Normal | Priority: High | Risk: Low-Medium (10/30)
Scope: VPS provisioning, installation of Node.js 20 LTS + PM2 + Nginx + Certbot, application deploy, seed data (6 restaurants, 24 items, 3 users), SSL configuration, webhook registration in ecp-digital-bank, DNS food.ecportilho.com.
Window: Saturday 10:00-12:00 BRT | Estimated duration: 45 minutes | Monitoring: 2h after deploy
Success Criteria
| Criterion | Validation |
|---|---|
| Application responding with SSL | curl -sf https://food.ecportilho.com/ returns HTML |
| API functional | GET /api/categories returns 200 |
| Authentication functional | POST /api/auth/login returns valid JWT |
| Bank integration accessible | POST /api/payments/bank-auth returns token |
| Webhook registered | ecp-digital-bank confirms registration |
| PM2 stable 30 min | pm2 status shows 0 restarts |
Service Level Objectives (SLOs)
Measurement window: Rolling 30 days.
DORA Metrics
| Metric | Target | Target Band | How to Measure |
|---|---|---|---|
| Deployment Frequency | 1-2x per week | Medium | Count of pm2 reloads in production per week |
| Lead Time for Changes | < 1 day | High | Timestamp of merge to main vs timestamp of deploy |
| Change Failure Rate | < 15% | Medium | Deploys with rollback / total deploys in the period |
| Mean Time to Recovery | < 30 minutes | High | Time between incident detection and confirmed restoration |
Targets calibrated for MVP with lean team and single VPS. Future: automated CI/CD via GitHub Actions.
Infrastructure
- Metrics: CPU, memory, restarts, uptime
- Log rotation: max 50MB, retention 10 files, compress
- Stdout logs: ~/.pm2/logs/foodflow-out.log
- Stderr logs: ~/.pm2/logs/foodflow-error.log
- Access log: /var/log/nginx/foodflow-access.log
- Error log: /var/log/nginx/foodflow-error.log
- SSL: Let’s Encrypt (Certbot auto-renew)
- Health check: GET /api/categories every 60s, timeout 5s
Environment Variables (15)
NODE_ENV, PORT, HOST, JWT_SECRET, JWT_REFRESH_SECRET, DB_PATH, CORS_ORIGIN, ECP_BANK_API_URL, ECP_BANK_PLATFORM_EMAIL, ECP_BANK_PLATFORM_PASSWORD, ECP_BANK_PLATFORM_PIX_KEY, ECP_BANK_PLATFORM_PIX_KEY_TYPE, ECP_BANK_PIX_EXPIRATION_MINUTES, ECP_BANK_WEBHOOK_SECRET, FOODFLOW_PUBLIC_URL
.env file at project root on VPS. NEVER commit to the repository.