quartz-research-note/content/BlueskyのPDSをCloudflare Tunnel環境でセルフホストする.md

87 lines
6.4 KiB
Markdown
Raw Normal View History

---
date: "2024-02-08T15:53:17+0900"
---
#self-hosted #bsky
公式リポジトリ
- [GitHub - bluesky-social/pds: Bluesky PDS (Personal Data Server) container image, compose file, and documentation](https://github.com/bluesky-social/pds)
- 公式のリポジトリのコードはインストールスクリプトと、管理ツール`pdsadmin`コマンドのシェルスクリプトがあるだけで、実際のDockerイメージになるパッケージとかはatprotoのリポジトリ内にある
- [atproto/packages/pds at main · bluesky-social/atproto · GitHub](https://github.com/bluesky-social/atproto/tree/main/packages/pds)
日本語のリソース
- [一番詳しい ATProtocol PDS のセットアップガイド](https://zenn.dev/neody/articles/2efd51216be32c?cache)
- [Self-hosting PDSを建てる - Bluesky](https://scrapbox.io/Bluesky/Self-hosting_PDS%E3%82%92%E5%BB%BA%E3%81%A6%E3%82%8B)
- [さくらの VPS で Bluesky PDS Personal Data Server をセルフホストしてみる - WWW WATCH](https://hyper-text.org/archives/2024/02/bluesky_pds_self_hosting/)
- [DockerなしでBlueskyのPDSを建てる方法 | 点と接線。](https://riq0h.jp/2024/02/25/085804/)
基本的には公式のリソースに従うのが一番。インストールスクリプトを実行すると`/pds`ディレクトリ以下に必要なリソースをコピーして、Dockerのインストールも含めて面倒を見てくれるので、すでにDockerで色々立ち上げてる人には逆にめんどくさいかもしれない。DNSの設定とかをDockerホスト側の設定含めチェックする必要があるからこういうやり方にしている…っぽい。
私はせっかく[[Proxmox]]環境なので、諦めて一個LXCコンテナを増やすことにした。
## Cloudflare環境でのハンドル解決問題
BlueskyのATプロトコルはDNSレベルでのハンドル解決を行う。そのため、例えばサーバーを`bsky.matsuuratomoya.com`でホストすると、通常はアカウントはサブドメインの`tomoya.bsky.matsuuratomoya.com`で解決されなければならない。
ここで、私の環境では問題が二つ。
- `bsky.matsuuratomoya.com`と`${handle}.bsky.matsuuratomoya.com`はどちらもpdsのサーバーのIPアドレスにAレコードで解決されなければならない。
- また実際のトラフィックはポート80、443をサーバーまで到達できるようにしなければならない。
立ち上げたサーバーが固定グローバルIPを持つ場合特に問題ない。私のサーバーはIPoE環境なので、IPv4で任意のポートを空けることができない。そのためWebサービスの公開には[[Cloudflare Tunnel]]を使っている。
この場合、必然的にネームサーバーもCloudflareのものを使うことになる。Cloudflareは自動でHTTPの接続をSSL化してくれるので、Let's Encryptとかの面倒な設定が要らないため便利。だが無料プランでは残念ながら二階層以上のサブドメイン、つまり`${handle}.bsky.matsuuratomoya.com`にはSSL証明書を発行してくれない。
解決策は次のどれかである
1. Cloudflareにお金を払ってSSL証明書を発行してもらう
2. サブサブドメイン部分だけどうにか別の方法で証明書を用意する
3. **自分一人のハンドル解決だけどうにかする設定にする**(今回はこれ)
## シングルユーザーインスタンス限定の解法
`/pds/pds.env`で`PDS_SERVICE_HANDLE_DOMAINS=.matsuuratomoya.com`のように指定すると、PDSサーバー自体のアドレスを`https://pds.matsuuratomoya.com`にしたまま、ハンドルのIDは`${handle}.matsuuratomoya.com`で設定できます。
もちろん、実際にはこの状態でアカウントをいくつも作っていっても、ハンドルIDが自分の立ち上げてる他のサーバーのアドレスとかち合ったりするので普通は運用できません。
しかし、使うユーザーが一人だけの場合は、`_atproto.${handle}.matsuuratomoya.com`にTXTレコードでアカウントのDID永続性のあるアカウントIDを指定することでハンドルを解決すれば問題なく動かすことができます。
というわけで、まずは公式の`install.sh`で`pds.matsuuratomoya.com`上に一通りサーバーを立ち上げて、`/pds/pds.env`に`PDS_SERVICE_HANDLE_DOMAINS=.matsuuratomoya.com`を追記します。
ついでに、管理メールの送信用のSMTPの設定も済ましておきましょう。
```
PDS_EMAIL_SMTP_URL=smtps://${_SMTP_USERNAME}:${_SMTP_PASSWORD}@${_SMTP_HOST}
PDS_EMAIL_FROM_ADDRESS=hogehoge@matsuuratomoya.com
```
(`PDS_EMAIL_FROM_ADDRESS`に関してはなぜかドキュメントに載っていなかった気がする)
その後`pdsadmin create-invite-code`でアカウント招待コードを作っておきます。(`pdsadmin account create`だと先にハンドル解決ができないため招待コードを経由する)
### Cloudflare Tunnelを立ち上げる
Cloudflare Tunnelを立ち上げます。私は別の用途で色々使っているトンネルがあるのでここでは省略。
一度も使ったことがないなら、おすすめは`/pds`以下に`compose.override.yml`というファイルを作ってコンテナを追加すること。
```
services:
tunnel:
container_name: cloudflared-tunnel
image: cloudflare/cloudflared:latest
volumes:
- ./cloudflared:/~/.cloudflared
restart: unless-stopped
command: tunnel run
privileged: true
environment:
- TUNNEL_TOKEN=<設定画面で出てきたトークン>
```
トンネルが開通したら、サーバーのローカルIP同じdocker composeで立ち上げてるなら`localhost`でに転送する。特にドキュメントに書かれてないが内部的には3000番でサーバーが立ち上がっているところに、[[Caddy]]でリバースプロキシをかけているので、トンネルからHTTPをそのまま3000番に転送してあげる。
なので、docker composeで立ち上がっているcaddyのサーバーは無用の長物になっているため、気になる人はオリジナルの`compose.yml`でコメントアウトしてもいいと思う。私はどうせアップデートかけた時にcompose.ymlが巻き戻る気がしててめんどくさいのでやってない
### PDSにログインする
https://bsky.app にアクセスして、