Settings
For most visitors there is nothing to set here. The bearer token and backend URL fields below only apply if you are running your own ghostloop backend with auth turned on.
Bearer token (optional)
Only needed if your backend has GHOSTLOOP_DASHBOARD_TOKEN set. The public demo leaves auth open, so most visitors can ignore this.
Stored in localStorage, never sent to any server but your configured backend. Match this to StaticTokenAuth.from_env() on the backend side.
Backend URL
Set GHOSTLOOP_BACKEND_URL to a deployed ghostloop FastAPI server. When unset, this UI shows demo fixtures so the Vercel deploy stays interactive without a backend.
GHOSTLOOP_BACKEND_URL=https://your-server.example.com
On Vercel: Project Settings, then Environment Variables, then Add. Then redeploy.
Deploy the backend
The backend is a 30-line FastAPI server wrapping ghostloop.dashboard.create_production_app. Run it anywhere with a public HTTPS URL (Railway, Fly, Render, your own VPS), then paste the URL into your Vercel env vars.
A ready-to-deploy version lives in this repo at backend/. On Railway:
- New Project, then Deploy from GitHub repo, then
joemunene-by/ghostloop-ui - Settings, then Root Directory:
backend(this is the key step. Default (repo root) tries to build the Next.js app and fails.) - Variables, then
GHOSTLOOP_DASHBOARD_TOKEN(random string) andCORS_ORIGINS(your Vercel URL) - Deploy, then Settings, then Networking, then Generate Domain
Full guide at backend/README.md. Or roll your own:
# backend/server.py: ~10 lines of glue
from ghostloop import GhostloopStore
from ghostloop.fleet import FleetRegistry
from ghostloop.dashboard import (
create_production_app, ProductionConfig, StaticTokenAuth,
)
app, alarms = create_production_app(
store=GhostloopStore("./ghostloop.db"),
fleet=FleetRegistry(),
config=ProductionConfig(
auth=StaticTokenAuth.from_env(),
cors_origins=["https://your-ui.vercel.app"],
),
)
# requirements.txt: ghostloop[dashboard]>=1.0.3
# run: uvicorn server:app --host 0.0.0.0 --port $PORTSet GHOSTLOOP_DASHBOARD_TOKEN on the server side and paste the same value into the Bearer token field above.