Buzz セルフホスト型チュートリアル: Codex、Claude Code、およびチーム用のプライベート エージェント ワークスペースをセットアップする

Block Buzz を VPS にデプロイし、Nostr Relay、PostgreSQL、Redis、オブジェクト ストレージの関係を理解し、ドメイン名、TLS、エージェント ID、バックアップ、モニタリング、パブリック ネットワーク セキュリティを構成します。

Buzz は、Block のオープンソースの共同ワークスペースです。人、AI エージェント、コード リポジトリ、パッチ、承認、ワークフロー、チャネル、音声コラボレーションを同じシステムに配置し、Nostr 署名イベントを使用して操作を記録します。 これは単純な「マルチプレイヤー チャット フロント エンド」ではありません。 Buzz では、エージェントは独自の ID とチャネル メンバーシップを持ち、履歴の検索、リポジトリのオープン、パッチの送信、レビューへの参加、ワークフローの実行を行うことができます。セルフホスティングのポイントは、チームがリレー、データ ストレージ、ドメイン名、監査レコードを制御することです。 この記事はリモート VPS の展開に焦点を当てています。 Buzz はまだ急速な開発段階にあり、リポジトリの構造、環境変数、および Compose ファイルが変更される可能性があります。したがって、この記事では、安定して再利用できるデプロイメントの判断を公式コマンドから分離します。特定の変数は常に、使用している .env.example のバージョンとデプロイメント ドキュメントの影響を受けます。

Buzz のデータ フローは、まず理解してから展開する必要があります。

ブラウザまたはデスクトップ クライアントは、すべての状態をローカルに直接保存しません。一般的な自己ホスト型インスタンスには、次のものが含まれます。

  • Buzz Web、デスクトップ、またはモバイル クライアント、
  • 署名済みイベントを処理する Nostr Relay、
  • 構造化された状態を保存する PostgreSQL、
  • キャッシュ機能とキューイング機能を提供する Redis、
  • 保存するため添付ファイル S3 互換オブジェクト ストレージ。
  • パブリック ネットワークに HTTPS を提供する Caddy またはその他のリバース プロキシ。 現在の公式の単一リレー構造では、1 つのリレー URL が 1 つのコミュニティに対応します。オペレーターが共有インフラストラクチャ上で複数のコミュニティをホストしている場合でも、ユーザーがアクセスする URL は依然としてワークスペースの境界です。 すべてのメッセージ、反応、ワークフロー ステップ、レビューの承認、および Git イベントは署名されたイベントです。オブジェクト ストレージをバックアップせずにデータベースをバックアップすると、添付ファイルが失われます。添付ファイルのみをバックアップし、ID とデータベースを無視した場合、ワークスペースを完全に復元することはできません。

マシンとドメイン名の選択

テスト環境は、4 コア、8 GB メモリ、80 GB SSD で開始できます。実際の要件は、同時ユーザーの数、エージェントの数、リポジトリのサイズ、添付ファイル、音声の使用状況によって異なります。 本番環境では少なくとも以下を準備する必要があります。

  • サポートされている Linux VPS、
  • buzz.example.com などの独立したサブドメイン名、
  • 80 ポートと 443 ポートが使用可能、
  • Docker エンジンCompose プラグイン。
  • スナップショットやオフサイト バックアップに使用できるストレージ。
  • SMTP やオブジェクト ストレージなど、プロジェクトで実際に必要な外部サービス。 Relay、PostgreSQL、Redis、MinIO の管理ポートをパブリック ネットワークに直接公開しないでください。パブリック ネットワークの入り口には HTTPS のみを使用し、SSH では送信元アドレスまたは VPN 経由のアクセスを制限する必要があります。 DNS はまず、VPS を指す A/AAAA レコードを作成します。 Cloudflareプロキシを使用する場合、初回の証明書発行時やWebSocketのデバッグ時に一時的に「DNSのみ」に設定し、サービスが正常であることを確認してからプロキシを有効にすることができます。

Docker のインストール

以下では、例として Ubuntu/Debian を取り上げます。本番環境では、ディストリビューションの古いパッケージに長期間依存するのではなく、Docker 公式リポジトリの使用を優先する必要があります。 最初にシステムを確認します:

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

インストール後に確認します:

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

一般ユーザーに docker グループへの参加を許可することは、root に近い権限を付与することと同じです。サーバーが複数のユーザーによって共有されている場合は、sudo を保存するためだけにこのグループに参加しないでください。 ディスクとメモリを確認します。

1
2
df -h
free -h

ルート パーティションが十数 GB しかない場合、サービスを開始できたとしても、ミラー、データベース WAL、および添付ファイルのスペースがすぐに足りなくなります。

Buzz のバージョンを固定する

別のディレクトリを作成します:

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

公式リポジトリのクローンを作成します:

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

運用環境が main を永久に追従しないようにしてください。リリースまたはコミットを表示し、テストしたバージョンをピン留めします。

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

その時点で適切な安定したラベルがない場合は、少なくともデプロイメント コミット SHA を記録します。

1
git rev-parse HEAD

アップグレード前に構成とデータベース移行の変更を正確に比較するために。

Compose とサンプル設定を読む

Buzz リポジトリは、docker-compose.yml、Dockerfile、および .env.example を提供します。まだ直接開始しないでください:

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

キーの確認:

  • どのサービスがパブリック ネットワーク ポートをリッスンするか。
  • データベース、Redis、オブジェクト ストレージが内部ネットワーク上にのみ存在するかどうか、
  • ボリュームがホストまたは Docker の名前付きボリュームにマウントされているかどうか、
  • デフォルトのパスワードがまだ存在しているかどうか、
  • リレー URL が外部アクセス URL と一致しているかどうか、
  • かどうかCaddy/TLS が有効な構成です。 環境ファイルをコピーします:
1
2
cp .env.example .env
chmod 600 .env

.env を Git に送信したり、完全なコンテンツを作業指示書に投稿したりしないでください。

次の例の値の代わりに認証情報を生成します。

OpenSSL を使用してランダムな値を生成できます。

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

データベース、オブジェクト ストレージ、アプリケーション署名、および管理者の起動認証情報は個別に生成する必要があり、パスワードを共有することはできません。 パスワード マネージャーに記録します:

  • 目的、
  • 作成日、
  • 環境、
  • 責任者のローテーション、
  • 回復方法。 変数に $#、スペース、または引用符が含まれている場合、Compose は予想とは異なる解析を行う可能性があります。変更後に実行:
1
docker compose config >/dev/null

このコマンドは、欠落している変数や YAML エラーを見つけることができますが、すべてのアプリケーション設定が有効であることを証明するものではありません。

最初の起動とログの判断

イメージをプルまたはビルドする:

1
2
docker compose pull
docker compose build --pull

リポジトリのバージョンは異なるため、どちらか 1 つだけが必要になる場合があります。 Compose の image または build フィールドを取得します。 バックグラウンド起動:

1
docker compose up -d

ステータスの表示:

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

コンテナが Up であることを確認して終了しないでください。データベースの移行、リレーの起動、オブジェクト ストレージ接続、および Web サービスのヘルス チェックを引き続き観察します。 単一サービスをリアルタイムで追跡する:

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

サービス名は docker compose config --services から取得されます。記事に基づいて推測しないでください。

ドメイン名、HTTPS および WebSocket

リポジトリに付属の Caddy を使用する場合は、外部ドメイン名が .env の URL とまったく同じであること、DNS がサーバーを指していること、および 80/443 が他のプログラムによって占有されていないことを確認してください。 ポートを確認します:

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

すでに Nginx を使用している場合は、Buzz が 127.0.0.1 の上位ポートのみをリッスンし、Nginx によって転送することができます。リレーおよびリアルタイム コラボレーションは長時間の接続に依存しており、リバース プロキシは WebSocket アップグレードを正しく処理する必要があります。 一般的な Nginx スニペットは次のとおりです。実際のアップストリーム ポートは 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;
}

証明書と応答を確認します。

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

ブラウザはホームページを開けることはできますが、チャネルは切断され続けます。通常は、WebSocket、外部 URL、プロキシ タイムアウト、Cloudflare 設定を確認する必要があります。

コミュニティと管理者の作成

最初の起動プロセスはバージョンによって異なる場合があります。管理者を作成する前に、サイトでパブリック ネットワークへの匿名登録が許可されていないことを確認してください。 推奨事項:

  1. 一時的にファイアウォールを使用してアクセス元を制限します。
  2. 管理者の作成を完了します。
  3. 不要なオープン登録を閉じます。
  4. 通常のメンバーのテスト アカウントを確立します。
  5. チーム アクセスを再度開きます。 管理者アカウントは管理のみに使用されます。日次エージェントに管理者 ID を共有させないでください。各エージェントには、独立したキー、チャネル メンバーシップ、および監査証跡が必要です。

Codex、Claude Code、およびその他のエージェントへのアクセス

Buzz リポジトリには、エージェント指向のスキルとツールが含まれており、ACP ハーネス関連のコンポーネントも提供します。特定のインストール方法は、現在のバージョンのドキュメントに従って実行する必要があります。 アクセスするときは、まず権限の低いテスト チャネルを確立し、機密情報のないデモ リポジトリのみを承認します。 検証シーケンス:

  • エージェントは指定されたチャネルを読み取ることができるかどうか、
  • 結合されていないプライベート チャネルを読み取ることができないかどうか、
  • 指定されたリポジトリを開くことができるかどうか、
  • パッチを送信するために手動確認が必要かどうか。
  • ワークフローの実行でエージェント ID が記録されるかどうか。
  • エージェント キーが取り消された直後に無効になるかどうか。 ホストの Docker ソケット、サーバーの SSH 秘密キー、または組織レベルの GitHub トークンをエージェントに直接渡さないでください。 Buzz の ID 分離は、基礎となる資格情報からの過剰なアクセス許可を自動的に無効にすることはありません。

リポジトリ、パッチ、承認の最小限のテスト

機密データを含まないテスト リポジトリを準備し、単純な問題を作成し、エージェントがパッチを直接マージせずにパッチのみを生成できるようにします。 手動検査:

  • 元のリクエストがチャネル内で見つかるかどうか、
  • パッチが正しい送信に対応しているかどうか、
  • CI 結果が同じレコードに関連付けられているかどうか、
  • レビュー承認者が独立したアイデンティティであるかどうか。
  • 最終的な合併の理由を追跡できるかどうか。 Buzz には、これらのイベントを検索可能なレコードに保存できるという利点があります。チームが依然として共有アカウントや外部スクリプトを介して承認をバイパスしている場合、この利点は失われます。

バックアップ対象は 1 つのディレクトリだけではない

最初に Compose からすべてのボリュームを確認してください:

1
2
docker compose config --volumes
docker volume ls

データベースは論理バックアップを使用しています:

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

サービス名、ユーザー名、およびデータベース名は、実際の構成に従って置き換える必要があります。オブジェクト ストレージ バケットをバックアップし、.env の暗号化されたコピーを保存します。 回復可能なバックアップには少なくとも以下が含まれている必要があります:

  • PostgreSQL データ、
  • オブジェクト ストレージ ファイルとメタデータ、
  • リレーまたはアプリケーション永続ボリューム、
  • 現在の .env およびリバース プロキシ設定;
  • デプロイコミット SHA;
  • 復元操作の手順。 少なくとも月に 1 回、隔離されたマシンで復旧訓練を実施します。回復検証を行わないバックアップは、単なる「役立つ可能性のあるファイル」にすぎません。

ログ、メトリクス、容量

最初に Docker を使用してリソースを表示します。

1
2
docker stats
docker system df

モニタリングの対象範囲は少なくとも次のとおりです。

  • HTTPS の可用性、
  • リレーの長い接続エラー、
  • PostgreSQL の数接続とディスク、
  • Redis メモリと削除、
  • オブジェクト ストレージ容量、
  • コンテナの再起動数、
  • 最後に成功したバックアップ時刻。 ログには、チャネル名、リポジトリのアドレス、またはユーザー ID が含まれる場合があります。一元収集中にアクセス制御と保存期間を設定し、デバッグ ログをサードパーティの貼り付けサービスに公開しないでください。

アップグレードとロールバック

アップグレード前に現在のステータスを記録します。

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

データベースとオブジェクト ストレージのバックアップを完了し、現在のバージョンからターゲット バージョンへの変更ログを読み取ります。 修正バージョンの更新後:

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

新しいバージョンで不可逆的なデータベース移行が実行される場合、古いミラーに切り替えるだけではロールバックされない可能性があります。検証は、アップグレード前のバックアップを使用してスタンドアロン環境に復元する必要があります。

一般的な障害

コンテナが繰り返し再起動する

docker compose logs <service> を実行し、最初のエラーを探します。一般的な理由は、変数の欠落、データベースの準備ができていない、権限、または移行の失敗です。

ログイン後にチャンネルが表示されない

現在の URL が正しいコミュニティを指しているかどうか、ユーザーがチャンネルに参加しているかどうか、キーが変更されているかどうかを確認してください。データベースを削除せずに、最初に再構築してください。

添付ファイルのアップロードに失敗しました

オブジェクト ストレージ エンドポイント、バケット、アクセス キー、リバース プロキシ アップロード サイズ、ディスク容量を確認してください。

ページは正常ですが、リアルタイム メッセージが切断されます

WebSocket のアップグレード、Cloudflare プロキシ、アイドル タイムアウト、およびリレー外部 URL を確認してください。

エージェントはアクセスすべきではないリポジトリを確認できます。

エージェントの認証情報を直ちに取り消し、Buzz チャンネルのメンバーシップと基礎となる Git トークンを確認します。組織レベルのトークンの共有は、多くの場合、権限拡張のソースとなります。

ディスクは増大し続けます

データベース、オブジェクト ストレージ、コンテナ ログ、およびクリーンアップされていないイメージを個別に確認します。

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

パスを確認せずに Docker データ ディレクトリを再帰的に削除しないでください。

オンラインにする前のチェックリスト

  • ドメイン名と HTTPS は正常で、証明書は自動的に更新できます。
  • 必要なポートのみがパブリック ネットワークに公開されています。
  • デフォルトのパスワードとシークレットの例はすべて置き換えられています。
  • 管理者と日常エージェント共有 ID はありません。
  • プライベート チャネルの分離は 2 つのアカウントによってクロステストされます。
  • エージェントはテスト リポジトリと必要なツールのみにアクセスできます。
  • データベース、オブジェクト ストレージ、構成はすべてバックアップされます。
  • リカバリ ドリルは成功しました。
  • ログには出力キー;
  • バージョンとアップグレードのロールバック方法が記録されています。 Buzz は、ID 境界と監査記録を保持しながら、エージェントを実際のチーム メンバーとして管理したいチームに適しています。まず小さなコミュニティを使用して、権限、データ回復、コラボレーション方法を検証し、次に実稼働リポジトリを移行するかどうかを決定します。これは、すべてのエージェントを一度に接続するより安全です。

Buzz の導入資料