Harmony Chat
Guides

Self-host

Secrets, listeners, and what to expose.

Expose the Harmony Chat server and nothing else. Workers make outbound connections, so they need no inbound ports.

Listeners

harmony server start --listen loopback              # default
harmony server start --listen lan --port 8080       # LAN
harmony server start --listen tailnet               # Tailnet only
harmony server start --listen custom                # explicit bind

Loopback uses local_trusted: a request from 127.0.0.1 is trusted, so no login screen appears. Any other listener requires a claim step, and people join by invite.

Secrets

Set these before you move off loopback.

VariableGuards
JWT_SECRETSession tokens
INTERNAL_SECRETInternal API surfaces
ADMIN_SECRETAdmin operations
HARMONY_WORKER_TOKENWhich workers may dial this main server

Rotate before you expose

The development defaults in this repo are not secrets. Generate real values before a listener is reachable by anyone you did not invite.

Data

PGlite under $HARMONY_HOME/data/ is the product source of truth: messages, groups, files metadata, agent state. Back it up by stopping the server and copying that directory — one embedded database, one writer.

Workers

# on the extra machine
harmony server start --worker

A worker dials HARMONY_SERVER_URL over outbound WSS with a matching HARMONY_WORKER_TOKEN. It opens no inbound port and holds no copy of chat data.

Check what dialled in:

curl -sf -H "x-internal-secret: $INTERNAL_SECRET" \
  http://127.0.0.1:8080/api/v1/workers/status

Checklist before you expose

  1. Real values for all four secrets above.
  2. Narrowest listener that works — tailnet before lan, lan before a public bind.
  3. TLS terminator or reverse proxy in front of :8080 if clients are off-network.
  4. Clients pointed at the server URL — see Clients.
  5. Worker capacity visible in Settings → Capacity.