Buzz Self-Hosted Tutorial: Set up a private Agent workspace for Codex, Claude Code and the team

Deploy Block Buzz on VPS, understand the relationship between Nostr Relay, PostgreSQL, Redis and object storage, and configure domain name, TLS, Agent identity, backup, monitoring and public network security.

Buzz is Block’s open source collaborative workspace. It puts people, AI Agents, code repositories, patches, approvals, workflows, channels, and voice collaboration into the same system, and uses Nostr signature events to record operations. It is not a simple “multiplayer chat front end”. In Buzz, Agents have their own identities and channel memberships, and can search history, open repositories, send patches, participate in Reviews, and run workflows. The point of self-hosting is that the team controls the Relay, data storage, domain names, and audit records. This article focuses on remote VPS deployment. Buzz is still in a period of rapid development, and the repository structure, environment variables, and Compose files may change. Therefore, this article separates deployment judgments that can be stably reused from official commands: specific variables are always subject to the version of .env.example and deployment documents you are using.

Buzz’s data flow needs to be understood first and then deployed

The browser or desktop client will not directly save all states locally. A typical self-hosted instance contains:

  • Buzz web, desktop or mobile client;
  • Nostr Relay to handle signed events;
  • PostgreSQL to save structured state;
  • Redis to provide caching and queuing capabilities;
  • To save attachments S3 compatible object storage;
  • Caddy or other reverse proxy that provides HTTPS to the public network. In the official current single Relay structure, one Relay URL corresponds to one community. Even if an operator hosts multiple communities on shared infrastructure, the URLs users access are still workspace boundaries. Every message, reaction, workflow step, Review approval, and Git event is a signed event. If you back up the database without backing up the object storage, you will lose attachments; if you back up only the attachments but ignore the identity and database, you will not be able to completely restore the workspace.

Select machine and domain name

The test environment can start with 4 cores, 8 GB memory, and 80 GB SSD. Actual requirements depend on the number of concurrent users, number of agents, repository size, attachments, and voice usage. The production environment must prepare at least:

  • A supported Linux VPS;
  • An independent subdomain name, such as buzz.example.com;
  • 80 and 443 ports are available;
  • Docker Engine and Compose plug-in;
  • Storage that can be used for snapshots or off-site backups;
  • External services actually required by projects such as SMTP and object storage. Do not directly expose the management ports of Relay, PostgreSQL, Redis and MinIO to the public network. The public network entrance should only have HTTPS, and SSH should restrict the source address or access through VPN. DNS first creates an A/AAAA record pointing to the VPS. If you use Cloudflare proxy, you can temporarily set it to “DNS only” when issuing certificates and debugging WebSocket for the first time, and then enable the proxy after confirming that the service is normal.

Installing Docker

The following takes Ubuntu/Debian as an example. The production environment should give priority to using the Docker official repository instead of relying on the distribution’s outdated packages for a long time. Confirm the system first:

1
2
uname -a
cat /etc/os-release

Verify after installation:

1
2
3
docker version
docker compose version
sudo systemctl enable --now docker

Allowing ordinary users to join the docker group is equivalent to granting close to root permissions. If the server is shared by multiple people, do not join this group just to save sudo. Look at disk and memory:

1
2
df -h
free -h

If the root partition is only a dozen GB, even if the service can start, the mirror, database WAL and attachments will quickly run out of space.

Get a fixed version of Buzz

Create a separate directory:

1
2
3
sudo mkdir -p /opt/buzz
sudo chown "$USER":"$USER" /opt/buzz
cd /opt/buzz

Clone the official repository:

1
git clone https://github.com/block/buzz.git .

Don’t let the production environment follow main forever. View Release or commit, pin the tested version:

1
2
git tag --sort=-version:refname | head
git log -1 --oneline

If there is no suitable stable label at that time, at least record the deployment commit SHA:

1
git rev-parse HEAD

In order to accurately compare configuration and database migration changes before upgrading.

Read Compose and sample configurations

The Buzz repository provides docker-compose.yml, Dockerfile and .env.example. Don’t start it directly yet:

1
2
3
sed -n '1,240p' .env.example
docker compose config --services
docker compose config > /tmp/buzz-compose-resolved.yml

Key confirmation:

  • Which service listens to the public network port;
  • Whether the database, Redis, and object storage are only on the internal network;
  • Is the volume mounted to the host or Docker named volume;
  • Whether the default password still exists;
  • Whether the Relay URL is consistent with the external access URL;
  • Whether Caddy/TLS is enabled configuration. Copy environment files:
1
2
cp .env.example .env
chmod 600 .env

Do not submit .env to Git, and do not post the complete content to the work order.

Generate credentials instead of following example values

You can use OpenSSL to generate random values:

1
2
openssl rand -hex 32
openssl rand -base64 48

Database, object storage, application signature and administrator boot credentials must be generated separately and cannot share a password. Record in the password manager:

  • Purpose;
  • Creation date;
  • Environment;
  • Rotation of responsible persons;
  • Recovery method. Compose may parse differently than expected if the variable contains $, #, spaces, or quotes. Run after modification:
1
docker compose config >/dev/null

This command can find some missing variables and YAML errors, but it will not prove that all application configurations are valid.

First startup and log judgment

Pull or build the image:

1
2
docker compose pull
docker compose build --pull

The repository versions are different, you may only need one of them. Take the image or build field in Compose. Background startup:

1
docker compose up -d

View status:

1
2
docker compose ps
docker compose logs --tail=200

Don’t just see that the container is Up and end it. Continue to observe database migrations, Relay startup, object storage connections, and web service health checks. Track a single service in real time:

1
docker compose logs -f --tail=100 <service-name>

The service name is obtained from docker compose config --services, do not guess based on the article.

Domain name, HTTPS and WebSocket

If you use Caddy that comes with the repository, make sure that the external domain name is exactly the same as the URL in .env, the DNS has pointed to the server, and 80/443 is not occupied by other programs. Check the port:

1
sudo ss -lntp | grep -E ':80|:443'

If you already have Nginx, you can let Buzz only listen to the high port of 127.0.0.1, and then forward it by Nginx. Relay and real-time collaboration rely on long connections, and the reverse proxy must handle WebSocket Upgrade correctly. The generic Nginx snippet is as follows, the actual upstream port needs to be confirmed from Compose:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 300s;
}

Verify certificate and response:

1
2
curl -I https://buzz.example.com/
openssl s_client -connect buzz.example.com:443 -servername buzz.example.com </dev/null

The browser can open the homepage but the channel keeps disconnecting, you should usually check WebSocket, external URL, proxy timeout and Cloudflare settings.

Creating communities and administrators

The first boot process may change from version to version. Before creating an administrator, make sure that the site does not allow anonymous registration to the public network. Recommendations:

  1. Temporarily use a firewall to restrict access sources;
  2. Complete administrator creation;
  3. Close unnecessary open registrations;
  4. Establish ordinary member test accounts;
  5. Open team access again. The administrator account is only used for management. Do not let daily Agents share the administrator identity. Each Agent should have independent keys, channel memberships, and audit trails.

Access to Codex, Claude Code and other Agents

The Buzz repository contains Agent-oriented skills and tools, and also provides ACP harness related components. The specific installation method must be performed according to the current version documentation. When accessing, first establish a low-privilege test channel and only authorize a demo repository without sensitive information. Verification sequence:

  • Can the Agent read the specified channel;
  • Whether it cannot read unjoined private channels;
  • Can the specified repository be opened;
  • Whether manual confirmation is required to send the patch;
  • Whether the workflow execution records the Agent identity;
  • Whether the Agent key becomes invalid immediately after being revoked. Do not hand over the host Docker Socket, server SSH private key or organization-level GitHub Token directly to the Agent. Buzz’s identity isolation does not automatically counteract excessive permissions from the underlying credentials.

Minimal testing of repository, patch and approval

Prepare a test repository without sensitive data, create a simple Issue, and let the Agent only generate patches without merging them directly. Manual inspection:

  • Whether the original request can be found in the channel;
  • Whether the patch corresponds to the correct submission;
  • Whether the CI results are associated with the same record;
  • Whether the Review approver is an independent identity;
  • Whether the reason for the final merger can be traced. Buzz has the advantage of putting these events in a searchable record. This advantage disappears if teams still bypass approvals through shared accounts and external scripts.

The backup cannot copy only one directory

Confirm all volumes from Compose first:

1
2
docker compose config --volumes
docker volume ls

The database uses logical backup:

1
docker compose exec -T postgres pg_dump -U <db-user> <db-name> > buzz.sql

The service name, user name and database name must be replaced according to the actual configuration. Back up the Object Storage Bucket and save an encrypted copy of .env. A recoverable backup must include at least:

  • PostgreSQL data;
  • Object storage files and metadata;
  • Relay or application persistent volumes;
  • Current .env and reverse proxy configuration;
  • Deployment commit SHA;
  • Restore operation instructions. Conduct a recovery drill on the isolated machine at least once a month. Backups without recovery verification are just “possibly useful files”.

Logs, metrics and capacity

Use Docker to view resources first:

1
2
docker stats
docker system df

Monitoring covers at least:

  • HTTPS availability;
  • Relay long connection error;
  • PostgreSQL Number of connections and disks;
  • Redis memory and elimination;
  • Object storage capacity;
  • Number of container restarts;
  • Last successful backup time. The log may contain channel name, repository address or user ID. Set access control and retention period during centralized collection, and do not expose debugging logs to third-party Paste services.

Upgrade and rollback

Record the current status before upgrading:

1
2
3
git rev-parse HEAD
docker compose images
docker compose ps

Complete the database and object storage backup, and then read the Changelog from the current version to the target version. After updating the fixed version:

1
2
3
4
git fetch --tags
git checkout <tested-tag-or-commit>
docker compose pull
docker compose up -d

If the new version performs irreversible database migration, just switching back to the old mirror may not be rolled back. Verification must be restored to a standalone environment using a pre-upgrade backup.

Common faults

Container restarts repeatedly

Run docker compose logs <service> and look for the first error first. Common reasons are missing variables, database not ready, permissions, or migration failure.

Cannot see the channel after logging in

Check whether the current URL points to the correct community, whether the user has joined the channel, and whether the key has changed. Do not delete the database and rebuild it first.

Attachment upload failed

Check the object storage endpoint, bucket, access key, reverse proxy upload size and disk capacity.

Page is OK but real-time messages are disconnected

Check WebSocket Upgrade, Cloudflare proxy, idle timeout, and Relay external URL.

Agent can see repositories that it should not access

Immediately revoke Agent credentials, check Buzz channel membership and underlying Git Token. Sharing organization-level tokens is often the source of permission expansion.

Disk continues to grow

Check the database, object storage, container logs, and uncleaned images individually:

1
2
sudo du -xh /var/lib/docker | sort -h | tail
docker system df

Do not recursively delete the Docker data directory without confirming the path.

Checklist before going online

  • The domain name and HTTPS are normal, and the certificate can be automatically renewed;
  • Only the necessary ports are exposed to the public network;
  • Default passwords and example Secrets have all been replaced;
  • Administrator and daily Agent No shared identity;
  • Private channel isolation is cross-tested by two accounts;
  • Agent can only access the test repository and required tools;
  • Database, object storage and configuration are all backed up;
  • The recovery drill was successful;
  • The log has no output key;
  • The version and upgrade rollback method have been recorded. Buzz is suitable for teams that want to manage Agents as real team members while retaining identity boundaries and audit records. First use a small community to verify permissions, data recovery and collaboration methods, and then decide whether to migrate the production repository. This is safer than connecting all Agents at once.

Buzz deployment resources