Skip to content

Local development

The services stay bound to the server’s localhost. You reach them through SSH tunnels; you never bind them to every interface or open security-group ports for convenience.

  1. Copy dev/local.env.example to dev/local.env (git-ignored) and set STAGING to your ssh host.
  2. Copy the repo-root local.env.example to local.env (ports only, no secrets).
  3. Have cluster.env available at the repo root on your machine (the apps read secrets from it; it is git-ignored).
  4. npm install in apps/api and in apps/web.
  5. Create the test logins: node apps/api/scripts/seed-dev-users.js.

Open three terminals:

Terminal window
bash dev/tunnel.sh # 1. leave running
cd apps/api && npm run dev # 2. API on http://127.0.0.1:4000
cd apps/web && npm run dev # 3. web on http://localhost:5173

Open http://localhost:5173. It must be localhost, not 127.0.0.1, or Keycloak rejects the redirect.

Log in as dev-admin, dev-analyst or dev-vendor (password DEV_USER_PASSWORD from cluster.env). node apps/api/scripts/smoke-login.js logs each in through the real code + PKCE flow and calls the API, which is a quick way to check that the tunnel, Keycloak and the API all work.

  • Views refresh inside the API process. In development that is your local API talking to the server’s Trino through the tunnel. In production the process that runs the API must stay up for views to refresh.
  • Spark: do not point a local driver at the server’s cluster through tunnels (the executors must connect back to your machine). Use master=local[*] with S3A and Nessie through the tunnels, or run the job on the server.
  • Check which ports are really in use on the server: sudo ss -ltnp | grep -E 'java|postgres|weed|postgrest|python|node'.
  • Check pages at volume: node apps/api/scripts/seed-stress-data.js --vendors 150 fills in many fake vendors; --clean removes them. Do this before calling a page done.

The equivalent of the tunnel is a VPN plus firewall rules, services bound to the private interface, and TLS between hosts.