Pre-render ~1,277 high-traffic HTML pages (homepage, books, chapters)
at build time and serve them directly via nginx. All other routes
(verses, search, API, PDFs, Strong's) fall through to a FastAPI
sidecar. If the sidecar crashes, nginx continues serving static
pages and health checks.
Also harden the FastAPI app against the memory/crash issues:
- Switch from bare uvicorn to gunicorn with uvicorn workers
- Add --max-requests worker recycling to prevent memory leaks
- Add --timeout to kill hung workers
- Add per-IP rate limiting middleware (10 req/s, burst of 50)
- Add request timeout middleware (30s max per request)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fly.io's Consul health checks hit /health. Now nginx responds
directly with 200 OK without proxying to uvicorn, so health
checks won't fail under heavy load.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- nginx.conf: docker-compose version (uses 'web:8001')
- nginx-prod.conf: production version (uses '127.0.0.1:8001')
- Separate nginx service in docker-compose
- uvicorn runs on port 8001, nginx exposes 8000
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>