Misskey鯖を立てた時にやったこと
基本的にはこの手順に沿って準備していく
動作環境はDockerでもよかったが、今回Oracle Cloud Infrastructureの VM.Standard.E2.1.Micro (AMD) (メモリ 1G) インスタンスで動かしたかったため、少しでもパフォーマンスオーバーヘッドの少なそうな Systemd の方を選択した
実際に立てた鯖はこれ
オブジェクトストレージの設定
こちらを参考にさせていただきました。
DBのバックアップ
DBのバックアップもこちらを参考にさせていただきました。
misskey のDB (postgresql) の定期バックアップも同じオブジェクトストレージ上で管理したかったため、ディレクトリ構成だけ変更
/
- backup/ # DB周りのバックアップ系
- storage/ # misskeyでアップロードされたファイル類
今思うとバケット単位で可視性設定しているので、メディア系とバックアップ系を1つのバケットに格納せずバケット分けてもよかったかも(公開されて困るものは無いはずなので良いか
インスタンス、ミドルウェア監視の設定
Mackerel を使った。
現在フリープランで運用していますが、個人的に使う分には十分すぎる機能。
Mackerel Agentのインストール
Hosts > 新規ホストの登録から、Ubuntu用のセットアップスクリプトをコピペして実行
ドキュメントにも同様のコマンドの記載があるのですが、新規ホストの登録からコピペした方にはAPIキーが最初からセットされてるのでこっちの方が手軽で良い
メトリクス監視
エージェントをインストールしただけでロードアベレージやCPU使用率、メモリ使用率などメジャーどころは取れるのでOK
Misskeyでは、キャッシュにredis, データベースにpostgresqlを使っているので、これらのミドルウェアのメトリクスも見れるようにします
プラグインを有効化してエージェントの再起動
最初からコメントアウトされた状態で postgresql とredis用のプラグインのコマンドが用意されているので、コメントをアウトを外して認証情報を追加した
$ vi /etc/mackerel-agent/mackerel-agent.conf
...
# Plugin for PostgreSQL
# Appropriate previlege settings required.
# By default, the plugin accesses PostgreSQL on localhost.
[plugin.metrics.postgres]
command = "mackerel-plugin-postgres -user=<ユーザー名> -password=<パスワード> -database=mk1"
# Plugin for Redis
# By default, the plugin accesses Redis on localhost.
# Currently AUTH password has not been supported yet.
[plugin.metrics.redis]
command = "mackerel-plugin-redis"
...
保存したら、 sudo systemctl status mackerel-agent
でエージェントの再起動
再起動したら、実際にカスタムメトリクスが送信されているか確認する。
postgresqlのカスタムメトリクス
redisのカスタムメトリクス
通知
通知先をDiscordに設定しています、Slack互換のWebhookURLをDiscordが生成してくれるので、これを MackerelのSlack通知URLに貼り付ければ動きます。
実際のアラートはこんな感じ
最低限のアラート設定だけ突っ込んでます
misskeyをアップデートする
これでアップデートする
アップデートスクリプトをダウンロードしてきて、実行する
wget https://raw.githubusercontent.com/joinmisskey/bash-install/main/update.ubuntu.sh -O update.sh
sudo bash update.sh
実行すると、コードをクローンしてきて、ビルドし直すみたい。
アプデ中はダウンタイムが発生するので注意(自分の場合は5分ぐらいかかった)
メモリ使用率が高い対策
メモリ 1Gのマシンで動かしているとメモリ使用率が高い時の動作が怪しくなることがちょくちょくあった。
というのをMisskeyで呟いたら、ありがたい情報を得た
ちょうど、Ubuntu22.04で動かしていたのでとりあえずやってみる
# インストール
sudo apt install libjemalloc2
この後に、各種サービスの再起動を求められたので何も考えずにmisskey含み複数サービスの再起動をした
sudo systemctl edit
をしたら nanoが起動したのでvimに変更した
sudo update-alternatives --config editor
sudo systemctl edit misskey.chilitreat.dev
以下を追加して保存
[Service]
Environment="LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2"
sudo systemctl restart misskey.chilitreat.dev
結果
16:00ちょい前の再起動によってSwap使用量は減った(これはlibjemalloc2インストール時の再起動)
16:10前後の再起動がlibjemalloc2へ設定変更した時の再起動
ちょっと様子見してSwapが上がり続けなければヨシ!
OCIのStorageの無料枠(20GB)に達してしまい、画像のアップロードが失敗するようになった
このブラーがかかった画像がアップロードに失敗してる画像群
サーバーのjournal見てみると、こんなエラーが出ていたので気づいた
ERR 1 [drive register] Upload Failed: key = storage/thumbnail-2ea772e5-f058-43f9-be0d-e0f822d1987e.webp, filename = casmarket-14-poster-wide>
StorageLimitExceeded: Storage limit exceeded for tenancy during upload
at throwDefaultError (/home/misskey/misskey/node_modules/.pnpm/@smithy+smithy-client@2.1.5/node_modules/@smithy/smithy-client/dist-cjs/default-error-ha>
at /home/misskey/misskey/node_modules/.pnpm/@smithy+smithy-client@2.1.5/node_modules/@smithy/smithy-client/dist-cjs/default-error-handler.js:18:39
at de_PutObjectCommandError (/home/misskey/misskey/node_modules/.pnpm/@aws-sdk+client-s3@3.412.0/node_modules/@aws-sdk/client-s3/dist-cjs/protocols/Aws>
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async /home/misskey/misskey/node_modules/.pnpm/@smithy+middleware-serde@2.0.8/node_modules/@smithy/middleware-serde/dist-cjs/deserializerMiddleware.>
at async /home/misskey/misskey/node_modules/.pnpm/@aws-sdk+middleware-signing@3.410.0/node_modules/@aws-sdk/middleware-signing/dist-cjs/awsAuthMiddlewa>
at async /home/misskey/misskey/node_modules/.pnpm/@smithy+middleware-retry@2.0.11/node_modules/@smithy/middleware-retry/dist-cjs/retryMiddleware.js:27:>
at async /home/misskey/misskey/node_modules/.pnpm/@aws-sdk+middleware-flexible-checksums@3.410.0/node_modules/@aws-sdk/middleware-flexible-checksums/di>
at async /home/misskey/misskey/node_modules/.pnpm/@aws-sdk+middleware-logger@3.410.0/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.>
at async Promise.all (index 0)
at async Upload.__uploadUsingPut (/home/misskey/misskey/node_modules/.pnpm/@aws-sdk+lib-storage@3.412.0_@aws-sdk+client-s3@3.412.0/node_modules/@aws-sd>
at async Upload.__doConcurrentUpload (/home/misskey/misskey/node_modules/.pnpm/@aws-sdk+lib-storage@3.412.0_@aws-sdk+client-s3@3.412.0/node_modules/@aw>
at async Promise.all (index 0)
at async Upload.__doMultipartUpload (/home/misskey/misskey/node_modules/.pnpm/@aws-sdk+lib-storage@3.412.0_@aws-sdk+client-s3@3.412.0/node_modules/@aws>
at async Upload.done (/home/misskey/misskey/node_modules/.pnpm/@aws-sdk+lib-storage@3.412.0_@aws-sdk+client-s3@3.412.0/node_modules/@aws-sdk/lib-storag>
at async DriveService1.upload (file:///home/misskey/misskey/packages/backend/built/core/DriveService.js:332:9)
at async Promise.all (index 1)
at async DriveService1.save (file:///home/misskey/misskey/packages/backend/built/core/DriveService.js:168:13)
at async DriveService1.addFile (file:///home/misskey/misskey/packages/backend/built/core/DriveService.js:506:20)
at async DriveService1.uploadFromUrl (file:///home/misskey/misskey/packages/backend/built/core/DriveService.js:691:31)
at async ApImageService.createImage (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApImageService.js:66:22)
at async ApImageService.resolveImage (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApImageService.js:94:16)
at async Promise.all (index 0)
at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:159:23)
at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
at async tryResolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:184:33)
at async Promise.all (index 0)
at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:202:29)
at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
at async Promise.all (index 0)
at async ApPersonService.updateFeatured (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApPersonService.js:494:31)
at async ApPersonService.createPerson (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApPersonService.js:328:9)
at async ApPersonService.resolvePerson (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApPersonService.js:464:16)
at async Promise.all (index 24)
at async ApAudienceService.parseAudience (file:///home/misskey/misskey/packages/backend/built/core/activitypub/ApAudienceService.js:32:33)
at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:143:30)
at async ApInboxService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/ApInboxService.js:353:13) {
'$fault': 'client',
'$metadata': {
httpStatusCode: 400,
requestId: 'nrt-1:VSfBvWBB4DyvWHnpS9vNzziCTb8n3RPBpr_PDH8K6qyzg1lTOIdHPm4tsaKzibiB',
extendedRequestId: undefined,
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
},
対策
OCIのプランを無料から有料プランにアップグレードした。
一旦回避できたが他に良い感じの方法ないか検討中