Guides
Web dashboard
pulseui is the pulse web dashboard: a single Go binary serving server-rendered HTML
(htmx for live polling — no Node, no build step). It reads queue state and performs
every action through the pulse SDK over gRPC, exactly like any other client; it never
connects to the database.
Run it
docker compose up # included in the repo compose file: http://localhost:8080
docker run -p 8080:8080 -e PULSE_ADDR=host:50051 bete7512/pulse-ui
go run ./ui/pulseui # from a clone| variable | default | description |
|---|---|---|
PULSE_ADDR | localhost:50051 | pulsed gRPC address |
PULSE_USER / PULSE_PASSWORD | — | fixed service credentials: skips the login flow |
PULSE_UI_PORT | 8080 | HTTP listen port |
Sign-in
The dashboard follows the server's authentication:
- Env credentials set — every request uses them; no login page. The mode for a single operator or the compose stack.
- No env credentials, open server — no login; straight to the dashboard.
- No env credentials, server with
PULSE_AUTH_USERS— a login page. Credentials are verified againstpulseditself, and each browser session holds its own connection dialed with that user's credentials — so cancel, requeue, and pause in the server's audit log carry the signed-in username, not a shared service account.
Sessions live in memory for 24 hours (sliding); restarting pulseui signs everyone
out.
Screens
- Dashboard — job counts per status, per-topic breakdown, a throughput chart (completed vs dead-lettered over the last hour), the age of the oldest waiting job, and the dispatch pause switch. Refreshes every few seconds.
- Jobs — filterable by status and topic, paginated, with each job's payload preview (full payload on hover) and per-row actions: cancel a job that hasn't started, requeue a dead-lettered or canceled one.
- Job detail — full state: attempts against the cap, last error, lease owner, timestamps, and the pretty-printed payload.
- Schedules — definitions with next/last run, pause/resume/delete.
Notes
- Responses carry a restrictive
Content-Security-Policy(frame-ancestors 'none'), and state-changing requests must originate from the dashboard's own pages — cross-site POSTs are rejected. - The dashboard serves plain HTTP; put TLS termination in front of it before exposing it beyond a trusted network.