Skip to content

Latest commit

 

History

History
142 lines (98 loc) · 5.48 KB

File metadata and controls

142 lines (98 loc) · 5.48 KB
last_verified 2026-05-10
verified_against v0.2.4
quadrant tutorial
audience developer

Quickstart — Developer

Five minutes from a fresh machine to a backend service running behind Flowplane with a curl that proves traffic flowed through Envoy. Single happy path — no choices to make.

This tutorial gets you to a working gateway. Once you're here, the how-to recipes cover the next layer: multi-route exposes, JWT auth, OpenAPI export.

Prerequisites

  • Docker (or Podman — both auto-detected by the CLI)
  • A POSIX shell, curl, and tar (preinstalled on macOS and most Linux distros)

That's the whole list — Flowplane ships prebuilt binaries and pulls its container images automatically.

1. Install

curl -fsSL https://raw.githubusercontent.com/rajeevramani/flowplane/main/scripts/install.sh | sh

The installer detects your platform (macOS arm64 or Linux x86_64), downloads the latest release tarball from GitHub, and places the two binaries it ships with on your PATH:

  • flowplane — the control plane CLI you'll use from here on.
  • flowplane-agent — a sidecar that runs alongside Envoy in dev mode, watching for misconfigurations Envoy detects and reporting them back to the control plane. The dev stack expects it.

The installer prefers /usr/local/bin and falls back to ~/.local/bin if that's not writable.

Need a pinned version or a custom install location? install.sh --help shows the flags.

Verify the install:

flowplane --version
flowplane-agent --version

Building from source (contributors only): see CONTRIBUTING.mdmake install wraps the two cargo install commands.

2. Boot the stack

cd ~                 # init works from any directory
flowplane init

flowplane init writes a Compose file to ~/.flowplane/docker-compose-init.yml and brings up the full dev stack:

Service Address
API http://localhost:8080
Swagger UI http://localhost:8080/swagger-ui/
httpbin http://localhost:8000 (direct, not through Envoy)
Envoy listeners on ports 10001-10020 (assigned by expose)
flowplane-agent sidecar in Envoy's network namespace

Dev mode skips Zitadel — a token is generated automatically and saved to ~/.flowplane/credentials. Every CLI command reads the credentials file automatically.

Confirm the auth mode:

curl http://localhost:8080/api/v1/auth/mode
{"auth_mode":"dev"}

If you previously ran make demo (the prod-mode evaluation harness), remove its network before booting dev mode: docker network rm flowplane-network. The two stacks use the same network name and won't share it.

3. Expose a backend

flowplane expose http://httpbin:80 --name demo
Exposed 'demo' -> http://httpbin:80
  Port:   10001
  Paths:  /

  curl http://localhost:10001/

A single expose call wires together four resources: a cluster pointing at httpbin:80, a route config with a catch-all route to that cluster, a virtual host, and a listener on the auto-assigned port. Envoy picks them up via xDS within a second or two.

Use httpbin, not localhost. Inside the Compose network, localhost resolves to the container itself, not to the httpbin service. The CLI rejects loopback upstreams in dev mode for exactly this reason.

The port is auto-assigned from the 10001-10020 pool. On a fresh stack the first expose lands on 10001; if you've exposed services already, check the Port: line in the output.

4. Verify the request reached Envoy

curl http://localhost:10001/get
{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Host": "localhost:10001",
    "User-Agent": "curl/8.7.1",
    "X-Envoy-Expected-Rq-Timeout-Ms": "15000"
  },
  "origin": "10.89.0.5",
  "url": "http://localhost:10001/get"
}

The X-Envoy-Expected-Rq-Timeout-Ms header is the proof: httpbin doesn't generate it, Envoy does. The request entered the gateway on port 10001, ran through the listener's filter chain, matched the catch-all route, and was forwarded to the httpbin:80 cluster.

That's the loop. You have a working API gateway.

5. Tear down

flowplane down             # stop containers, keep data
flowplane down --volumes   # stop and delete all data

Use --volumes if you want a clean slate next time. Without it, the database, audit log, and any resources you created persist across init cycles.

Next steps

You've shipped one route. The how-to recipes pick up from there:

Or, depending on where you go next: