KO
|
EN
gitlite β search
Search
#typescript
#ai-agents
#ai
#dsh-plugin
#deepseek-harness
#open-source
#claude-code
#codex
#cli
#developer-tools
#react
#windows
selfhost-buzz
β 66
Open GitHub β
Selfhost https://buzz.xyz
Download README (.md)
Explore Similar Repositories
buzzbot
:
π€ Beep Boop Bop β I am BuzzBot; a facebook messenger bot for newsrooms
buzzphonics
:
Buzzphonics is a sounds app for parents and kids to learn Phase 2 and Phase 3 phonics in the UK. Built with React and with love.
OldBuzzEngine
:
Commenting system, similar to Disqus, but simpler and running on Google App Engine
Foundations-of-Machine-Learning
:
We're excited to be your gateway into machine learning. ML is a rapidly growing field that's buzzing with opportunity.
buzzdb
:
Educational database system developed at Georgia Tech
// repository documentation
Was this content helpful?
β 0
(0 ratings)
Select Rating:
β
β
β
β
β
Submit Feedback
Recent Feedback
×
Download README
Do you want to download the
README.md
file for
selfhost-buzz
?
Download (.md)
# selfhost-buzz Run your own [Buzz](https://github.com/block/buzz) Nostr relay on a machine you own, reachable only over your [Tailscale](https://tailscale.com) network. Buzz is a Nostr relay plus a platform for AI agents that live in your chats. Hosting it yourself means your messages, uploads and agent traffic stay on your own hardware. ## Why Tailscale A relay has to be reachable to be useful, but you almost certainly don't want to expose one to the open internet β that means port forwarding, a public DNS record, certificate management and an attack surface. Tailscale sidesteps all of it. The relay joins your private network as its own machine, gets a stable name like `buzz.tail1a2b3.ts.net` and a real Let's Encrypt certificate, and is reachable from every device signed into your Tailscale account β laptop, phone, anywhere in the world β while remaining completely invisible to everyone else. Nothing is published to the host and no router config is needed. That's the whole ingress story here: `tailscale serve` terminates TLS and proxies to the relay. If a device isn't on your tailnet, the relay may as well not exist. ## What runs ``` <you, anywhere on your tailnet> β wss:// + https:// βΌ buzz.<your-tailnet>.ts.net ββ Tailscale node (TLS terminated here) β ββ / βββΊ buzz relay ββ /pair βββΊ buzz-pair device pairing sidecar (NIP-AB) β ββββΊ buzz-postgres events, members, channels ββββΊ buzz-redis pub/sub fan-out ββββΊ buzz-minio media uploads + git objects ``` Nothing binds a host port. The Tailscale container is the only way in. ## Requirements - Docker with Compose v2 - A Tailscale account (the free tier is plenty) - A machine that stays on β a spare Mac, a NUC, a home server, a VPS - A Nostr identity, which the [Buzz app](https://github.com/block/buzz) creates for you on first launch ## Docs - [docs/tailscale.md](docs/tailscale.md) β setting up a tailnet, creating the auth key, sharing the relay with other people - [docs/local-llm.md](docs/local-llm.md) β pointing agents at Ollama or LM Studio instead of a hosted API --- ## Setup ### 1. Set up Tailscale **Full walkthrough: [docs/tailscale.md](docs/tailscale.md)** β start there if you don't already have a tailnet. The short version: 1. Install Tailscale on the host machine and on every device you want to use Buzz from, signing them all into the same account. 2. In the [admin console](https://login.tailscale.com/admin) **DNS page**, enable **MagicDNS** and **HTTPS Certificates**, and note your **tailnet name** β `tail1a2b3.ts.net`, or a word pair like `honey-bee.ts.net`. 3. On the **Keys page**, generate an auth key with **Reusable** ticked. A one-shot key works exactly once, and every later container restart then fails with `invalid key: API key does not exist`. ### 2. Configure ```bash git clone https://github.com/ciram-co/selfhost-buzz cd selfhost-buzz scripts/setup.sh ``` That writes a `.env` with all the random secrets already generated. Open it and fill in the three things only you can provide: | Variable | Where it comes from | |---|---| | `TS_TAILNET` | your tailnet name, e.g. `tail1a2b3.ts.net` | | `TS_AUTHKEY` | the reusable auth key from step 1 | | `BUZZ_RELAY_OWNER_PUBKEY` | your own Nostr pubkey, 64-char **hex** (not `npub`) | Everything public is derived from `TS_TAILNET`, so there's exactly one place to change if you rename things: ``` BUZZ_HOSTNAME=buzz + TS_TAILNET=tail1a2b3.ts.net ββββΊ wss://buzz.tail1a2b3.ts.net relay https://buzz.tail1a2b3.ts.net/media uploads https://buzz.tail1a2b3.ts.net/pair device pairing ``` `BUZZ_RELAY_OWNER_PUBKEY` is you β the account that administers the relay. In the Buzz desktop app it's under your profile; copy the hex form, not the `npub` form. Note this is **different** from `BUZZ_RELAY_PRIVATE_KEY`, which is the relay's own identity and is generated for you. Keep them separate: the relay signs its own events, and it shouldn't do that with your personal key. ### 3. Start it ```bash docker compose up -d scripts/check.sh ``` First boot takes a minute or two β the database migrates, MinIO runs a conformance probe, and Tailscale provisions a certificate. `scripts/check.sh` tells you whether the relay is answering at its public address. ### 4. Let yourself in The relay ships closed: only pubkeys you've explicitly added can connect. ```bash scripts/members.sh add <your-npub-or-hex> admin scripts/members.sh list ``` Add people one at a time, a couple of seconds apart. The roster is published as a single signed event, and simultaneous adds can overwrite each other. ### 5. Connect a client In the Buzz app, add your relay: `wss://buzz.<your-tailnet>.ts.net` For a phone, use **Settings β Pair device** in the desktop app β that's what the `/pair` sidecar is for. The phone has to be on your tailnet too. --- ## Everyday use ```bash docker compose up -d # start docker compose down # stop (keeps all data) docker compose ps # status docker compose logs -f buzz # follow relay logs scripts/check.sh # is it reachable? scripts/members.sh list # who's allowed on scripts/backup.sh # dump the database to backups/ scripts/reset-data.sh # wipe all data, keep the hostname ``` ### Upgrading ```bash docker compose pull && docker compose up -d ``` Pin `BUZZ_VERSION` rather than tracking `main`. Buzz publishes **`sha-<7>` image tags, not semver** β `ghcr.io/block/buzz:v0.4.25` doesn't exist. Resolve a release to its tag: ```bash gh api repos/block/buzz/commits/v0.4.25 --jq .sha # take the first 7 chars # -> BUZZ_VERSION=sha-e8105d1 ``` Postgres, Redis and MinIO are pinned in `docker-compose.yml`. Bumping Redis or MinIO is routine; **bumping Postgres across a major version is not** β the new server refuses to start on a data directory written by the old one. Dump first (`scripts/backup.sh`), start clean, and restore. ### Backups `scripts/backup.sh` covers the database, which holds messages, channels and members. Uploaded media lives in the MinIO volume and isn't included β back up the `selfhost-buzz_buzz-minio-data` volume separately if you care about it. The values in `.env` matter more than either. `BUZZ_RELAY_PRIVATE_KEY` **is** your relay's identity β regenerate it and every client sees a different relay. Save `.env` somewhere safe and don't commit it. --- ## Running agents against a local LLM Agents can run against Ollama or LM Studio on your own hardware instead of a hosted API. **Full walkthrough: [docs/local-llm.md](docs/local-llm.md)** β covers the model server on the same machine, on another machine over Tailscale, or in Docker. Two things to know up front: - **The relay never calls the LLM.** Agents run inside the Buzz *desktop app*, so the endpoint has to be reachable from the machine running the app, and putting these variables in `docker-compose.yml` does nothing. - **Pick a model that reliably emits tool calls.** Agents reply by *calling a tool*, not by producing prose. A model that decides "no tool call needed" and answers in plain text produces total silence in the chat β the harness discards the prose. If an agent goes quiet while the LLM is clearly being hit, this is almost always why; switch models before debugging anything else. Agents are also chatty by design: reactions, typing indicators, presence and telemetry mean a single "hi" can produce a dozen relay events. That's normal. --- ## Gotchas Things that cost real time to work out: - **Never `docker compose down -v`.** The `buzz-tailscale-state` volume *is* the node's machine identity. Delete it and Tailscale registers a new machine; since the old node still holds the name, yours becomes `buzz-1` and the URL silently breaks for every client. Recovering means deleting the stale node in the admin console, then waiting ~30s for a fresh certificate. Use `scripts/reset-data.sh` when you want a clean slate β it keeps the identity. - **Passwords must be hex, not base64.** They're interpolated straight into `DATABASE_URL` and `REDIS_URL`, and a `/` from `openssl rand -base64` breaks URL parsing with a thoroughly misleading `invalid port number`. `scripts/setup.sh` generates hex. - **Changing `BUZZ_POSTGRES_PASSWORD` after first boot doesn't take.** Postgres only applies it when initialising an empty data directory. Run `ALTER ROLE buzz WITH PASSWORD '...'` inside the container as well. - **The auth key must be reusable**, or only the first container start ever succeeds. - **Use MinIO, not an AWS mock.** Buzz's git-on-object-storage needs linearizable conditional writes, and localstack-style emulators don't guarantee them. `BUZZ_GIT_CONFORMANCE_PROBE` gates startup on exactly this, and the relay refuses to start if the backend fails it. - **The `/pair` sidecar is a separate binary.** It ships in the same image but the relay doesn't serve it, so without the `buzz-pair` service, device pairing fails with a 404 that gives no hint as to why. - **Wiping the database also wipes the member list.** With closed relay mode on, everyone β including your agents β is locked out until you re-add them. --- ## Troubleshooting ### "Community rejected: Load failed" The desktop client reports nearly every failure this way β it's WebKit's generic message, with no status code. Start by finding out whether the request reaches the relay at all: ```bash BUZZ_RUST_LOG='buzz_relay=info,tower_http=debug' docker compose up -d --force-recreate buzz docker logs buzz --since 2m | grep "processing request" ``` - **Requests appear** β it's an HTTP or CORS problem. Note that a CORS block still reaches the server and gets logged; only the browser discards the response. - **Nothing appears** β the failure is below HTTP, so CORS is ruled out. Since `tailscale serve` terminates TLS before proxying, a TLS failure also leaves no log. Compare `tailscale status` byte counters across a retry to tell "never left the machine" from "TLS failed". **On macOS, check Local Network permission first.** macOS 15+ requires apps to be granted permission before they can reach Tailscale `100.x` addresses β and terminal `curl` already has it while a GUI app does not. The symptom is maddening: `curl` works perfectly, the app fails, and the relay logs show nothing at all. Fix it under System Settings β Privacy & Security β Local Network. ### The hostname became `buzz-1` The Tailscale state volume was deleted. Remove the stale `buzz` node in the [admin console](https://login.tailscale.com/admin/machines), restart the container, and give it about 30 seconds to get a new certificate. ### `502 Bad Gateway` The Tailscale sidecar is proxying to itself. Its `hostname:` must not collide with the relay's service name β that's why it's `buzz-ts` here while `TS_HOSTNAME` carries the tailnet-visible name. ### Relay won't start: `Permission denied` on `/data/git` The `buzz-git-data-init` one-shot didn't run. The image runs as uid 1000 but Docker creates fresh volumes as root, so that container chowns the volume first. Check `docker compose ps -a` for it. --- ## License MIT β see [LICENSE](LICENSE). This repo is deployment configuration only. Buzz itself is a separate project; see [block/buzz](https://github.com/block/buzz) for its own license and docs.