この記事は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
パッケージの方がおすすめです。
quarterly | latest | |
---|---|---|
www/node | 18.18.2 | 20.9.0 |
www/node20 | 20.8.1 | 20.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で動かそうとする人間がいました。私です。
この時、躓いた点は以下の三点です。
- sharpがインストールできない
- re2がインストールできない
- 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(記事公開の前日)、この記事を書き終え、記事の指示に従ってちゃんとインストールできるかどうかを確認していた時のことでした。
ビルドに失敗している!!!
記事がボツになるかと焦りましたが、原因、そして対処法はわかりました。冒頭に述べた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ユーザーの皆様、よいお年を!(まだちょっと早い)