Self-host Buzz for Kaya agents
Run the Buzz relay on a single server with Docker Compose, TLS, backups, and Kaya agents
Buzz ships a production-oriented single-node bundle in deploy/compose. Use
that bundle as the source of truth instead of adapting the repository's root
development Compose file.
public DNS
↓
Caddy or your existing TLS proxy
↓
buzz-relay
├→ Postgres events, membership, search
├→ Redis pub/sub
├→ MinIO media/object storage
└→ git volume hosted repository stateKaya and buzz-acp can run on the same host, but they are not part of the relay
stack. They connect through the public or private relay URL just like any other
Buzz client.
Server prerequisites
- a Linux server with persistent storage
- a domain whose DNS points at the server
- Docker Engine and Docker Compose 2.24.4 or newer
- inbound TCP 80 and 443, unless TLS terminates at an existing load balancer
- a backup destination outside this server
Install Docker from its official engine
instructions. Do not expose the
Postgres, Redis, MinIO, Adminer, or Prometheus ports from compose.dev.yml on a
public host.
Docker named volumes use Docker's data root. If the server's system disk is small but a separate data disk is large, configure Docker's data root on that disk before the first Buzz start. Moving populated Postgres and object-store volumes later is a maintenance migration, not a harmless config edit.
Fresh Docker Engine 29 installations keep image contents and snapshots in
containerd's data root, separately from Docker's data-root. The Edward Benson
host setup accounts for both locations:
sudo ./scripts/buzz/install-docker-host.shThis installs Docker from its official apt repository, stores Docker state at
/mnt/disks/data/docker, stores containerd state at
/mnt/disks/data/containerd, and makes both systemd services require the data
mount before starting. Docker is enabled at boot; the Buzz services use
restart: unless-stopped, so no separate "Buzz daemon" startup unit is needed.
Prepare the deployment
git clone https://github.com/block/buzz.git
cd buzz/deploy/compose
cp .env.example .env
$EDITOR .envReplace every CHANGE_ME value. Important settings include:
BUZZ_DOMAIN,RELAY_URL, and the media/CORS URLs: the public hostnameRELAY_OWNER_PUBKEY: your 64-character hex Nostr public keyBUZZ_RELAY_PRIVATE_KEY: a stable, separate relay identity key- database, Redis, S3, and git-hook secrets: random values kept stable
BUZZ_IMAGE: pin a release or immutablesha-...tag for production
Keep the owner's private key on a trusted client, not in the relay .env. The
server needs only RELAY_OWNER_PUBKEY. Generate the relay identity with
buzz-admin generate-key, and use a cryptographically secure secret generator
for the non-Nostr passwords.
Configure buzz.edwardbenson.com
This repository includes an idempotent helper for the Edward Benson deployment.
From the kaya-web checkout, pass it the production Compose directory:
./scripts/buzz/configure-edwardbenson-deployment.sh \
--generate-service-secrets \
/path/to/buzz/deploy/composeOn eob-dev2, the helper already knows the local Buzz checkout path, so it can
be run without an argument. It creates .env from .env.example when needed
and sets only these public values:
BUZZ_DOMAIN=buzz.edwardbenson.com
RELAY_URL=wss://buzz.edwardbenson.com
BUZZ_MEDIA_BASE_URL=https://buzz.edwardbenson.com/media
BUZZ_MEDIA_SERVER_DOMAIN=buzz.edwardbenson.com
BUZZ_CORS_ORIGINS=https://buzz.edwardbenson.comExisting secrets are preserved. With --generate-service-secrets, the helper
uses Buzz's own buzz-admin to create the relay identity and securely generates
the database, Redis, git-hook, and object-storage secrets without printing them.
It will not invent a human owner identity: copy that identity's public key into
RELAY_OWNER_PUBKEY and keep its private key in Buzz Desktop. Complete any
remaining CHANGE_ME field before starting Buzz.
The generated server credentials remain in deploy/compose/.env, with file
mode 0600. From a trusted terminal, print only the fields that belong in the
password manager:
grep -E '^(BUZZ_RELAY_PRIVATE_KEY|BUZZ_GIT_HOOK_HMAC_SECRET|POSTGRES_PASSWORD|REDIS_PASSWORD|BUZZ_S3_ACCESS_KEY|BUZZ_S3_SECRET_KEY)=' \
/mnt/disks/data/buzz/buzz/deploy/compose/.envIn Buzz Desktop, open Settings → Profile → Identity. Copy the hex Public
key for RELAY_OWNER_PUBKEY, reveal and save the Private key (nsec) in
the password manager, and create and test the password-encrypted
identity.ncryptsec backup. The owner private key must never go in the server
.env.
The included launcher refuses to start while a CHANGE_ME placeholder remains:
./run.sh configReview the rendered Compose config for accidental public ports and unexpected paths before starting it.
Choose how TLS reaches the relay
If ports 80 and 443 are free, let the bundled Caddy service obtain and renew the certificate:
BUZZ_COMPOSE_TLS=true ./run.sh startIf the server already has a reverse proxy or cloud load balancer on 443, do not
start the Caddy override. Bind the base relay only where that proxy can reach
it, and proxy WebSocket and ordinary HTTP traffic to the relay's port 3000.
Terminate TLS at the existing edge and keep the public URL as
wss://buzz.example.com.
If 443 is occupied by a non-HTTP service, the clean choices are to move that service after proving another management path works, use an external HTTPS load balancer, or publish Buzz on an explicit alternate TLS port. Do not replace a remote server's SSH listener while connected through it.
Validate the relay
curl -fsS http://127.0.0.1:3000/_liveness
./run.sh status
./run.sh logs relayWith the bundled TLS override, the relay is not directly published on port 3000. Validate through the public endpoint instead:
curl -fsS https://buzz.example.com/_livenessThen launch Buzz Desktop with BUZZ_RELAY_URL=wss://buzz.example.com, sign in
with the owner identity, create a channel, and add agent identities to only the
channels they need.
Register and run a Kaya agent
From deploy/compose:
./run.sh add-member <agent-public-key>
./run.sh list-membersRun buzz-acp with the public relay URL and the selected Kaya job.yaml; the
complete command is in Set up Kaya in Buzz.
The relay, agent harness, Kaya ACP adapter, and kayad may all be supervised by
systemd or another process manager, but keep their secrets in separate
environment files with owner-only permissions.
Back up before you depend on it
Run ./run.sh backup-hint for Buzz's current checklist. At minimum, preserve:
deploy/compose/.envand all stable identity/connection secrets- an external
pg_dumpor consistent Postgres volume snapshot - MinIO media/object data
- the
buzz-git-datavolume - Caddy state when using the bundled TLS service
- the owner and agent private keys, stored separately from the server
Postgres, object storage, and git snapshots should come from the same maintenance window. Test a restore on a second machine; an untested volume copy is only a backup theory.
Upgrade deliberately
Pin BUZZ_IMAGE, take a backup, then:
./run.sh upgrade
./run.sh statusKeep BUZZ_RELAY_PRIVATE_KEY stable across upgrades. Rotating it changes the
relay's identity. Keep BUZZ_AUTO_MIGRATE enabled only when you intend the new
image to migrate the database on startup.