Platform & deployment

Deployment

Halo is live, not a localhost demo: the FastAPI backend runs on Railway and the Next.js web app runs on Vercel.

Where it runs

The monorepo splits cleanly into two independently deployed services:

ServicePathHost
Web app (landing, dashboard, war room, these docs)apps/webVercel
Workflow API (state machine, mode logic, gateway calls)apps/apiRailway

The live app is at haloagent.xyz, and this documentation is served from the same deployment at /docs.

Backend on Railway

The API deploys from apps/api (Railway Root Directory = apps/api) using the in-repo Dockerfile. On every boot the container creates its tables, seeds the demo incidents, and then starts Uvicorn bound to Railway's injected $PORT:

python -c "import app.db.models; from app.db.session import create_db_and_tables; create_db_and_tables()" \
  && python scripts/seed_resilience_demo.py \
  && python scripts/seed_live_approval_demo.py \
  && uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-8000}

Railway exposes it on a public HTTPS URL (for example https://halo-api-production.up.railway.app). Configuration — the TrueFoundry gateway URL, saved-agent IDs, and the Jaguar action bridge — comes from environment variables; see Run it locally for the full list.

Frontend on Vercel

The web app deploys from apps/web (Vercel Root Directory = apps/web) as a standard Next.js 15 project. It needs exactly one environment variable to find the backend:

NEXT_PUBLIC_API_BASE_URL=https://<your-railway-url>

Because it is a NEXT_PUBLIC_ variable it is baked in at build time, so it has to be set before the build. If it is unset, the app falls back to http://127.0.0.1:8000 for local development.

How they connect

All of the frontend's API calls run server-side — from server components and server actions — so the browser never talks to the backend directly. That means the two services only need the Railway URL wired into Vercel; no CORS setup is requiredfor the app to work. The backend just has to be reachable from Vercel over HTTPS.

State & demo data

The API uses SQLite, which is ephemeral on Railway — the file is wiped on every redeploy or restart. That is intentional: the boot command reseeds the demo incidents each time, so the deployment always comes up in a clean, known state. Don't attach a volume expecting persistence.

Right now everything is up: the backend is running on Railway and the frontend on Vercel, wired together through NEXT_PUBLIC_API_BASE_URL — open haloagent.xyz and the dashboard lists live incidents straight from the Railway API.