Observability and deploy
Budget: 1 week, once users exist.
Why this matters
Your current deploy is one VM plus nginx. That is fine today. The day a user reports "my solve failed and I don't know why," you will wish you had structured logs, error tracking, and a CI pipeline that builds known good images. Do this before users arrive, not after.
What to learn
| Topic | Time |
|---|---|
structlog in Python: JSON in prod, pretty in dev | 0.5-1 day |
| Pick and wire a managed log destination (Axiom, Better Stack, Grafana Cloud) | 0.5 day |
| Sentry for the FastAPI backend | 0.5 day |
| Sentry for the React frontend, sourcemaps included | 0.5 day |
| GitHub Actions: one workflow for pytest + frontend build + Docker image | 1-2 days |
| Push Docker images to Artifact Registry on merge to main | 0.5 day |
| Evaluate Cloud Run or Fly.io as the next deploy target (defer the migration) | 0.5 day |
Resources
- structlog docs: structured logging for Python.
- Sentry for FastAPI: backend error tracking.
- Sentry for React: frontend error tracking with sourcemaps.
- GitHub Actions docs: the workflow syntax reference.
- Cloud Run docs: the next deploy target when a single VM is not enough.
- Fly.io docs: alternative to Cloud Run, slightly simpler DX.
- Managed log destinations: Axiom, Better Stack, Grafana Cloud.
Exercise
Replace server.log and ad-hoc print statements in server.py with
structlog. Configure it to emit JSON in production and pretty
human-readable output in development. Add Sentry to both the backend
and the frontend. Write one GitHub Actions workflow that runs tests,
builds the Docker image, and pushes it to Artifact Registry on a push
to main. Leave the VM deploy as is for now. The goal is to know when
something is broken, not to rearchitect the deploy.