FirefishからSharkeyに移行してみた(非Docker / Ubuntu)
※自環境で動作は確認していますが細かい不具合などあるかもしれません。あくまで夜坂個人はこれでやりましたという体験談であり、サポートドキュメントの類ではありません。自己責任で対応をお願いします。
※Ubuntuを利用しているのでUbuntu以外の方は細かい違いを自分でご確認ください。
※素人の説明なので至らないところがあり跳んでいる個所があるかもしれません。あくまで参考資料としてください。
作業の流れ
既存のFirefishからSharkeyに移行する場合、Firefishで使っていたデータベースを新しいSharkeyで読み込めるようにする変更を行うという移行方法になります。
そのためこのあとやることは簡単にいうと
Sharkeyを新しくインストールする準備段階のところまで行う
Firefishで利用しているデータベースをSharkeyで使える形式にする
Sharkeyをbuild,migrateして起動させる
みたいな感じになります。
出来たらこれらの操作を試す場合、データベースのコピーを作成して一度本番環境以外で試してから本番で実行することをお勧めします。
実際にやったこと
1.Sharkeyのインストール準備をする
基本的には上記リンク内のManuallyの部分の流れを参考にする感じです。Misskeyと一緒ですと書かれている通りほぼMisskeyを新規でインストールする時と同じ流れです!そのため以下の説明を読んでもわからない箇所があるという方はUbuntu向けの詳しいインストール方法の説明のうち、詰まっている部分と関係のあるところを参考にしてみてください。 ただ、Firefishがすでに動作する環境であれば、Sharkeyの動作に必要なソフトウェアはほぼほぼ入っている状態だろうと思われるため、git cloneなどでフォルダをコピーする所からが、今回の移行に実際に必要な対応になります。以下がその流れです。
Firefishを利用しているユーザーのhomeフォルダでgit cloneしていきましょう。
code:command
cd Sharkey
このときnodeのバージョンによっては次のコマンドでうまくいかないよーと警告が出るかもしれません。その時は画面上にエラーと一緒に英語で「このバージョンを使ってほしい」という旨の表示が出てると思うのでそのバージョンのNodeをインストールしてください。(この記事作成時点の2024.09前半ではv20系でした。v22などでやるとうまくいかなかったよとエラーが出ます)
code:command
pnpm install --frozen-lockfile
エラーが出ないと言うことであれば設定ファイルをコピーしましょう
code:command
cp .config/example.yml .config/default.yml
ここで作成された.config/default.ymlの内容をFirefish側の.config/default.ymlの内容に合わせてnanoやvimで修正しましょう。変更に必要なのは以下の部分です。ここを既存のFirefishの.config/default.ymlで使用している内容に合わせてください。またもしここ以外の設定をカスタムして変えている場合は同時に確認して調整ください。
code:.config/default.yml
db:
host: localhost
port: 5432
db: {Firefishで投稿の保存に利用しているデータベースの名前}
user: {上記データベースにアクセスするユーザー名}
pass: {上記データベースにアクセスするユーザーのパスワード}
// これらの設定は既にFirefish側の.configフォルダ内にあるdefault.ymlに記載している情報を使うので、そこの内容を確認してください
これらを行うことでSharkeyが動いた時に元々利用していたDBを利用するという設定が完了します。
※追記:もしローカルストレージなどを利用していてFirefish側にFilesフォルダがある場合はそれもコピーして移動しておいてください。
2.サーバーを停止して、データベースのバックアップを用意する
このタイミングでサーバーを停止し、失敗しても戻れる状態にする必要があります。
必ず作業開始前にFirefishを停止してください。
systemdの人ならsudo systemctl stop {あなたがFirefishの起動に利用しているsystemdのサービスファイル名}.service、pm2を利用している人ならpm2 stop {あなたがFirefishの起動に利用しているsystemdのサービスファイル名}で止める必要があります。このコマンドの後止まっているかコマンドなりサイトを開くなりで確認してください。また起動登録している場合は再起動とかしてしまうと起動してしまうので不安であれば再起動時の起動設定を解除しておきましょう。
データベースのバックアップを取得します。
データベースのバックアップが良くわからない方はスナップショットでも大丈夫です。この後行う作業はデータベースを書き換える対応になるため万が一失敗した時には元に戻せるようバックアップを作成してください。
データベースのバックアップは pg_dump database名 > backup_file名で出来るかと思います。初心者向けの解説を参考にするかこれもちょっと分からない方は作業前にサーバー側のスナップショット作成を利用するといいと思います。 3.Firefishで利用しているデータベースをSharkeyで使える形式にする
このまますぐ使えればいいのですが、FirefishとSharkeyでは色々保存しているデータなどが違います。たとえば最新版Misskey系では存在するロール機能がFirefishでは存在しないし、逆にFirefishでは使えるチャットが最新版Misskey系にはない、など。そういったデータの差があるとうまく読み込みできません。
そのためデータベースの使わなくなる部分を削除し、新しく必要な部分を作成したり、いまあるものの名前を変えると言う作業が必要になります。以下がその手順です。
ダウングレードするための挙動を自動でやってくれるsqlを配布してくださっているのでそれをダウンロードします。
code:comand
このクエリを利用してデータベースをSharkeyに切り替える操作を出来る段階まで戻します。以下で使用する値はSharkeyのインストール準備で使用するものとおなじです
code:comand
psql --file=/tmp/downgrade.sql --user={データベースにアクセスするユーザー名} --{Firefishで投稿の保存に利用しているデータベースの名前}
これをすると1.0.5rcに対応したデータベースになりますので今度はSharkey側の移行用ドキュメントのFrom Firefishの部分から記載されている方法に従って更にデータベースを修正します。Dockerの方はDockerの方法に従ってください。Manuallyの方は以下の流れで対応します。 PostgreSQLの操作画面にアクセスする
code:comand
sudo -u postgres psql
変更したいデータベースにアクセスする
code:comand
\c {アクセスしたいデータベース名} {データベースにアクセスするユーザー名}
Sharkeyのドキュメントに書いている流れに従ってコマンドを実施するためにまず開始コマンドを入力します。この後入力されたコマンドを複数実行するための開始宣言になります。
code:comand
BEGIN;
コマンドを実行します。 この時一カ所でもERRORと言う表示が出たら何かしら失敗しています。 次のコマンドに進む前にエラー箇所を確認してROLLBACK;と言うコマンドを入力し復旧してください。コマンドを分けて乗せます。必ず確認しながら実行してください。
できたらここに記載されている内容ではなくではなく公式ドキュメントの同じ内容の部分を確認してほしいですが、公式ドキュメントを参考にする場合/-- start a transaction... などの説明用コメントの部分は省いてコマンドを実行してください。 復旧用のコマンドを入力すれば保存されませんので確認しながら実行してください。
code:comand
ALTER TABLE "user_profile" ADD "integrations" JSONB NOT NULL DEFAULT '{}';
ALTER TABLE "meta" ADD "twitterConsumerSecret" VARCHAR(128);
ALTER TABLE "meta" ADD "twitterConsumerKey" VARCHAR(128);
ALTER TABLE "meta" ADD "enableTwitterIntegration" BOOLEAN NOT NULL DEFAULT false;
ALTER TABLE "meta" ADD "enableGithubIntegration" BOOLEAN NOT NULL DEFAULT false;
ALTER TABLE "meta" ADD "githubClientId" VARCHAR(128);
ALTER TABLE "meta" ADD "githubClientSecret" VARCHAR(128);
ALTER TABLE "meta" ADD "enableDiscordIntegration" BOOLEAN NOT NULL DEFAULT false;
ALTER TABLE "meta" ADD "discordClientId" VARCHAR(128);
ALTER TABLE "meta" ADD "discordClientSecret" VARCHAR(128);
code:comand
CREATE TABLE antenna_note();
code:comand
CREATE TABLE "reversi_game" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "startedAt" TIMESTAMP WITH TIME ZONE, "user1Id" character varying(32) NOT NULL, "user2Id" character varying(32) NOT NULL, "user1Accepted" boolean NOT NULL DEFAULT false, "user2Accepted" boolean NOT NULL DEFAULT false, "black" integer, "isStarted" boolean NOT NULL DEFAULT false, "isEnded" boolean NOT NULL DEFAULT false, "winnerId" character varying(32), "surrendered" character varying(32), "logs" jsonb NOT NULL DEFAULT '[]', "map" character varying(64) array NOT NULL, "bw" character varying(32) NOT NULL, "isLlotheo" boolean NOT NULL DEFAULT false, "canPutEverywhere" boolean NOT NULL DEFAULT false, "loopedBoard" boolean NOT NULL DEFAULT false, "form1" jsonb DEFAULT null, "form2" jsonb DEFAULT null, "crc32" character varying(32), CONSTRAINT "PK_76b30eeba71b1193ad7c5311c3f" PRIMARY KEY ("id"));
CREATE INDEX "IDX_b46ec40746efceac604142be1c" ON "reversi_game" ("createdAt");
CREATE TABLE "reversi_matching" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "parentId" character varying(32) NOT NULL, "childId" character varying(32) NOT NULL, CONSTRAINT "PK_880bd0afbab232f21c8b9d146cf" PRIMARY KEY ("id"));
CREATE INDEX "IDX_b604d92d6c7aec38627f6eaf16" ON "reversi_matching" ("createdAt");
CREATE INDEX "IDX_3b25402709dd9882048c2bbade" ON "reversi_matching" ("parentId");
CREATE INDEX "IDX_e247b23a3c9b45f89ec1299d06" ON "reversi_matching" ("childId");
code:comand
ALTER TABLE "user" RENAME COLUMN "movedToUri" TO "ff_movedToUri";
ALTER TABLE "user" RENAME COLUMN "alsoKnownAs" TO "ff_alsoKnownAs";
ALTER TABLE "user" RENAME COLUMN "isIndexable" TO "ff_isIndexable";
ALTER TABLE "user" RENAME COLUMN "speakAsCat" TO "ff_speakAsCat";
ALTER TABLE "user_profile" RENAME COLUMN "preventAiLearning" TO "ff_preventAiLearning";
ALTER TABLE "meta" RENAME COLUMN "silencedHosts" TO "ff_silencedHosts";
code:comand
CREATE TYPE public.new_antenna_src_enum AS ENUM ('home', 'all', 'list');
ALTER TABLE antenna ADD COLUMN new_src public.new_antenna_src_enum;
DELETE FROM antenna WHERE src NOT IN ('home', 'all', 'list');
ALTER TABLE antenna DROP COLUMN src;
ALTER TABLE antenna RENAME COLUMN new_src TO src;
DROP TYPE public.antenna_src_enum;
ALTER TYPE new_antenna_src_enum RENAME TO antenna_src_enum;
code:comand
DELETE FROM moderation_log WHERE info = '{}';
ALTER TYPE "public"."user_profile_mutingnotificationtypes_enum" ADD VALUE 'note';
エラーがなく問題なさそうだと思ったら保存します。
code:comand
COMMIT;
問題なければ一度この段階で\qコマンドで操作画面を終了します。
4. Sharkeyをbuild,migrateして起動させる
ここまでくればデータベースが読み書きできる状態になっているのであとはSharkey本体を動かせる状態にします。Sharkeyのインストールされたフォルダに移動し、以下のコマンドを実行します。
Sharkeyを動かせる状態にするためにbuildを実行します
code:comand
pnpm run build
今度はデータベースをSharkeyで読み込めるようにします
code:comand
pnpm run migrate
これらの作業中もしかすると予期しないエラーが起こる可能性があります。エラーが出た時は落ち着いてどのようなエラーだったか内容を確認し手順を確認してみてください。私の場合過去に復旧作業をしたテーブルの所有者が間違っていたのでその修正を行った…ということがありました。ただこれらの内容はちゃんとエラーで出ますので落ち着いてエラーを確認した後、検索なり頼れる方に聞くなりして対応してみて下さい。
上記コマンドが無事完了した後、起動するとnginxを使用している場合同じ設定でそのまま公開されます。問題ないか再確認してみて下さい。(Caddyの場合はちょっとわからないので確認してください)
起動コマンド実行します。するとしばらくしたあとSharkeyと言う文字が表示されるかと思います。その後、サイトURLにアクセスした時正常に表示されるか確認しましょう。
code:comand
pnpm run start
この時もエラーが出ている場合があります。その時はサイト側でなくサーバー側の画面にも更新時に何かしらエラーが出ているかと思うので何のエラーが発生しているか確認して調べて、やりなおしてみてください。もしあまりにもわからない内容の場合SharkeyのドキュメントではDiscordでのサポートを受け付けているという記載があるのでそちらで聞いてみるのもよいかもしれません
このコマンドを実行中はサーバーが起動状態になります。コマンドをCtrl+Cするとサーバーが閉じます。
pnpm run start 中にサーバーにアクセスして、無事起動を確認した方は一旦Ctrl+C等でstartしているSharkeyを停止しましょう。必ず停止させられてるか確認してから次の内容を実施してください。
ここまで起動ができるのであれば、データベースの大きい変更は無事クリアしたということになると思うので細かいデータベースの変更を行います。3の時と同様の操作です。Sharkey側の移行用ドキュメントを確認しながら対応してください。 PostgreSQLの操作画面にアクセスする
code:comand
sudo -u postgres psql
変更したいデータベースにアクセスする
code:comand
\c {アクセスしたいデータベース名} {データベースにアクセスするユーザー名}
Sharkeyのドキュメントに書いている流れに従ってコマンドを実施するためにまず開始コマンドを入力します。この後入力されたコマンドを複数実行するための開始宣言になります。
code:comand
BEGIN;
コマンドを実行します。 この時一カ所でもERRORと読み取れる類の表示が出たら何かしら失敗しています。 次のコマンドに進む前にエラー箇所を確認してROLLBACK;と言うコマンドを入力し復旧してください。このコマンドを入れると入力したコマンドは保存されません。コピペで間違ってた時保証できないので公式ドキュメントの同じ箇所を確認しながら実行してください。
code:comand
UPDATE "user" SET approved = true;
UPDATE "user" SET "movedToUri" = "ff_movedToUri" WHERE "ff_movedToUri" IS NOT NULL;
UPDATE "user" SET "alsoKnownAs" = "ff_alsoKnownAs" WHERE "ff_alsoKnownAs" IS NOT NULL;
UPDATE "user" SET "noindex" = NOT (COALESCE("ff_isIndexable", true));
UPDATE "user" SET "speakAsCat" = COALESCE("ff_speakAsCat", false);
UPDATE "user_profile" SET "preventAiLearning" = COALESCE("ff_preventAiLearning", true);
UPDATE "meta" SET "silencedHosts" = COALESCE("ff_silencedHosts",'{}');
ALTER TABLE "user" DROP COLUMN "ff_movedToUri";
ALTER TABLE "user" DROP COLUMN "ff_alsoKnownAs";
ALTER TABLE "user" DROP COLUMN "ff_isIndexable";
ALTER TABLE "user" DROP COLUMN "ff_speakAsCat";
ALTER TABLE "user_profile" DROP COLUMN "ff_preventAiLearning";
ALTER TABLE "meta" DROP COLUMN "ff_silencedHosts";
エラーがなく問題なさそうだと思ったら保存します。
code:comand
COMMIT;
問題なければ\qコマンドで操作画面を終了します。
再度起動コマンド実行し問題ないか確認しましょう。
code:comand
pnpm run start
ここまで問題なければ、Firefishを削除し後は初回の起動登録を行って下さい。何が起こるかわからないので間違ってもこの後Firefishと多重起動が発生しないように、気を付けてください。
/etc/systemd/system/sharkey.serviceを作成し、以下の内容で保存します
code:sharkey.service
Description=Sharkey daemon
Type=simple
User= {Firefishの起動などに使用していたユーザー名と同じ}
ExecStart=/usr/bin/pnpm start
WorkingDirectory= {Sharkeyのあるフォルダのパス /home/username/Sharkeyみたいな}
Environment="NODE_OPTIONS=--max-old-space-size=8192"
Environment="NODE_ENV=production"
TimeoutSec=60
StandardOutput=journal
StandardError=journal
SyslogIdentifier=sharkey
Restart=always
WantedBy=multi-user.target
このあたりでうまくいかない場合は個人で調べてみてください。
pm2の場合はSharkeyのあるフォルダに移動してpm2 start pnpm --name sharkey -- start してpm2 listに余分なFirefishの設定がある場合は削除してからpm2 startup してpm2 saveします。
多分これで行けると思いますが違っていても責任取れないので許してください。あくまで私の実行した内容を元に記載したものになります。公式ドキュメントを読み込んでください。