Skip to main content
The UI is a TanStack Start app that authenticates via WorkOS and calls both backend and statesman. It also acts as the public gateway when tunneling (e.g., ngrok): expose the UI port, and point external callbacks to the UI domain. Use this page when you want to run ui/ outside Docker for fast frontend iteration.
make -C self-hosting/docker-compose all-up
docker compose -f self-hosting/docker-compose/docker-compose.yml stop ui
Run make -C ... from repo root, or run make all-up from self-hosting/docker-compose. Then run UI from ui/ with .env.local. When backend/statesman remain in Docker, set UI service URLs to host ports:
  • ORCHESTRATOR_BACKEND_URL=http://localhost:3000
  • STATESMAN_BACKEND_URL=http://localhost:8080
  • TOKENS_SERVICE_BACKEND_URL=http://localhost:8081
  • DRIFT_REPORTING_BACKEND_URL=http://localhost:3001 (optional)
Use the ports: mappings in self-hosting/docker-compose/docker-compose.yml as the source of truth for host ports.

Quick start

  1. Copy .env.example to .env.local in ui/ and fill the essentials:
    # URLs
    PUBLIC_URL=http://localhost:3030                            # replace with ngrok URL when exposing UI
    ALLOWED_HOSTS=localhost,127.0.0.1                           # include ngrok hostname when exposing UI
    
    # WorkOS (User Management)
    WORKOS_CLIENT_ID=<your_workos_client_id>
    WORKOS_API_KEY=<your_workos_api_key>
    WORKOS_COOKIE_PASSWORD=<32+ random chars>
    WORKOS_REDIRECT_URI=http://localhost:3030/api/auth/callback # replace with ngrok callback URL; must match WorkOS config
    WORKOS_WEBHOOK_SECRET=<if using webhooks locally via tunnel>
    
    # Backend
    ORCHESTRATOR_BACKEND_URL=http://localhost:3000
    ORCHESTRATOR_BACKEND_SECRET=orchestrator-secret   # matches backend DIGGER_INTERNAL_SECRET
    ORCHESTRATOR_GITHUB_APP_URL=http://localhost:3000/github/setup  # or your app install URL
    
    # Statesman
    STATESMAN_BACKEND_URL=http://localhost:8080
    STATESMAN_BACKEND_WEBHOOK_SECRET=statesman-secret  # matches OPENTACO_ENABLE_INTERNAL_ENDPOINTS
    
    # Optional
    DRIFT_REPORTING_BACKEND_URL=http://localhost:3001
    DRIFT_REPORTING_BACKEND_WEBHOOK_SECRET=...
    POSTHOG_KEY=...
    
    In WorkOS, add http://localhost:3030/api/auth/callback and your ngrok callback URL as redirects.
  2. Install deps and run:
    cd ui
    pnpm install   # or npm install
    pnpm dev --host --port 3030
    
    Open http://localhost:3030 (or your tunnel URL) and sign in with a WorkOS user that belongs to at least one org. Ensure the WorkOS redirect URI matches the public URL you configured.
  3. Ensure backend + statesman were started and the same secrets are in place (see Backend and Statesman).
  4. Sync the WorkOS org/user to both services using the curl snippets on those pages (required for repos/units to load).

ngrok setup

ngrok http 3030
After ngrok starts, update and restart UI:
  • PUBLIC_URL=https://<your-ngrok-domain>
  • WORKOS_REDIRECT_URI=https://<your-ngrok-domain>/api/auth/callback
  • ALLOWED_HOSTS includes <your-ngrok-domain>
GitHub App callback/webhook URLs should also use the same UI tunnel domain.

Common errors

  • NotFound/Forbidden listing units: statesman org/user not synced or webhook secret mismatch.
  • 404 on repos or GitHub connect: backend missing org/user, DIGGER_ENABLE_API_ENDPOINTS not set, or ORCHESTRATOR_GITHUB_APP_URL points to a non-existent path.
  • WorkOS login succeeds but dashboard redirects to / or errors: the signed-in user has no WorkOS org membership; add to an org and resync to services.
  • WorkOS redirect blocked: public URL not whitelisted; add your tunnel host to ALLOWED_HOSTS and to the WorkOS redirect URI list.