2 Commits

Author SHA1 Message Date
kennethreitz 57b4ed7dd9 Switch from gunicorn/uvicorn to granian with Rust-level static file serving
Replaces gunicorn + uvicorn with granian across all entry points (Dockerfile,
docker-compose, main.py, sidecar script). Static files are now served directly
from granian's Rust layer, bypassing Python entirely for /static routes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 10:07:23 -04:00
kennethreitz 2ab3dfa142 Add static site generation with nginx + hardened FastAPI sidecar
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>
2026-01-31 21:59:34 -05:00