SyoBoN's Home


FreeBSDとMisskeyのはなし

この記事はMisskeyアドベントカレンダー(2枠目)の8日目の記事です。

みなさん、Misskeyサーバーは持っていますか?持っていますよね?

サーバーのOSには何をお使いでしょうか。MisskeyHubにガイドのあるUbuntu?ある程度詳しい人ならArch LinuxやManjaroを使っている人が多いでしょうか。

私は逆張りオタクなので、サーバー用OSはFreeBSD一択です。他に理由なんてありません、人が使っていないから使うのです。FreeBSDはいいぞ。

しかし、FreeBSDは(Linuxと比較して)マイナーなOSなので、予期せぬトラブルに見舞われることも少なくはありません。実際、MisskeyをFreeBSDで動かせるようになるまでには多少の障害がありました。しかし、紆余曲折を経て、今やMisskeyをFreeBSDで動かすのに苦労は(ほぼ)ありません。

さあ、みなさんもこの記事を読んでFreeBSD鯖缶になりましょう!

※この記事の前半7割はFreeBSDにMisskeyをインストールするガイド、残りの3割は私のMisskey on FreeBSDへの挑戦の振り返りです。

はじめに: Why FreeBSD?

BSDを源流に持つOSは、FreeBSDだけではありません。NetBSDやOpenBSD、DragonflyBSDなどがその例です。では、なぜFreeBSDなのでしょうか。

一言で言えば、「FreeBSD以外ではMisskeyがビルドできないから」です。

MisskeyのバックエンドはTypeScriptによって書かれています。しかし、Node.jsが実行できるのはJavaScriptのみであるため、トランスパイルを行う必要があります。このトランスパイル作業には、Misskey v13.7.1以来swcが使われています。そしてこのswc、Windows / macOS / Linux / FreeBSD / Android用のバイナリは配布されていますが、NetBSDやOpenBSD用のバイナリが存在しません。これが、NetBSDやOpenBSDでMisskeyがビルドできない理由です。

ちなみに、Misskey v13.7.1より前はtscというツールが使用されており、Misskeyには今でもtscを利用してビルドする機能が残っています。が、この記事を書くにあたって検証してみたところ、現在tscでのビルドは失敗してしまうようでした。これについてはまた時間のあるときにさらに詳しく調べてみることとします。

Misskey on FreeBSDインストールガイド

注意

この記事は、FreeBSDでMisskeyサーバーを起動するところまでを対象としています。Linuxと大きく異なるファイアウォールについては扱いますが、リバースプロキシの設定、CDNの設定などは取り扱いません。サードパティ製のパッケージの設定ファイルが/etc以下ではなく/usr/local/etc以下に配置されていることなどを除けばLinuxと同様ですので、MisskeyHubなどを参考に進めてください。

FreeBSDのリポジトリについて

FreeBSDのパッケージリポジトリには、常に最新のパッケージが収録されるlatestブランチと、四半期ごとにメジャーバージョンが更新されるquarterlyブランチが存在します。どちらを選ぶかによってインストールされるパッケージのバージョンが変化します。この記事ではデフォルト設定であるquarterlyを前提に説明しますが、後述するNode.jsの都合でlatestの方がMisskeyのアップデートへの追従が楽かもしれません。以下のようにすることでlatestに変更ができます。

mkdir -p /usr/local/etc/pkg/repos
cp /etc/pkg/FreeBSD.conf /usr/local/etc/pkg/repos

の後、/usr/local/etc/pkg/repos/FreeBSD.confをエディタで開き

  url: "pkg+http://pkg.FreeBSD.org/${ABI}/quarterly",

の行を

  url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",

に変更して保存

依存関係のインストール

以下のパッケージをインストールします。

  • devel/git-tiny
    Misskeyのソースコードのダウンロード、アップデートに使用します。フル機能は必要なく、最小限の機能のみのtinyで十分です。
  • www/nodeもしくはwww/node20
    Node.jsです。www/node20がNode.js 20のパッケージ、www/nodeがその時最新のLTSをインストールするメタパッケージです。この記事を書いている現状でMisskeyの依存は20.4以上なのですが、降ってくるバージョンがリポジトリによって以下の表のように差があります。
    この通り、quarterlyブランチの場合www/nodeではMisskeyの依存を満たせないため、注意が必要です。latestブランチの場合は、メジャーバージョンを自動で最新のLTSに合わせてくれるwww/nodeパッケージの方がおすすめです。
 quarterlylatest
www/node18.18.220.9.0
www/node2020.8.120.9.0
  • www/npmもしくはwww/npm-node20
    npmです。FreeBSDではNode.jsのパッケージとnpmのパッケージが分離されているので注意しましょう。こちらもNode.js同様、使用するリポジトリに合わせてパッケージを選びましょう。
  • databases/postgresql15-serverもしくはdatabases/postgresql16-server
    PostgreSQLです。こちらにはメタパッケージが存在しないので、リポジトリに関係なくバージョンを指定してあげる必要があります。同時に複数のバージョンをインストールすることはできないので、他に動かしたいソフトウェアがあればそちらの依存も考慮してバージョンを選びましょう。Misskeyの依存は15以上ですので、15と16が使用できます。
  • databases/redis
    Redisです。特に意識しなければいけないことはありません。
  • graphics/vips
    FreeBSDで動かす上で唯一Linuxと異なる点です。Linuxではnpmで提供されるバイナリが使用できますが、FreeBSD用のバイナリは存在しないためシステムにインストールする必要があります。

面倒くさがりの方のためのインストールコマンドです。

  • latestブランチの場合

    pkg install -y node npm postgresql15-server redis vips
    
  • quarterlyブランチの場合

    pkg install -y node20 npm-node20 postgresql15-server redis vips
    

続いて、corepackを有効にします。

corepack enable

これで必要なものが揃いました。

PostgreSQLの設定

service postgresql enable
service postgresql initdb
service postgresql start
psql -U postgres
CREATE ROLE misskey LOGIN PASSWORD 'password';
CREATE DATABASE misskey OWNER misskey;
\q

'password'の部分を好きなパスワードに置き換えてください。

Redisの設定

service redis enable
service redis start

ファイアウォールの設定

FreeBSDで使用できるファイアウォールアプリケーションはいくつかありますが、ここでは設定が簡単なpfを使用します。OpenBSD由来のプロジェクトです(OpenBSD側の変更はほぼ取り込まれておらず実質ハードフォークになっているようですが)。

/etc/pf.confを作成し、お好きなエディタで編集してください。

set skip on lo0

block in all
pass out all keep state

pass in proto tcp to any port { 80 443 }

SSHのポートなど、他に開放したいポートがあれば{ 80 443 }の部分に追加してください。

pass in proto tcp from 192.168.0.0/24 to any port 22のようにすれば、ローカルの接続だけ受け入れるようにもできます。

完了したら有効化します。

service pf enable
service pf start

設定ファイルの構文に問題がある場合、ここで怒られます。修正してください。

Misskeyのビルド

まずはmisskey用のユーザーを作成します。adduserを使用しますが、Ubuntuなどで使用されているものとはかなり異なります。以下のように進めていけばOKです。

adduser
Username: misskey
Full name: Misskey
Uid (Leave empty for default):
Login group [misskey]:
Login group is misskey. Invite misskey into other groups? []:
Login class [default]:
Shell (sh csh tcsh nologin) [sh]:
Home directory [/home/misskey]:
Home directory permissions (Leave empty for default): 700
Use password-based authentication? [yes]: no
Lock out the account after creation? [no]:
OK? (yes/no) [yes]:
Add another user? (yes/no) [no]:
Goodbye!

さきほど作成したユーザーに切り替え、Gitを用いソースコードをクローンし、依存関係をインストールします。

su - misskey
git clone -b master https://github.com/misskey-dev/misskey.git --recurse-submodules
NODE_ENV=production pnpm install --frozen-lockfile

設定ファイルをコピーします。

cp .config/example.yml .config/default.yml

.config/default.ymlをお好きなエディタで開き、適宜編集してください。FreeBSDに特有な点などはありません。

完了後、ビルドします。ただし、このままではビルドが通らない(後述)ため、若干の修正を行います。

packages/backend/.swcrcをエディタで開き

"keepImportAttributes": true

の行を

"keepImportAssertions": true

に変更します。変更を保存し

NODE_ENV=production pnpm run build

でビルドが完了しました。後は

pnpm run init

でデータベースの初期化をすれば

NODE_ENV=production pnpm run start

でMisskeyを起動することができます。お疲れさまでした。

(本当はこの後Misskeyのサービス化まで説明する予定でしたが、間に合わなかったためひとまずここまでです。後日追記しますので、お待ちください。)

MisskeyをFreeBSDで動かすまでの過程

時は戻って2023年4月、Misskey v13.10をFreeBSDで動かそうとする人間がいました。私です。

この時、躓いた点は以下の三点です。

  1. sharpがインストールできない
  2. re2がインストールできない
  3. no bindings found

Sharpがインストールできない

pnpm installがsharpのインストールでコケました。原因は簡単です。「依存関係のインストール」のセクションで説明した通り、vipsがインストールされていないためです。

少し詳しく見てみましょう。

Misskeyは、内部の画像処理(サムネイル生成、webpへの圧縮など)にsharpというモジュールを使用しています。そして、このsharpはlibvipsというライブラリを使用することで高速な変換を実現しています。ここで、sharpがどのようにlibvipsを読み込んでいるかというのがポイントです

npmには、@img/sharp-libvips-<os>-<arch>というパッケージがOS、アーキテクチャごとに存在し、これをNode.jsモジュールとして読み込むことでNode.js外への依存を排除して動作することが可能になっています。

では、npm上を@img/sharp-libvips-freebsd-x64で検索してみましょう。

https://www.npmjs.com/search?q=@img/sharp-libvips-freebsd-x64

はい。存在しません。これが、graphics/vipsが必要となる理由です。npmにFreeBSD用のモジュールが存在せずNode.js、npmのエコシステム内で完結しないため、システム上にライブラリが必要になるわけです。

これは、graphics/vipsをインストールするだけで解決できました。簡単です。

re2がインストールできない

sharpの問題が解決したと思ったら、今度はre2がインストールできないと言われました。しかも、今度はまともなエラーメッセージがありません。

これは、www/npm-nodeのインストールで解決できました。

Bindings not found.

以上二点で依存関係の問題は解決できました。これでやっとpnpm run buildを実行できるのですが、ここでも問題が発生しました。

packages/backend build: Bindings not found.

謎のエラーが発生。いろいろと調べた結果、どうやらswcに存在するFreeBSD用バイナリがMisskeyの依存関係に入っておらず、それが原因と分かりました。

その後、GitHubにてIssueを建て、無事修正していただけたことで解決できました。

ここまででMisskey v13.10がFreeBSDで動くようになりました。しかし、Misskey v13.12にて新たな壁が出現します。

slaccの採用

2023/05/05、Misskeyは独自のライブラリであるslaccを採用しました。計算量の多い処理をRustで置き換えることでパフォーマンスの向上を図るものです(間違っていたらごめんなさい)。

このslaccはswcやsharp-libvipsと同様、バイナリ形式で配布、利用します。つまり、FreeBSDで利用するためにはFreeBSD用のバイナリを用意する必要があるということです。

幸い、元々「FreeBSDにも対応させよう」という流れがあったようで、GitHub ActionsにFreeBSD向けにビルドするステップを追加しPull Requestを送信したところ、無事マージしていただけました。

これにて、ついにMisskeyをFreeBSD上で動かすことができるようになり、この記事にまとめられる…はずでした。

pnpm run buildに失敗する

それは、12/07(記事公開の前日)、この記事を書き終え、記事の指示に従ってちゃんとインストールできるかどうかを確認していた時のことでした。

[blog/Screenshot_20231207_222357]

ビルドに失敗している!!!

記事がボツになるかと焦りましたが、原因、そして対処法はわかりました。冒頭に述べたswcの話に繋がります。

この記事の冒頭で、swcについて「Windows / macOS / Linux / FreeBSD / Android用のバイナリは配布されています」と書きましたが、実のところ、現在も更新がされているのはこのうちWindows/macOS/Linuxのみで、FreeBSD、Android用のバイナリはバージョン1.3.11を最後に更新が停止しています。

そして、このエラーの原因は「swcのアップデートにより設定のパラメータ名が変更されたこと」のようでした。幸い、処理自体は変わっていないか影響のないほど小さいものだったようで、パラメータ名を戻すことでビルドは通りましたが、残念ながら今後もそうである保証はありません…。

最後の最後で悲しい話となってしまいましたが、ひとまずこれがMisskey on FreeBSDを成功させるまでの過程でした。

おわりに

アドベントカレンダーに登録した当初は、MisskeyのFreeBSD対応の話をタネとして世の中のソフトウェアがFreeBSDを初めとするマイナーOSに対応していないことを嘆く記事にしようと思っていたのですが、あくまで「Misskeyアドベントカレンダー」なのでやめにしました。 その後どういう記事にするかかなり悩み、結果前日の夜まで書いていた(正直ビルドエラーが出たときは本当に焦った)ため、もしかしたら間違い等があるかと思います(そもそもまるで推敲できていない…)。発見された場合は@syobon@syo.barもしくは@syobon@misskey.ioまでご連絡ください。

近年、Linuxへはユーザー人口の増加を追い風に様々な新機能が開発・投入されています。これにより利便性が格段に向上する一方、伝統的なUNIXからは少しずつ遠ざかっているように思います。それは決して悪いことではありませんが、たまには伝統的なUNIXに近いものを触ってみるのはどうでしょうか。Void Linux、FreeBSD、NetBSDなどが選択肢に上がるでしょう(そして、おそらくこの順により伝統に近いと思います)。

さて、Misskeyアドベントカレンダー、翌日は1枠目がyupixさんによる「MiPAとMiPACの進捗」、2枠目がCYakigasiさんによる「Telnetから操作するMisskeyクライアントを作る」です。アドベントカレンダーはまだまだ続きます。楽しんでいきましょう。

では、Misskeyユーザーの皆様、よいお年を!(まだちょっと早い)


[CC BY-SA]

このサイト上の文章はCC BY-SAライセンスの下公開されています。

© SyoBoN Some rights reserved.