Get started with API Gateway (local evaluation)
This guide walks through standing up a local evaluation stack on a workstation with Docker Compose, and signing in to both the Admin Console and the Developer Portal for the first time.
This is not the production install. The local stack is for trying the product on one machine. A production deployment runs on Kubernetes from an offline bundle that includes every image and its own installation guide; it is delivered with your licence. To arrange an installation, email hello@phron.tech.
Prerequisites
- Docker and Docker Compose
make- Go (only if you want to generate a local admin token yourself instead of using the default one printed by the stack — see below)
- A modern browser
1. Stand up the stack
From the repository root:
make up
This starts the full local topology defined in infra/docker-compose/docker-compose.yml:
| Service | Purpose | Local URL |
|---|---|---|
| Admin Console | Platform admin UI | http://localhost:5173 |
| Developer Portal | API consumer UI | http://localhost:5174 |
| Control Plane API | Backend REST API both UIs talk to | http://localhost:31000 |
| APISIX Gateway | The actual traffic-serving gateway | http://localhost:9080 |
| APISIX Admin API | Internal, used only by the control plane | http://localhost:9180 (loopback only) |
| PostgreSQL | Durable configuration and audit storage | localhost:5432 |
| Redis | Rate-limit counters, caching, jobs | localhost:6379 |
| etcd | APISIX’s own configuration store | localhost:2379 |
| Prometheus metrics | Control plane and gateway metrics | http://localhost:31000/metrics, http://localhost:9091/apisix/prometheus/metrics |
To stop the stack:
make down
To confirm everything is wired up correctly, run the smoke tests:
make smoke
2. First login: platform admin (Admin Console)
Open http://localhost:5173. The console needs two things before it will let you make any changes:
- Control Plane URL — pre-filled with
http://localhost:31000for the local stack. - Admin Token — a signed JWT that proves who you are and what role you hold. The console does not issue this token itself:
- Paste a token directly into the Admin Token field — this is the normal path for local development.
For the local Docker Compose stack, a working admin token can be minted with the bundled dev token generator, which signs a JWT against the same JWKS fixture the control plane is configured to trust. The signing key is a throwaway per-checkout fixture (generated on first use into the gitignored tests/security/fixtures/; no key is committed):
sh tests/security/gen-fixtures.sh # generate/reuse the throwaway keypair
cd tests/security
go run . # prints the token
This prints a JWT with roles: ["admin"] (global admin) valid for one hour. Copy it into the Admin Token field in the console. The token is remembered in the browser (localStorage) so you won’t need to re-paste it every reload — a Sign Out button next to the field clears it.
Once a token is present, the console’s tabs become usable. Start on the Wizard or Env Setup tab (see the Admin Console Guide) to create your first environment.
3. First login: API developer (Developer Portal)
Open http://localhost:5174. The Developer Portal signs developers in with a magic link — a
one-time sign-in link. That is the only login path the container-built portal renders:
- Enter the Control Plane URL (
http://localhost:31000by default). - Enter your Email and click Send Login Link.
- You see: “Check your email. If that email has portal access, a login link has been sent and should arrive within a couple of minutes.” The exact response comes back for every address, registered or not — it is deliberate, and is not a signal that something went wrong.
- Retrieve the link (below) and open it in the same browser. It signs you in and lands you on the Catalog view.
In the local stack the link lands in a file, not a mailbox. The dev/test mail provider is the
log-only mailer (MAIL_PROVIDER=log): it writes each requested link as one line
(<timestamp> <email> <link>) to the control plane’s MAIL_DEV_DUMP_FILE. In the make up stack
that path is a host bind mount — a real file on your machine, not the container’s tmpfs — so
you read it straight from the repository root:
# the newest line (the link you just requested):
tail -n 1 infra/docker-compose/dev-mailer/dev-magic-links.log
# or follow the file while you click "Send Login Link":
tail -f infra/docker-compose/dev-mailer/dev-magic-links.log
Open the …/v1/portal/login/verify?token=… URL printed on the newest line in the same browser.
Links are single-use and valid for 15 minutes. The dump file is the only place a raw link ever
appears — the control plane’s own logs record only a redacted marker — so keep it local: it is
gitignored and its directory is created mode 0700.
Why is there no email/display-name shortcut in this stack? PORTAL_EMAIL_LOGIN_ENABLED is a
real server-side control-plane switch for a passwordless
POST /v1/portal/login shortcut, on by default only in local/development. It is not what the
shipped portal renders: the portal’s dev-shortcut UI is gated by the build-time
VITE_PORTAL_DEV_LOGIN_ENABLED, and no Dockerfile passes it, so every container build — the
make up stack, the test host, and the k8s testing overlay — compiles the shortcut out. The
shortcut remains a convenience only for npm run dev with the variable set locally; against any
container build, sign in with the magic link above.
See the Developer Portal Guide for the full application → access request → API key workflow.
Next steps
- Platform admins: continue to the Admin Console Guide.
- API developers: continue to the Developer Portal Guide.
- If something errors out along the way, check Troubleshooting.