Skip to content
VerifAIer
Home / Docs / Operations / Runbooks
Operations · Runbooks

Runbooks, local, Docker & compose

Three ways to run it, verified against the real Dockerfile and compose files, plus the exact health checks each exposes.

Local development runbook

Run the API directly with uvicorn. The source lives under src/, so PYTHONPATH=src is required for a local (non-installed) run; pip install -e . installs the console entry points.

pyproject.toml · src/vailidator/api/routes.py · db/database.py

bash

python -m venv .venv && source .venv/bin/activate    # Windows: .venv\Scripts\activate
pip install -e ".[dev]"                              # core + dev extras
cp .env.example .env                                 # optional; defaults are safe (mock)

# run the API (reload for development)
PYTHONPATH=src uvicorn vailidator.api.routes:app --reload --port 8000

# verify
curl -s http://localhost:8000/health        # {"status":"ok","version":"1.4.2"}
  • SQLite is created at <project_root>/vailidator.db by default (override with DB_PATH).
  • No API keys needed, the default provider is the offline mock.
  • Run the test suite with python -m pytest tests/ -q.

Docker runbook

The Dockerfile builds a python:3.12-slim image, installs the package, runs as a non-root user (appuser), exposes 8000, ships a container HEALTHCHECK, and launches uvicorn with a single worker.

Dockerfile

bash

docker build -f Dockerfile -t verifaier-api .

docker run --rm -p 8000:8000 \
  --env-file .env \
  -e DB_PATH=/app/data/vailidator.db \
  -v verifaier_data:/app/data \
  verifaier-api

curl -s http://localhost:8000/health
Persist the database. The SQLite file lives at /app/data inside the container, mount a volume there (as above) or the data is lost when the container is removed. See backup posture.
  • Workers: the image runs --workers 1. Scale by running more replicas behind a load balancer (SQLite is single-writer, for true multi-node, use DATABASE_URL Postgres).
  • Non-root: the process runs as appuser; /app/data is owned by it.

docker-compose runbook

docker-compose.yml brings up the API plus the two Streamlit dashboards. The dashboards wait for the API to be healthy before starting; the API's SQLite lives on the named db_data volume and reads .env via env_file.

docker-compose.yml · docker-compose.dev.yml · Dockerfile.dashboard · Dockerfile.cc_dashboard

bash

# production-style stack (api :8000, dashboard :8501, cc_dashboard :8502)
docker compose up --build

# development: live code reload + local ./data + ./src mounts
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build

docker compose ps          # check health
docker compose logs -f api
docker compose down        # keep the db_data volume
docker compose down -v     # DESTROY the db_data volume (data loss)
ServiceImagePortDepends on
apiDockerfile8000n/a
dashboardDockerfile.dashboard8501api healthy
cc_dashboardDockerfile.cc_dashboard8502api healthy

The dashboards reach the API via API_URL=http://api:8000 (set by compose). All services use restart: unless-stopped.

Health checks

Every runtime exposes a liveness endpoint, and the containers wire it into their HEALTHCHECK:

TargetCheckContainer HEALTHCHECK
APIGET /health{"status":"ok","version":"1.4.2"}urllib GET /health, 30s interval, 5s timeout, 3 retries, 15s start-period
dashboardStreamlit /_stcore/healthurllib GET, 30s interval, 20s start-period
cc_dashboardStreamlit /_stcore/healthurllib GET, 30s interval, 20s start-period

/health is unauthenticated and dependency-free, safe for load balancers and uptime probes. Use it for readiness and liveness. For deeper checks, see the authenticated monitoring endpoints.