VayuPress Operations Runbook
Version: 1.0.0 (Prompt 6 — Operations)
Audience: Production operators, on-call maintainers
SLA: 99.9% uptime target; P1 response < 15 minutes
Quick Reference
# Service status
systemctl status vayupress meilisearch isso
# Health check
curl -s http://localhost:8080/health | jq .
curl -s http://localhost:8080/health/dependencies | jq .
# Logs (last 100 lines)
journalctl -u vayupress -n 100 --no-pager
# Restart application
systemctl restart vayupress
# Emergency stop
systemctl stop vayupress
Service Architecture
| Service |
Port |
User |
Managed By |
| vayupress |
8080 (localhost) |
vayupress |
systemd |
| nginx |
80, 443 |
www-data |
systemd |
| meilisearch |
7700 (localhost) |
meilisearch |
systemd |
| isso |
8090 (localhost) |
isso |
systemd |
Health Endpoints
| Endpoint |
Purpose |
Expected Response |
GET /health |
Overall health |
{"status":"ok"} |
GET /health/live |
Liveness probe |
{"live":true} |
GET /health/ready |
Readiness probe |
{"ready":true} |
GET /health/dependencies |
Dep status |
Per-service status JSON |
GET /health/migrations |
Migration status |
Applied migration list |
GET /health/ethics |
Ethics compliance |
{"compliant":true} |
Runbooks
RB-01: Application Not Starting
- Check logs:
journalctl -u vayupress -n 50
- Look for
CHECKSUM DRIFT — means a migration was tampered (ADR-0034). Do NOT restart until investigated.
- Look for
FATAL: database locked — kill any zombie vayupress processes: pkill -f vayupress
- Check data dir permissions:
ls -la /data/vayupress.db
- Verify env vars loaded:
systemctl cat vayupress | grep EnvironmentFile
- Test binary directly:
sudo -u vayupress /usr/local/bin/vayupress --dry-run
RB-02: High Memory Usage (>800 MB)
- Check current memory:
systemctl status vayupress | grep Memory
- Check for write queue backlog:
curl http://localhost:8080/health/dependencies | jq .queue
- Check WAL size:
ls -lh /data/vayupress.db-wal
- If WAL > 100 MB, checkpoint manually:
sqlite3 /data/vayupress.db "PRAGMA wal_checkpoint(RESTART);"
- If memory continues to grow, restart:
systemctl restart vayupress
- If recurring: check for runaway pprof goroutine, review recent deploys
RB-03: Database Corruption
- Run integrity check:
sqlite3 /data/vayupress.db "PRAGMA integrity_check;"
- If errors, IMMEDIATELY stop writes:
systemctl stop vayupress
- Identify most recent valid backup:
ls -lt /data/backups/*.db.gz | head -5
- Restore from backup (see RB-07)
- File incident report in
docs/incidents/
RB-04: TLS Certificate Expired
- Check expiry:
certbot certificates
- Force renewal:
certbot renew --force-renewal
- Test nginx config:
nginx -t
- Reload nginx:
systemctl reload nginx
- If ACME challenge fails, check firewall:
ufw status (port 80 must be open for HTTP-01)
RB-05: High Error Rate (>1% 5xx)
- Check error logs:
journalctl -u vayupress | grep 'level=error' | tail -20
- Check
/health/dependencies for failing deps
- If database errors: check WAL size, run integrity check (RB-03 step 1)
- If Meilisearch errors:
systemctl restart meilisearch (app degrades gracefully)
- If nginx errors:
nginx -t && systemctl reload nginx
RB-06: Disk Space Running Low (<20% free)
- Check usage:
df -h /data
- Find large files:
du -sh /data/* | sort -rh | head -10
- Rotate logs:
logrotate -f /etc/logrotate.d/vayupress
- Clean orphaned media:
curl -X POST http://localhost:8080/api/v1/admin/cleanup-orphans -H "Authorization: Bearer $VAYU_API_KEY"
- Archive old backups: keep last 30 days, compress older
- If WAL is large: checkpoint (RB-02 step 4)
RB-07: Restore from Backup
# Stop application
systemctl stop vayupress
# List available backups
ls -lt /data/backups/
# Restore (replace TIMESTAMP with target backup)
cp /data/vayupress.db /data/vayupress.db.pre-restore
zcat /data/backups/vayupress-TIMESTAMP.db.gz > /data/vayupress.db
# Verify restored DB
sqlite3 /data/vayupress.db "PRAGMA integrity_check;"
# Set correct ownership
chown vayupress:vayupress /data/vayupress.db
# Start application
systemctl start vayupress
# Verify health
curl http://localhost:8080/health
RB-08: Fail2ban Blocking Legitimate Users
- Check if IP is banned:
fail2ban-client status nginx-limit-req
- Unban specific IP:
fail2ban-client set nginx-limit-req unbanip <IP>
- Whitelist if needed: add to
/etc/fail2ban/jail.local under [DEFAULT] ignoreip
- Reload:
fail2ban-client reload
RB-09: API Key Rotation
# Generate new key
NEW_KEY=$(openssl rand -hex 32)
echo "New API key: $NEW_KEY"
# Update environment
# Edit /etc/vayupress/vayupress.env
# Change VAYU_API_KEY=<new_value>
# Restart to apply
systemctl restart vayupress
# Update all API clients with new key
# Verify health
curl -H "Authorization: Bearer $NEW_KEY" http://localhost:8080/health
Monitoring Metrics (Prometheus)
Key metrics exposed at http://localhost:8080/metrics (internal only):
| Metric |
Alert Threshold |
Action |
vayupress_requests_total{status="5xx"} |
>1% of total |
RB-05 |
vayupress_memory_bytes |
>800 MB |
RB-02 |
vayupress_wal_size_bytes |
>64 MB |
RB-02 step 4 |
vayupress_migration_drift_detected |
>0 |
RB-01 step 2 |
vayupress_write_queue_depth |
>1000 |
RB-02 |
vayupress_auth_lockouts_total |
rising |
Security alert |
vayupress_wal_checkpoint_duration_ms |
>5000 |
Investigate I/O |
vayupress_dead_letter_queue_size |
>10 |
ADR-0035 review |
Scheduled Operations
| Schedule |
Task |
Script/Command |
| Nightly 02:00 |
Database backup |
/etc/cron.d/vayupress-backup |
| Nightly 03:00 |
Orphan cleanup |
POST /api/v1/admin/cleanup-orphans |
| Weekly 04:00 |
Restore validation |
/etc/cron.d/vayupress-restore-validate |
| Daily |
TLS renewal check |
certbot renew |
| On deploy |
Migration checksum verify |
ADR-0034; startup check |
Capacity Planning
| Resource |
Current Limit |
Warning Level |
Action |
| Memory |
800 MB |
600 MB |
Review queue depth |
| Disk (data) |
Host-dependent |
80% full |
Add storage or archive |
| SQLite WAL |
32 MB adaptive |
32 MB |
RESTART checkpoint auto |
| Concurrent goroutines |
10,000 (default) |
8,000 |
Review plugin pool |
| Binary size |
45 MB |
40 MB |
make check-size |
| JS bundle (gzip) |
50 KB |
45 KB |
Audit new dependencies |
Incident Classification
| Severity |
Definition |
Response Time |
Escalation |
| P1 Critical |
Site down, data loss, security breach |
15 min |
BDFL + Security Lead |
| P2 High |
Degraded performance, elevated errors |
1 hour |
On-call maintainer |
| P3 Medium |
Single feature broken, non-critical |
4 hours |
Community Lead |
| P4 Low |
Cosmetic, advisory |
Next sprint |
Regular backlog |
Security incidents: email security@vayupress.com immediately.