MastodonサーバーをXserver VPSからKagoya Cloud VPSへ移行しました

公開日:

[tech] #Mastodon #Ubuntu #VPS #docker

きっかけ

https://blog.asterism.xyz/posts/20251103-0000016c/

前回のMastodonアプデ記事の時に書いた通り、Ubuntu 26.04への移行と合わせてインスタンス作り直したかったというのがまずあります。

元々redisとpsqlだけdocker上じゃなくネイティブに動いていました。(これは歴史的経緯が強い。変えるタイミングはたくさんあったけどやってなかった)

この状態で sudo do-release-upgrade をすると、ポスグレのアプグレがめっちゃ大変です。

昔Ubuntu 18.04からUbuntu 20.04辺りに上げた時、pg_upgradeみたいなコマンドであれこれやったのを覚えています。めちゃくちゃ時間かかったしドキュメントも微妙だしで超大変でした。今みたいに困ったらAIに聞いちゃおwってのもできないし。

そういうのもあってインプレースアップグレードはやりたくなくて、それに加えてDBもdocker内に押し込みたくて、あとは /home/aries/mastodon/docker-compose.yml みたいにホームディレクトリの中にコンテナのあれこれを置いてるのも正直センスないなぁって感じなので /opt/mastodon/docker-compose.yml みたいに色々整理したいなー、というのがあり。

Xserver VPSで新インスタンスを作るか、別サービスでインスタンス建てるかの二択。

VPS比較(3年ぶり)

円安どころか半導体高騰でどこのサービスも何ともって感じの時代になってしまいました。

LinodeからXserver VPSに移った時の記事

https://blog.asterism.xyz/posts/20230306-000000d3/

ConoHaとさくらとIndigoは以前の記事で書いた時とほぼ変わってないので無し、となると国内サービスだとKagoyaくらいしか移行先が無い訳ですが、当時Kagoyaを避けた理由は今思えば大した話じゃなかった(記事には書かないですしもううろ覚えですけど)のと、あとプランの再編でストレージが値段の割に容量多いというのが魅力的。

4.4.xへのアップデート作業のとき、VPSの容量不足でちょっと危なかったのが頭にありました。KagoyaはRAM3GBでも4GBでも、Xserver VPSの2200円プランの二倍三倍くらいストレージが多いので、まぁこれなら困る事ないだろうなと。

インスタンス移行するとなるとダンプファイルを一時的に置かなきゃとかもありますし、ストレージに余裕があって、かつ今使っているXserver VPSよりも安いKagoya VPSが良さそうです。

RAM3GBプランで月1430円、4GBでも1760円。国内だと最安クラス。一応CPUとメモリだけで見たらシンVPSがもっと安いですが、あっちはその分ストレージケチってるのでどちらを取るかですね。

Mastodonで言うと、例えば外部投稿含めて1週間しかデータ持ちませんよ、みたいな運用するならシンVPSでも悪く無いんじゃないかなーと思います。

そうじゃない場合、私のサーバーでもDB50GBくらい(ダンプすると9GBくらい)掛かるので分散SNS用途でシンVPSはちょっと合わないかなと思います。

あとは色々こだわりたい気持ちが強かった昔と違って今は「とりあえずちゃんと動いてセキュリティ問題なければインフラ構成なんてできる限りシンプルな方がええ」って考えに変わってきてるので、プラットフォーム側FW機能なんかもあんまり気にしなくなりました。

ZeroTierはトラブったから一応辞めて、またdocker使うからufwも微妙だしFWもしょぼいプラットフォーム側ので十分かな。SSHきつめにしばらないとログ汚れるけど…。

そんな感じで色々な方針も合わせてKagoya VPSのRAM3GBプランで一旦決定。うまくいかなかったらまた考えましょうって感じ。

新旧の構成比較

新旧どちらでもメディアファイルについては、S3へアップしてCloudFrontの無料枠(月1TB転送まで無料になったのも結構前ですね)でプロキシしてます。

リバースプロキシはどっちもCaddyのdockerコンテナ使ってます。非常に楽。

旧サーバー

新サーバー

移行手順

ざっくりの手順としては

こんな感じ。いたって普通ですね。

VMの準備だけ週末にやって、その後

2026/08/11 11:40頃から作業開始、14時頃にサーバー復旧しました。

DB周りの作業時間としては

他にサーバー移行後に少し試した感じだと

バックアップのやり方変えたのもあったので念のためテストした結果こんな感じ。中身も確認できたので一安心。

Kagoya固有の注意点

今回の記事の本題です。やっぱり初めて使うサービスなのもあって色々ありました。

Kagoyaアカウント

Kagoya ID(Kagoyaのサービスをまとめるアカウントらしい?)を作ったうえで、そのKagoya IDに紐づく形でKagoya VPSアカウントを作ります。

なので実質管理が必要なアカウントは二つです。Kagoya IDとKagoya VPSのアカウント。

両方二要素認証使えるので、ちゃんと設定しましょう。

住所確認メール

アカウント作って初期設定した次の日の夕方に住所確認のメールが届きました。

正しい住所かどうか確認して、メールの返事をしてくださいとのこと。(期日は次の日だったので期限まで六時間。あのさぁ…)

案内に従ってメールの返事を書きました。

SSH設定

インスタンス作成時あるいは作成前に、VPS管理画面から鍵を発行します。

そこで作った鍵を、インスタンス作成時デフォルトユーザー(Ubuntuだったら ubuntu )に設定してくれるという感じでした。

ただこの状態だと、デフォルトのsshd_configではパスワードログインが有効のままです。

とはいえubuntuユーザーはパスワードが未設定なので、パスワードでのSSHは不可能という状態になっています。

またインスタンス作成時に「コンソールパスワード」という項目があります。

こちらはプラットフォーム側のVNCでrootログインするときに使う、rootユーザーのパスワードです。

ちなみにsshd_configでrootログインは無効化されてました。

なので、新しいユーザーを作って管理しようと考えている場合は注意してください。デフォルトではパスワードでのSSHログインが無効化されていないのでユーザー作ったタイミングからログインできてしまいます。

私の場合、新しく作ったユーザー名もパスワードも安全なものだったので特にログイン試行などもされませんでしたが注意が必要なポイントかと。

/etc/ssh/sshd_config.d/10-hardening.conf なんてのを作って

PermitRootLogin no
PasswordAuthentication no
DenyUsers ubuntu

こんなのを設定しました。

新しく作ったユーザーは別途鍵ファイルを設置してSSHログインを確認してから反映しています。

後細かいですが、SSHDの設定変更をするときは接続済みのSSHセッションは残しておくようにしましょう。

設定ミスで一切なにもつながらない、なんて状態になったら最悪インスタンス作成から作業し直しになってしまいます。

ついでに整理した項目

移行ついでにディレクトリ構成とかログの構成、バックアップの取り方なんかを変更しています。

ディレクトリ構成

前述の通り、元々は /home/aries/ の中にmastodonやcaddy、今動いてないマルコフ連鎖botなどのファイルを置いていました。

流石にちょっと…って感じではありますが、ちゃんと動いているものをわざわざ変える理由もあまりなく、2018年からずっとこんな状態でした。

今回は考え直そうとなったため、以下のようにディレクトリ構成を変更しています。

ログ設定

元々はdocker-compose.ymlで、logging driverをawslogsにしてました。

この状態からjournaldであれこれ管理できるようにするために、少しだけ設定を入れてあります。

/etc/systemd/journald.conf.d/mastodon.conf

[Journal]
Storage=persistent
SystemMaxUse=4G
MaxRetentionSec=3month
RateLimitBurst=0

journald側を設定してから、mastodonなどを動かしているdocker-compose.yml側で

x-logging: &logging
  driver: journald
  options:
    tag: "mastodon/{{.Name}}"

こんなのを冒頭に書いて、serviceの中に logging: *logging と書いてます。

Ubuntu Pro

Linuxカーネルへのライブパッチを使って運用少し楽しちゃお、という事で個人用途なら無料で5インスタンスまで使えるUbuntu Proを設定しています。

リソース監視

mackerelの無料アカウントを使っています。

また今回はdocker pluginも使っています。

mackerelのインスタンス追加からワンライナーをコピーしてきてインストールした後で、

sudo apt install mackerel-agent-plugins

とかやって、 /etc/mackerel-agent/mackerel-agent.conf

[plugin.metrics.docker]
command = "/usr/bin/mackerel-plugin-docker"

を記入した上で sudo systemctl restart mackerel-agent.service

バックアップ用サイドカーコンテナ

今までsystemd-timerとホームディレクトリ以下にポン置きしたスクリプトで動かしてたバックアップをコンテナ化しました。 これでこのサーバーで見ればいいのはdockerだけになったので、今後するかもしれない移行なんかも楽になるかなと。

Dockerfile

FROM alpine:3.24
# postgresql18-client / curl / tzdata は main、rclone は community。
# 公式 alpine イメージは main と community の両方が有効なので追加設定は不要。
RUN apk add --no-cache postgresql18-client rclone curl tzdata \
 && pg_dump --version && rclone version && curl --version
ENV SCHEDULE="0 4 * * 6"
COPY backup.sh /usr/local/bin/backup.sh
CMD echo "$SCHEDULE /usr/local/bin/backup.sh > /proc/1/fd/1 2>&1" > /etc/crontabs/root && exec crond -f -l 8

backup.sh

#!/bin/sh
set -eu
FILE="$PGDATABASE-$(date -u +%Y%m%dT%H%M%SZ).dump"
trap 'rm -f "/scratch/$FILE"' EXIT
pg_dump -Fc -f "/scratch/$FILE"
rclone copyto "/scratch/$FILE" "$RCLONE_DEST/$FILE"
if [ -n "${PING_URL:-}" ]; then
  curl -fsS -m 10 "$PING_URL"
fi

rclone.confや環境変数$RCLONE_DEST, $PING_URLはdocker-compose.ymlで渡してます。

healthchecks.ioを使ってみています。

外形監視について

元々freshstatusのカスタムページを使ってましたが今はもう独自ドメイン使いたきゃ有料アカウントが必要になってしまったので一旦無しで。

discord通知くらいはn8nとか使って良い感じにやろうかな?と考えてますが、そもそも自分が使おうとしたとき死んでたら気づくから別によくない?とも思わんでもない。

移行結果

8/11の昼下がりに作業完了してから翌日夕方の今まで、今のところは元気に動いています。(プラットフォーム側に止められたりも無し)

ただメモリが結構ぎりぎりなので、サーバー動いてる状態でバックアップコンテナ動かしてどうなるかなーとか色々見ておきたいポイントはまだまだたくさん残ってるって感じです。

グラフ上は800MB~1GBくらいメモリ余裕あるので大丈夫だとは思うんですけどね。変に負荷掛かった時どうかなーって感じ。

mackerelから見たメモリ使用量

ちなみにswapはデフォで4.7G用意されてました。

今後

今はMastodon4.4.x系を使ってるので流石にそろそろ4.6.x系への更新と、自分用のMastodonクライアントに引用機能とか追加したりとかもしたい。

結構やりたい事多いな…。

検索Esc で閉じる