Get started with API Gateway (local evaluation)

Try API Gateway locally with Docker Compose and sign in to the Admin Console and Developer Portal. Production installs use the offline Kubernetes bundle.

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:

ServicePurposeLocal URL
Admin ConsolePlatform admin UIhttp://localhost:5173
Developer PortalAPI consumer UIhttp://localhost:5174
Control Plane APIBackend REST API both UIs talk tohttp://localhost:31000
APISIX GatewayThe actual traffic-serving gatewayhttp://localhost:9080
APISIX Admin APIInternal, used only by the control planehttp://localhost:9180 (loopback only)
PostgreSQLDurable configuration and audit storagelocalhost:5432
RedisRate-limit counters, caching, jobslocalhost:6379
etcdAPISIX’s own configuration storelocalhost:2379
Prometheus metricsControl plane and gateway metricshttp://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:

  1. Control Plane URL — pre-filled with http://localhost:31000 for the local stack.
  2. 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:

  1. Enter the Control Plane URL (http://localhost:31000 by default).
  2. Enter your Email and click Send Login Link.
  3. 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.
  4. 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