Skip to content

feat: add /health endpoint, migrate to lifespan lifecycle, and fix Dockerfile for production#439

Open
Arijit429 wants to merge 3 commits intofireform-core:mainfrom
Arijit429:feat/health-check-and-lifespan-lifecycle
Open

feat: add /health endpoint, migrate to lifespan lifecycle, and fix Dockerfile for production#439
Arijit429 wants to merge 3 commits intofireform-core:mainfrom
Arijit429:feat/health-check-and-lifespan-lifecycle

Conversation

@Arijit429
Copy link
Copy Markdown

@Arijit429 Arijit429 commented Apr 15, 2026

Closes #116
Closes #118
Closes #122
Closes #135
Closes #187
Closes #274
Closes #388

Summary

Adds a health check endpoint for container orchestration, migrates database
initialization to FastAPI's modern lifespan pattern, and fixes the Dockerfile
to actually start the application server.

Problem

  1. No health check — Docker, Kubernetes, and cloud platforms need a
    /health endpoint to monitor if the app is alive and auto-restart on failure.
    FireForm had no such endpoint.

  2. Database init at import timeTemplate.metadata.create_all() and
    FormSubmission.metadata.create_all() ran at the module top level, meaning
    database tables were created whenever any file imported main.py — including
    during test collection, linting, and static analysis. FastAPI's recommended
    pattern uses lifespan context managers.

  3. Dockerfile doesn't start the appCMD ["tail", "-f", "/dev/null"] keeps
    the container alive but does not run the server. PYTHONPATH was also set to
    /app/src instead of /app, which would break imports.

Changes

api/main.py

  • Added GET /health endpoint returning {"status": "healthy", "service": "fireform"}
  • Migrated database initialization into lifespan async context manager
  • Removed top-level create_all() calls
  • Added FastAPI metadata (title, description, version)

Dockerfile

  • Changed CMD to start uvicorn server
  • Fixed PYTHONPATH from /app/src to /app
  • Added EXPOSE 8000
  • Added HEALTHCHECK directive using the /health endpoint

Testing

  • GET /health returns expected JSON response
  • All existing tests pass without modification
  • Server startup logs confirm lifespan initialization

Changes Summary

File Change Why
api/main.py Added GET /health endpoint Docker/K8s liveness probe
api/main.py Added lifespan context manager DB init at startup, not import time
api/main.py Added API metadata (title, description, version) Professional /docs page
Dockerfile Changed CMD to uvicorn api.main:app Old CMD did nothing (tail -f /dev/null)
Dockerfile Fixed PYTHONPATH /app/src/app Imports would fail with old path
Dockerfile Added HEALTHCHECK directive Docker auto-restarts unhealthy containers
Dockerfile Added EXPOSE 8000 Documents container port for platforms

- Add HTTPException handler for consistent error shape across all routes
- Add RequestValidationError handler with human-readable error messages
- Add catch-all Exception handler to prevent stack trace leakage
- Fix duplicate get_template() call in forms.py (was querying DB twice)
- Wrap Controller errors in AppError for safe client-facing messages
- All errors now return uniform {success, error: {code, message}} envelope
…file

- Add GET /health liveness probe for Docker and container orchestration
- Migrate database init from module-level to FastAPI lifespan context manager
- Fix Dockerfile: start uvicorn server instead of tail -f /dev/null
- Fix Dockerfile: correct PYTHONPATH from /app/src to /app
- Add Docker HEALTHCHECK directive using /health endpoint
- Add EXPOSE 8000 for container port documentation
- Add FastAPI metadata (title, description, version) for API docs
@Arijit429
Copy link
Copy Markdown
Author

Context

Three deployment blockers fixed: added a /health liveness probe for container orchestration, moved database init from import-time to FastAPI's lifespan context manager, and fixed the Dockerfile to actually start the server instead of running tail -f /dev/null.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant