はじめに
この記事の通りに作ると一見完成しているようにみえますが、後から不具合きたしまくったので新しく書き直しました!以下の記事を参考にしてください! (2023/05/10 追記)
レターパックで現金送れ 与謝野晶子
この無関係な2ワードに関係性を見出してしまう方は多いのではないでしょうか。
Twitterが某起業家に買収されてから度々話題に上がるMisskey.io、筆者ももれなくハマっていますが、Fediverseの本質は個々人が自由にインスタンスを持つことができ、システムやインスタンスの壁を超えてつながり合えること。
少し技術に触れている身からすると、自分でインスタンスをもつことにはとても興味があるわけです(その過程にも)。思い立ったが吉日、手をつけてやっと安定したのでその過程を備忘録的にまとめていきます。これからインスタンスを持ってみたいという方の参考になれば良いかと思います。
用意したもの
インスタンスを立ち上げるにあたって、用意したものを記述していきます。
- さくらVPS 石狩第1ゾーン, 仮想2Core, 1GBメモリ, SSD 50GB
- Google Cloud Strage
- ドメイン
- Mailgunアカウント
- Cloudflareアカウント
現状3人のインスタンスですので、この程度のスペックで十分動いています。
建てていく
早速作業を進めていきます。
スワップ領域の設定
2GB以上のメモリを積んであれば問題ないかと思われますが、1GBですと普通にメモリが足りません。
スワップ領域の設定を行えば、全く解消できるので、やっておいた方が絶対に良いです。下記の記事にわかりやすく全部まとまっているので、参考に。
Misskeyの構築
Misskey本体を構築していきます。公式のドキュメントは以下の通りです。
基本的にドキュメント通りに進めていけば問題ありませんが、設定の内容なども書きたいので、1から書いていきます。
公式リポジトリを取得します。
$ git clone -b master https://github.com/misskey-dev/misskey.git
$ cd misskey
$ git checkout master
各種設定ファイルのサンプルをコピーします。
$ cp .config/docker_example.yml .config/default.yml
$ cp .config/docker_example.env .config/docker.env
$ cp ./docker-compose.yml.example ./docker-compose.yml
この設定ファイルを編集していきます。
default.yml
で変更した場所は4箇所です。
DB周りは飛ばすと致命的なのでしっかりバックアップをとっておいた方がいいです。
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Misskey configuration
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# ┌─────┐
#───┘ URL └─────────────────────────────────────────────────────
# Final accessible URL seen by a user.
url: https://xxx.com #ここに使うドメインを記述
...
# Database name
db: xxxx #任意のDBの名前を記述
# Auth
user: xxxxx #DBのユーザー名
pass: xxxxx #DBのパスワード
...
続いてdocker.env
を編集していきます。
ここにはさっきのdefault.yml
に書いたことと同じことを書けば大丈夫です。
# db settings
POSTGRES_PASSWORD=xxxxx #さっき設定したDBのパスワード
POSTGRES_USER=xxxxx #さっき設定したDBのユーザー名
POSTGRES_DB=xxxx #さっき設定したDBの名前
最後にdocker-compose.yml
を編集していきます。
コメントがあるところを書き換えたり増やしたりしました。手元でビルドできそうなスペックであるなら、変えなくても大丈夫かと思いますが、今回は無理そうと判断したのでイメージを取得するようにしています。
version: "3"
services:
web:
image: misskey/misskey:latest #buildではなくimageを取得する
restart: always
links:
- db
- redis
# - es
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
ports:
- "3000:3000"
networks:
- internal_network
- external_network
volumes:
- ./files:/misskey/files
- ./.config:/misskey/.config:ro
#追加する
environment:
VIRTUAL_HOST: xxx.com
VIRTUAL_POST: 3000
LETSENCRYPT_HOST: xxx.com
LETSENCRYPT_EMAIL: yyy@xxx.com
redis:
restart: always
image: redis:7-alpine
networks:
- internal_network
volumes:
- ./redis:/data
healthcheck:
test: "redis-cli ping"
interval: 5s
retries: 20
db:
restart: always
image: postgres:15-alpine
networks:
- internal_network
env_file:
- .config/docker.env
volumes:
- ./db:/var/lib/postgresql/data
healthcheck:
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
interval: 5s
retries: 20
# es:
# restart: always
# image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.2
# environment:
# - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
# - "TAKE_FILE_OWNERSHIP=111"
# networks:
# - internal_network
# volumes:
# - ./elasticsearch:/usr/share/elasticsearch/data
networks:
internal_network:
internal: true
external_network:
external: true #新しく生やした
自分で記事に沿ってやってたらめちゃくちゃ設定忘れてました。
nginxとmisskeyを繋ぐためのネットワークを作る必要があります。 (2023/04/12 追記)
sudo docker network create external_network
これで設定は終わったので初期化と起動を行います。
さくらVPSでやったときはスムーズに行ったのですが、Macの検証環境でやったときにイメージが見つからずに怒られが発生したので、そのときは落ち着いてdocker pull
でイメージを落としましょう。
$ sudo docker compose run --rm web pnpm run init
$ sudo docker compose up -d
起動が完了したら
$ curl localhost:3000
で確認しましょう。ちゃんとソースコードが出てきたら完了です。
nginxの構築
リバースプロキシのためのnginxを構築していきます。ymlを書く程度ですが…
version: "3"
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./certs:/etc/nginx/certs:ro
- /etc/nginx/vhost.d
- /usr/share/nginx/html
restart: always
networks:
- external_network
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: letsencrypt
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./certs:/etc/nginx/certs:rw
volumes_from:
- nginx-proxy
restart: always
networks:
- external_network
networks:
external_network:
external: true
これだけで設定は終わりなので、起動しましょう。
$ sudo docker compose up -d
起動が完了したら、もうアクセスできるはずなので、設定したドメインからアクセスして、管理者アカウントを作成しておきましょう。
アカウントの作成が済んだら、次の作業に進みます。
CDNの設定
公式ドキュメントでも言われている通り、MisskeyはCDNの利用が推奨されています。
私はCloudflareを使いましたので、これで進めていきます。
アカウントを作成し、ドメインを登録したら、いくつか設定を進めていきます。
次に、ルール→ページルールからページルールを作成します。
xxx.com/api/*
のようにし、キャッシュレベルをスキップにします。リレーを行うときにすべき設定らしいです。
これで一旦Cloudflareの設定は終わりです。証明書関連のエラーや、リダイレクトが繰り返されたなどの問題が発生している場合は、一旦nginxを止めて、ymlファイルのLet's Encryptの設定を削除してからもう一度起動すると治るかと思います。
オブジェクトストレージの設定
アップロードされた画像や、絵文字のデータはそのままの設定だとすべてローカルに保存されます。これだと無限にVPSの容量を圧迫するので、別にストレージを確保します。AWSやWasabiなどがありますが、別件でGCPのアカウントを持っていたので、流れでGoogle Cloud Storageを選択しました。
基本的な設定はこちらの記事が参考になりました。相互運用性のタブをクリックしたらそこで止めてください。
Misskeyで用いるにあたって、公開サーバーにする必要があります。
これに関しては公式のドキュメントがわかりやすいので、参照してください。
オブジェクトストレージのリバースプロキシのようなもの
純粋にオブジェクトストレージのURLをMisskeyに設定しても問題ないのですが、利用するオブジェクトストレージを変更し、URLが変わったときに連合先のインスタンスではリンク切れが多発します。なので、保有しているドメインからオブジェクトストレージに対してリバースプロキシを行うことで、この先なにがあってもいいようにしておきます。
ようなもの…と書いたのはnginxに設定を追加して自鯖で処理すればよかったのですが、なぜかうまくいかず、前述したレートリミットにぶち当たってどうにもならなくなってしまったので、CloudflareのWorkersルールで強引に解決しました。(一応リクエスト数が1日10万件となっているので、おいおい自分でできるようにすべきと思います。)
CloudflareのダッシュボードからWorkersルートを選択し、Workersを管理する、サービスを作成と進み、エディタのようなものが出てきます。ここに以下のスクリプトをコピペします。
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
const url = new URL(request.url);
const bucketUrl = `https://storage.googleapis.com/YOUR_BUCKET_NAME${url.pathname}`;
const response = await fetch(bucketUrl, request);
return response;
}
YOUR_BUCKET_NAME
はオブジェクトストレージで設定したバゲットの名前に置き換えてください。
これで保存、デプロイし、HTTPルートを追加します。任意のドメイン(筆者はmi.soli0222.comをインスタンスURL、media.soli0222.comをストレージのものとしています。*.xxx.comならCloudflareがついでに証明書もつけてくれます。)に/*
をつけて保存すれば完了です。
GCSの画面から適当な画像ファイルをアップロードして、公開URLをコピー、ブラウザからアクセスして画像が表示されるのを確認したら、storage.googleapis.com/YOUR_BUCKET_NAME
の部分を先ほど設定したドメインに置き換えて、同じ画像が表示されるか検証してください。されれば完了です。
Misskeyにオブジェクトストレージを設定する
まず、GCSの設定から相互運用性を開きます。
ユーザーアカウントのHMACで鍵を作成し、アクセスキーとシークレットを取得します。
次に、Misskeyのコントロールパネルを開き、オブジェクトストレージを選択します。
BaseURLには先ほどCloudflareで設定したURL、Prefixはバゲット内のディレクトリなので、好きなように設定してください。
また、Access KeyとSecret KeyはGCSで取得したものです。
リージョンなど異なる場合がありますが、他は画像のように設定すれば完了です。
ノートを作成し、正しく画像が表示されていれば完了です。
メールサーバーの設定
最後です。メールサーバーを設定します。
これはパスワードを忘れたときや、お知らせの配信のために使われるもので、設定が推奨されています。
Mailgunが件数に制限はありますが、無料で使えるのでこれを選択しました。
途中の過程はこちらの記事が参考になりました。
DNSレコードの設定に関してはCDNにて行いました。
また、SMTPの設定が出ていると思うので、これをMisskeyのコントロールパネルからメールサーバーを選択し、入力すれば完了です。
アップデート
インスタンス作成自体の作業はこれで終わりなのですが、Misskeyのアップデートをする際の記述もしておきます。
$ git stash
$ git checkout master
$ git pull
$ git submodule update --init
$ sudo docker pull misskey/misskey
$ sudo docker compose stop && sudo docker compose up -d
これだけで終わりです。
おわりに
ひとまずこれで、小規模なインスタンスは完成です!お疲れ様でした!
自分でインスタンスを立てるとやりたい放題できますし、身内のコミュニティも作れますし、何より作っていく過程(主にトラブルシューティング)が楽しかったので満足です。
読んでいただき、ありがとうございました。
参考文献