Pulse
Service registry and shared configuration layer. Beacon apps register with
it out of the box, and any Go service can join through the client SDK at
pkg/sdk — tap into shared indexers, quality profiles, download
clients, and media-handling settings with a single client instance.
Features
What Pulse does
Service registry
Each Beacon service registers on startup with its name, type, URL, and capabilities, then heartbeats periodically. Move Pilot to a new host — Prism picks up the address on the next heartbeat cycle with no config edits.
Indexer management
Indexers — the search APIs that catalog torrent and Usenet releases — usually mean a Torznab or Newznab endpoint. Add one to Pulse and it's auto-assigned to every service whose capabilities match the indexer's catalog category: Movies-tagged indexers reach Prism, TV-tagged reach Pilot. A built-in catalog with pre-filled setting schemas, one-click add, and a tester that verifies connectivity before saving make first-time setup quick.
Quality profile management
A quality profile is a ranked list of acceptable resolutions, sources, and codecs plus an upgrade cutoff — what the manager will and won't grab, and when it stops looking for something better. Profiles live in Pulse and mirror to Pilot and Prism with a managed_by_pulse flag: synced copies are read-only, local-only profiles still work for per-app overrides. Edit a 1080p cutoff once in Pulse and both services update on the next sync.
Shared download clients
When Haul registers as a download client, Pulse auto-creates the entry and shares its address and API key with Pilot and Prism through the registration handshake. No manual key-copy step, no "add download client in each app's settings."
WebSocket event stream
Pulse pushes live updates over /ws and fires per-service sync hooks the moment shared state changes — indexer added, quality profile edited, settings updated. Consumers don't have to wait for the next 30-second poll.
Go client SDK
A drop-in SDK at pkg/sdk for any Go service. Register with retry backoff, auto-heartbeat on a 30-second tick, discover peers by type or capability, pull assigned indexers, and read shared config — all with one client instance.
Interface
Dashboard
React 19 + TypeScript UI embedded in the Go binary. No separate server to run.
Technical
Advanced features
API surface
Full REST API (Huma v2 + Chi v5) under /api/v1/. OpenAPI docs at /api/docs. WebSocket event stream at /ws. Everything the UI does is available over HTTP.
SDK — register and pull
client, _ := sdk.NewWithRetry(sdk.Config{ PulseURL: "http://pulse:9696", ServiceName: "pilot", ServiceType: "media-manager", APIURL: "http://pilot:8383", Capabilities: []string{"content:tv", "supports_torrent"}, }) indexers, _ := client.MyIndexers(ctx) clients, _ := client.DiscoverByType(ctx, "download-client")
Storage
Postgres-backed state with Goose migrations and SQLC-generated type-safe query code. Zero configuration out of the box — all settings editable in the UI or via PULSE_* environment variables.
Tag management
Central tag registry with usage counts. Tags drive indexer assignment (tv, movies, all), notification routing, and library filtering across every service — managed once in Pulse.
Install
Getting started with Pulse
Standalone Docker for a single-service install. Full stack compose in beacon-stack/deploy.
docker run -d \ --name pulse \ -p 9696:9696 \ -v /path/to/config:/config \ ghcr.io/beacon-stack/pulse:latest
Open http://localhost:9696 — Pulse starts with zero additional configuration.
Configuration
Environment variables
| Variable | Default | Description |
|---|---|---|
PULSE_PORT | 9696 | Host port for the web UI and API. Set in .env if 9696 is taken on your host. |
PULSE_CONFIG_PATH | ./config/pulse | Where Pulse's config.yaml and cached state live. Override to put configs on a different volume. |
PULSE_FLARESOLVERR_URL | — | FlareSolverr endpoint for Cloudflare-protected indexers. Opt-in: uncomment in docker-compose.yml and set COMPOSE_PROFILES=flaresolverr. |
PULSE_DASHBOARD_DOCKER_SOCKET | — | Path to the Docker socket. Enables container resource panels in the dashboard. Opt-in: uncomment both this var and the /var/run/docker.sock mount in docker-compose.yml. |
PULSE_DASHBOARD_GLUETUN_URL | — | Gluetun control-server URL for the dashboard's VPN panel. Auto-set to http://vpn:8000 when the VPN overlay is active. |
LOG_LEVEL | info | Set once in .env; Compose passes the same value to every Beacon service. debug, info, warn, error. |
TZ | UTC | IANA timezone (e.g. America/New_York). Set once in .env and applied to every service for log timestamps and scheduled tasks. |