Getting Started

This guide gets you from zero to a running HAProxy UI in under 10 minutes. You will install dependencies, bring up a local HAProxy + Dataplane API stack, point the UI at it, and apply a real configuration change.

Who is this for?

  • Platform engineers and SREs evaluating HAProxy UI for their edge / ingress tier

  • Developers who want to try the graph editor without touching a production cluster

Prerequisites

  • Node.js 20+ and pnpm 9+

  • macOS, Linux, or Windows for the browser build

  • For the desktop build only: a Rust toolchain (rustup, stable channel) and the platform prerequisites below

  • Docker + Docker Compose for the local Dataplane stack (optional — the app runs fully against a built-in mock fixture with no cluster at all)


Step 1 — Get the code

git clone https://gitlab.starstorm.dev/starstorm/ha-proxy-ui.git
cd ha-proxy-ui
pnpm install

Platform prerequisites for the desktop build:

  • macOS — Xcode Command Line Tools (xcode-select --install)

  • Linux — libwebkit2gtk-4.1-dev, libgtk-3-dev, libayatana-appindicator3-dev, librsvg2-dev, libsoup-3.0-dev, libssl-dev, patchelf, build-essential, curl, wget, file

  • Windows — WebView2 runtime (preinstalled on Windows 10+)


Step 2 — Run against the mock first

The fastest way to see the editor work is with no cluster at all. An instance with no baseUrl is served by mockClient, an in-memory fixture with a 150 ms simulated latency.

pnpm dev

Open http://localhost:5173. You should see the topology canvas with the fixture frontends, backends and servers already laid out. Drag a node, open its inspector, edit a field — everything works. Nothing has been sent anywhere.

Tip: The canvas is pan-and-pinch, not drag-and-drop-to-reparent in this build. Click a node to focus its inspector panel; edges follow from the Frontend → Backend → Server structure.


Step 3 — Bring up a local Dataplane stack

To exercise the real read/write/apply path you need an actual HAProxy and its Dataplane API. The bundled compose file runs haproxy:3.1 plus haproxytech/dataplaneapi:3.1:

docker compose up -d

Port

Service

80

HAProxy

5555

Dataplane API

8404

HAProxy stats page

The local stack is seeded with HTTP Basic auth admin:admin and is otherwise unauthenticated-in-spirit — a development convenience only.


Step 4 — Point the UI at it

Copy the environment template and point the dev server at the Dataplane through the Vite proxy. This is the recommended browser setup because the browser then only ever makes same-origin requests — no CORS preflight, nothing to configure on the Dataplane side.

cp .env.example .env
echo 'PUBLIC_DATAPLANE_BASE_URL=/dataplane' >> .env
pnpm dev

The Vite dev server forwards /dataplane/* to http://localhost:5555/*. To send it somewhere else:

DATAPLANE_PROXY_TARGET=http://elsewhere:5555 pnpm dev

Leave PUBLIC_DATAPLANE_API_TOKEN empty for the local stack. Then create an instance in the sidebar with the URL /dataplane and Basic credentials admin:admin. The moment an instance has a baseUrl, the UI switches from mockClient to realClient.


Step 5 — Verify a read / write / apply cycle

Confirm the read path first — the canvas should now show your cluster's actual backends rather than the fixture.

curl -s http://localhost:5555/v3/services/haproxy/configuration/version -u admin:admin

Then, in the UI:

  1. Open a backend node and change its balance algorithm.

  2. The pending-changes bar appears at the bottom with your unsaved edit.

  3. Open the diff panel — you should see a red/green diff against the live configuration.

  4. Click Apply. The write goes to the Dataplane API scoped to a transaction, then a graceful reload is triggered.

  5. Re-open the backend — the change persisted.

If the apply is rejected because the live config moved underneath you, you will get a conflict dialog offering Reload & re-diff rather than a generic error. See Operations & Troubleshooting.


Step 6 (optional) — Run the desktop build

The desktop app is the same UI packaged as a native window, with a Rust backend that brokers every outbound call.

pnpm dev:tauri # native window with HMR against the Vite dev server
pnpm build:tauri # signed installer for the host OS

In Tauri mode you do not need the Vite proxy or any CORS configuration: requests originate in Rust via reqwest, so any URL the host can reach works directly, including the absolute http://localhost:5555. Enter the absolute URL in the instance dialog. Tokens are resolved from the OS keychain inside Rust and never cross the webview boundary. Full checklist: docs/verify-desktop.md.


What's next


Was this article helpful?