はじめに
Pleroma は Fediverse (フェディヴァース) の実装の一つです。マイクロブロギング用途に開発されていて、Twitter や Mastodon に近いです。Elixir (言語) が使用されています。それにより「Erlang (言語) の VM 上で動くため、低レイテンシで / 分散処理を行えて / フォールト・トレラントな (耐障害性を有する) システム」であることが期待できます。
こちらが初期状態のランディング画面です:
最新のメジャーマイナーバージョンである 2.5.0 が先月にリリースされました 🎉🎉🎉
本記事で OpenBSD という堅牢な Unix システムにインストールする方法をご紹介します。
なぜ最新の 7.2 では無く 7.1 の OpenBSD を使ったのか ?
Pleroma をインストールするには、OpenBSD 7.1 を使うほうが簡単でした。と言うのも、Ports にある Elixir を利用できたからです。
7.2 の場合、Ports にある Elixir を使うと、以下の mix タスクが失敗したのです:
$ env LC_ALL=en_US.UTF-8 MIX_ENV=prod \
mix phx.server
以下のエラーが出ました:
xx:xx:xx.xxx [notice] Application runtime_tools exited: :runtime_tools.start(:normal, []) returned an error: shutdown: failed to start child: :ttb_autostart
** (EXIT) an exception was raised:
** (UndefinedFunctionError) function :observer_backend.ttb_resume_trace/0 is undefined (module :observer_backend is not available)
(runtime_tools 1.19) :observer_backend.ttb_resume_trace()
(runtime_tools 1.19) ttb_autostart.erl:47: :ttb_autostart.init/1
(stdlib 4.0.1) gen_server.erl:848: :gen_server.init_it/2
(stdlib 4.0.1) gen_server.erl:811: :gen_server.init_it/6
(stdlib 4.0.1) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
{"Kernel pid terminated",application_controller,"{application_start_failure,runtime_tools,{{shutdown,{failed_to_start_child,ttb_autostart,{undef,[{observer_backend,ttb_resume_trace,[],[]},{ttb_autostart,init,1,[{file,\"ttb_autostart.erl\"},{line,47}]},{gen_server,init_it,2,[{file,\"gen_server.erl\"},{line,848}]},{gen_server,init_it,6,[{file,\"gen_server.erl\"},{line,811}]},{proc_lib,init_p_do_apply,3,[{file,\"proc_lib.erl\"},{line,240}]}]}}},{runtime_tools,start,[normal,[]]}}}"}
Kernel pid terminated (application_controller) ({application_start_failure,runtime_tools,{{shutdown,{failed_to_start_child,ttb_autostart,{undef,[{observer_backend,ttb_resume_trace,[],[]},{ttb_autostart,init,1,[{file,"ttb_autostart.erl"},{line,47}]},{gen_server,init_it,2,[{file,"gen_server.erl"},{line,848}]},{gen_server,init_it,6,[{file,"gen_server.erl"},{line,811}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]}}},{runtime_tools,start,[normal,[]]}}})
Crash dump is being written to: erl_crash.dump...done
可能性として、7.2 では Ports が提供する Elixir のバージョンが 1.14 であることが、原因かもしれません。
環境
- OpenBSD 7.1 (リリース日 2022 年 4 月 21 日)
- PostgreSQL 14.5 (リリース日 2022 年 4 月 11 日)
- Erlang/OTP 21.2.5 (リリース日 2019 年 2 月 4 日)
- Elixir 1.11.4 (リリース日 2021 年 5 月 16 日)
- Pleroma (リリース日 2022 年 12 月 23 日)
チュートリアル
データベース / アプリケーション・エンジン / ユーザー の準備
データベース / アプリケーション・エンジン / サービス・デーモンのユーザー を準備する必要があります。
PostgreSQL サーバーのインストール (必要な場合)
データベース・サーバーが環境下ですでに動いていて、且つ * postgresql-contrib エクステンションが設定されている * 場合は、本節をスキップできます。
PostgreSQL とエクステンションをインストールします:
$ doas pkg_add postgresql-server \
postgresql-contrib
出力は以下の通りでした:
quirks-5.5 signed on 2022-10-18T12:24:43Z
postgresql-server-14.5:libxml-2.9.13p2: ok
postgresql-server-14.5:postgresql-client-14.5: ok
useradd: Warning: home directory `/var/postgresql' doesn't exist, and -m was not specified
postgresql-server-14.5: ok
postgresql-contrib-14.5: ok
Running tags: ok
The following new rcscripts were installed: /etc/rc.d/postgresql
See rcctl(8) for details.
New and changed readme(s):
/usr/local/share/doc/pkg-readmes/postgresql-server
それからデータベース・システムの初期構成を行います。
_postgresql
として振る舞います:
$ doas su _postgresql -
次のコマンドを実行してください:
$ initdb -D /var/postgresql/data -U postgres
出力は以下の通りでした:
The files belonging to this database system will be owned by user "_postgresql".
This user must also own the server process.
The database cluster will be initialized with locale "C".
The default database encoding has accordingly been set to "SQL_ASCII".
The default text search configuration will be set to "english".
Data page checksums are disabled.
creating directory /var/postgresql/data ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 20
selecting default shared_buffers ... 128MB
selecting default time zone ... Asia/Tokyo
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
initdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
Success. You can now start the database server using:
pg_ctl -D /var/postgresql/data -l logfile start
できました。
$ exit
最後に、デーモンを有効にして起動しましょう:
$ doas rcctl enable postgresql
$ doas rcctl start postgresql
Elixir のインストール
ありがたいことに、Ports システムは、今回必要な Elixir のアプリケーション環境を提供してくれています:
$ doas pkg_add elixir
出力は以下の通りでした:
quirks-5.5 signed on 2022-10-18T12:24:43Z
elixir-1.11.4p0:erlang-21.2p5v0: ok
elixir-1.11.4p0: ok
--- +erlang-21.2p5v0 -------------------
You may wish to add /usr/local/lib/erlang21/man to /etc/man.conf
Pleroma 用パッケージのインストール
さらに Ports システムは私たちを手助けしてくれます。
必要なパッケージ群をインストールしましょう:
$ doas pkg_add gmake \
git cmake libmagic
追加で、必須ではありませんが、これらのものもインストールすると良いかもしれません:
$ doas pkg_add ImageMagick \
ffmpeg p5-Image-ExifTool
前者の出力結果は以下の通りでした:
quirks-5.5 signed on 2022-10-18T12:24:43Z
gmake-4.3: ok
git-2.35.1p0:cvsps-2.1p2: ok
(...)
git-2.35.1p0: ok
cmake-3.20.3p6v0:libuv-1.44.1: ok
(...)
cmake-3.20.3p6v0: ok
libmagic-5.43: ok
The following new rcscripts were installed: /etc/rc.d/gitdaemon
See rcctl(8) for details.
New and changed readme(s):
/usr/local/share/doc/pkg-readmes/git
後者については以下の通りでした:
quirks-5.5 signed on 2022-10-18T12:24:43Z
ImageMagick-6.9.12.38:x265-3.5p0: ok
(...)
ImageMagick-6.9.12.38: ok
ffmpeg-4.4.1p3v1:fribidi-1.0.11: ok
(...)
ffmpeg-4.4.1p3v1: ok
p5-Image-ExifTool-12.40: ok
Running tags: ok
New and changed readme(s):
/usr/local/share/doc/pkg-readmes/ffmpeg
/usr/local/share/doc/pkg-readmes/sdl2
ユーザーの作成とプロジェクト・ディレクトリの作成
アプリの実行ユーザーを作成しましょう。rc.d
すなわちデーモンスクリプトで使います:
$ doas useradd \
-d /var/www/_pleroma -m _pleroma
/var/www/_pleroma
をホーム・ディレクトリとして定義して、ここで自動生成されるようにしています。
その隣にプロジェクト・ディレクトリを作成しましょう。パーミッションも設定します:
$ doas mkdir /var/www/pleroma
$ doas chown -R \
_pleroma:_pleroma /var/www/pleroma
最後に、ユーザーのログイン・クラスを拡張します。なぜかと言うと、デフォルト設定値では Elixir の Phoenix アプリを実行するには小さ過ぎるからです:
$ doas nvim /etc/login.conf
以下のように追記します:
+ _pleroma:\
+ :datasize-max=1536M:\
+ :datasize-cur=1536M:\
+ :openfiles-max=4096
追記内容を反映させます:
$ doas cap_mkdb /etc/login.conf
ご参考までに、結果は以下のようになりました:
$ ls -l /etc/login*
-rw-r--r-- 1 root wheel 2785 Dec 26 21:02 /etc/login.conf
-rw-r--r-- 1 root wheel 73728 Dec 26 21:02 /etc/login.conf.db
(...)
Pleroma のインストール
とうとうメインの節にたどり着きました。
カレントディレクトリ確認後にソースを取得
こちらのユーザーとして振る舞います:
$ doas su _pleroma -
ログイン・シェルは ksh
のはずです。
さて、プロジェクト・ディレクトリへ行きましょう:
$ cd /var/www/pleroma
最新の安定版ソースをカレント・ディレクトリに配置します:
$ git clone -b stable \
https://git.pleroma.social/pleroma/pleroma.git \
.
出力は以下の通りでした:
Cloning into '.'...
remote: Enumerating objects: 155563, done.
remote: Counting objects: 100% (1606/1606), done.
remote: Compressing objects: 100% (562/562), done.
remote: Total 155563 (delta 1131), reused 1458 (delta 1040), pack-reused 153957
Receiving objects: 100% (155563/155563), 198.25 MiB | 6.12 MiB/s, done.
Resolving deltas: 100% (118994/118994), done.
Mix タスク: deps.get
依存パッケージを取得します:
$ mix deps.get
Hex をインストールするかどうかたずねられます。“y” を入力して進みましょう:
warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell)
!!! RUNNING IN LOCALHOST DEV MODE! !!!
FEDERATION WON'T WORK UNTIL YOU CONFIGURE A dev.secret.exs
Could not find Hex, which is needed to build dependency :phoenix
Shall I install Hex? (if running non-interactively, use "mix local.hex --force") [Yn] y
出力は以下の通りでした:
* creating /var/www/_pleroma/.mix/archives/hex-2.0.0
* Getting gettext (https://github.com/tusooa/gettext.git - 72fb2496b6c5280ed911bdc3756890e7f38a4808)
remote: Enumerating objects: 4046, done.
remote: Counting objects: 100% (254/254), done.
remote: Compressing objects: 100% (130/130), done.
remote: Total 4046 (delta 121), reused 213 (delta 100), pack-reused 3792
(...)
Resolving Hex dependencies...
Resolution completed in 1.875s
Unchanged:
accept 0.3.5
(...)
websockex 0.4.3
* Getting phoenix (Hex package)
(...)
* Getting phoenix_pubsub (Hex package)
You have added/upgraded packages you could sponsor, run `mix hex.sponsor` to learn more
elixir-captcha は OpenBSD ではうまく動かないので修正 (必要に応じて)
elixir-captcha
の 0.1.0 が前段の操作でやって来ています。しかしこちらは OpenBSD ではうまく動きません。なぜなら環境によらず make
を実行するからです。Pleroma のネイティヴなキャプチャを使いたいのであれば、代わりに gmake
を使うように、下記ファイルの内容を変える必要があります:
$ nvim deps/captcha/mix.exs
次のように編集します:
defmodule Mix.Tasks.Compile.Make do
def run(_) do
- {result, _error_code} = System.cmd("make", [], stderr_to_stdout: true)
+ {result, _error_code} = System.cmd("gmake", [], stderr_to_stdout: true)
Mix.shell().info(result)
(...)
defmodule Mix.Tasks.Clean.Make do
def run(_) do
- {result, _error_code} = System.cmd("make", ['clean'], stderr_to_stdout: true)
+ {result, _error_code} = System.cmd("gmake", ['clean'], stderr_to_stdout: true)
Mix.shell().info(result)
このようにしておかなければ、mix pleroma.instance gen
実行時に、以下のようなエラーが発生します。もっともこれは致命的なものではありません:
==> captcha
rm -f priv/captcha src/captcha.o
cc -g -c src/captcha.c
mkdir -p priv
cc -I src -o priv/captcha src/captcha.o
cc: error: no such file or directory: 'src/captcha.o'
cc: error: no input files
*** Error 1 in /var/www/pleroma/deps/captcha (Makefile:10 'priv/captcha')
Mix タスク: pleroma.instance gen
Pleroma インスタンスを生成しましょう:
$ env MIX_ENV=prod \
mix pleroma.instance gen
rebar3 をインストールするかどうかたずねられます。先ほどのように “y” を入力して進みましょう:
warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell)
warning: `config/prod.secret.exs` not found. You may want to create one by running `mix pleroma.instance gen`
Could not find "rebar3", which is needed to build dependency :parse_trans
I can install a local copy which is just used by Mix
Shall I install rebar3? (if running non-interactively, use "mix local.rebar --force") [Yn] y
出力は以下の通りでした:
* creating /var/www/_pleroma/.mix/rebar
* creating /var/www/_pleroma/.mix/rebar3
===> Analyzing applications...
===> Compiling parse_trans
(...)
==> pleroma
Compiling 592 files (.ex)
(...)
Generated pleroma app
アプリ設定
その後、以下のようにたずねられるでしょう。ここはご自身の環境に合わせてください。
What domain will your instance use? (e.g pleroma.soykaf.com) [] pleroma-on-openbsd.com
What is the name of your instance? (e.g. The Corndog Emporium) [pleroma-on-openbsd.com]
What is your admin email address? [] [email protected]
What email address do you want to use for sending email notifications? [[email protected]]
Do you want search engines to index your site? (y/n) [n]
Do you want to store the configuration in the database (allows controlling it from admin-fe)? (y/n) [n]
What is the hostname of your database? [localhost] 127.0.0.1
What is the name of your database? [pleroma]
What is the user used to connect to your database? [pleroma]
What is the password used to connect to your database? [autogenerated]
Would you like to use RUM indices? [n]
What port will the app listen to (leave it if you are using the default setup with nginx)? [4000]
What ip will the app listen to (leave it if you are using the default setup with nginx)? [127.0.0.1]
What directory should media uploads go in (when using the local uploader)? [uploads]
What directory should custom public files be read from (custom emojis, frontend bundle overrides, robots.txt, etc.)? [instance/static/]
Do you want to strip location (GPS) data from uploaded images? This requires exiftool, it was detected as installed. (y/n) [y]
Do you want to read data from uploaded files so clients can use it to prefill fields like image description? This requires exiftool, it was detected as installed. (y/n) [y]
Do you want to anonymize the filenames of uploads? (y/n) [n] y
Do you want to deduplicate uploaded files? (y/n) [n]
Writing config to config/generated_config.exs.
Writing the postgres script to config/setup_db.psql.
Writing /var/www/pleroma/instance/static/robots.txt.
All files successfully written! Refer to the installation instructions for your platform for next steps.
インスタンスの生成はこれで完了です !! 設定をカスタマイズする準備をしておきましょう:
$ cp config/generated_config.exs \
config/prod.secret.exs
アプリのカスタマイズ (必要に応じて)
上のファイルの編集が必要な場合もあるかもしれません:
$ nvim config/prod.secret.exs
一例ですが PostgreSQL サーバーが外部ホストで動いている時、しかも TLS/SSL 接続が必要な時です:
config :pleroma, Pleroma.Repo,
(...)
- hostname: "(your-hostname)"
+ hostname: "(your-hostname)",
+ port: xxx,
+ ssl: true
(...)
+ config :pleroma, Pleroma.Captcha,
+ enabled: true
別の例です。ネイティヴなキャプチャの代わりに kocaptcha を使いたい時があるかもしれません:
+ config :pleroma, Pleroma.Captcha,
+ enabled: true,
+ method: Pleroma.Captcha.Kocaptcha
データベースのマイグレーション
Pleroma のデータベースをセットアップしましょう。 こちらを実行します:
$ psql -U postgres -f config/setup_db.psql
出力は以下の通りでした:
CREATE ROLE
CREATE DATABASE
You are now connected to database "pleroma" as user "postgres".
CREATE EXTENSION
CREATE EXTENSION
CREATE EXTENSION
マイグレーション・コマンドを実行します:
$ env MIX_ENV=prod \
mix ecto.migrate
出力は以下の通りでした:
warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell)
Compiling 592 files (.ex)
(...)
xx:xx:xx.xxx [info] == Migrated 20221103014728 in 0.0s
xx:xx:xx.xxx [info] == Running 20221111164213 Pleroma.Repo.Migrations.DeprecateQuack.up/0 forward
xx:xx:xx.xxx [info] == Migrated 20221111164213 in 0.0s
Mix タスク: Phoenix サーバーの起動
準備がほぼほぼ完了しました。Phoenix を起動しましょう:
$ env LC_ALL=en_US.UTF-8 MIX_ENV=prod \
mix phx.server
出力は以下の通りでした:
xx:xx:xx.xxx [warning] Description: 'Authenticity is not established by certificate path validation'
Reason: 'Option {verify, verify_peer} and cacertfile/cacerts is missing'
xx:xx:xx.xxx [info] tzdata release in place is from a file last modified Wed, 21 Oct 2020 18:40:20 GMT. Release file on server was last modified Sat, 29 Oct 2022 01:50:44 GMT.
xx:xx:xx.xxx [warning] The on_load function for module crypt returned:
{:error, {:load, 'Library load-call unsuccessful (1).'}}
xx:xx:xx.xxx [info] Tzdata has updated the release from 2020d to 2022f
xx:xx:xx.xxx [warning] The on_load function for module crypt returned:
{:error, {:load, 'Library load-call unsuccessful (1).'}}
xx:xx:xx.xxx [info] Running Pleroma.Web.Endpoint with cowboy 2.9.0 at 127.0.0.1:4000 (http)
xx:xx:xx.xxx [info] Access Pleroma.Web.Endpoint at https://(your-domain)
xx:xx:xx.xxx [info] Gopher server disabled
xx:xx:xx.xxx [info] Transferring embedded hashtags to `hashtags` (from oid: 0)...
xx:xx:xx.xxx [warn] The on_load function for module crypt returned:
{:error, {:load, 'Library load-call unsuccessful (1).'}}
(...)
xx:xx:xx.xxx [info] Running Pleroma.Web.Endpoint with cowboy 2.9.0 at 127.0.0.1:4000 (http)
xx:xx:xx.xxx [info] Access Pleroma.Web.Endpoint at https://pleroma-on-openbsd.com
xx:xx:xx.xxx [info] Gopher server disabled
xx:xx:xx.xxx [info] Transferring embedded hashtags to `hashtags` (from oid: 0)...
xx:xx:xx.xxx [info] Deleting context objects from `objects` (from oid: 0)...
サーバーの疎通
上の Phoenix (内実は Pleroma アプリ) のプロセスは、動いたままにしておいてください。
レスポンスが正しく返って来るか見てみましょう:
$ curl -I http://127.0.0.1:4000/
私が実行した時、レスポンスヘッダーの内容は、以下の通りでした:
HTTP/1.1 200 OK
access-control-allow-credentials: true
access-control-allow-origin: *
access-control-expose-headers: Link,X-RateLimit-Reset,X-RateLimit-Limit,X-RateLimit-Remaining,X-Request-Id,Idempotency-Key
cache-control: max-age=0, private, must-revalidate
content-length: 7880
content-security-policy: upgrade-insecure-requests;script-src 'self' 'wasm-unsafe-eval';connect-src 'self' blob: https://pleroma-on-openbsd.com wss://pleroma-on-openbsd.com;media-src 'self' https:;img-src 'self' data: blob: https:;default-src 'none';base-uri 'self';frame-ancestors 'none';style-src 'self' 'unsafe-inline';font-src 'self';manifest-src 'self';
content-type: text/html; charset=utf-8
date: Mon, 26 Dec 2022 12:35:06 GMT
permissions-policy: interest-cohort=()
referrer-policy: same-origin
server: Cowboy
x-content-type-options: nosniff
x-download-options: noopen
x-frame-options: DENY
x-permitted-cross-domain-policies: none
x-request-id: FzRX_VnDh-YizPQAABaR
x-xss-protection: 1; mode=block
良い感じです :)
“HTTP/… 200 OK” が出力されていれば、Pleroma はうまく動いていると考えて大丈夫です。
Pleroma admin の作成
いちおうの確認ですが、いま /var/www/pleroma
に _pleroma ユーザーとして いるでしょうか。
もしそうでしたら、次のコマンドで、スーパー・ユーザーを作成しましょう:
$ env LC_ALL=en_US.UTF-8 MIX_ENV=prod \
mix pleroma.user new \
(admin-name) ([email protected]) --admin
以下のようにたずねられるはずです:
A user will be created with the following information:
- nickname: pleroma_admin
- email: [email protected]
- password: [generated; a reset link will be created]
- name: (admin-name)
- bio:
- moderator: false
- admin: true
Continue? [n] y
私が続行した時は、以下のように出力されました:
User (admin-name) created
Admin status of (admin-name): true
Generated password reset token for (admin-name)
URL: https://(your-domain))/api/v1/pleroma/password_reset/xxx...
relayd の起動
Pleroma はデフォルトでは 127.0.0.1 つまり localhost のみをリッスンします。
サービスとして公開するためには、Web サーバーと組み合わせる必要があります。Pleroma では nginx を使うことが、Apache や Caddy と比較して、多い印象です。
OpenBSD では relayd が開発されており、サポートされています。OpenBSD のネイティブなリレー・デーモンであり、「ロード・バランサー、アプリケーション・レイヤー・ゲートウェイ、および透過型プロキシとして作用する」とされています。 relayd を使って、Pleroma を外部とつなげてリクエスト / レスポンスのやり取りをさせるには、こちらのファイルを編集します:
$ doas nvim /etc/relayd.conf
最もシンプルな設定内容は以下のようなものでしょう:
table <pleroma_server> { 127.0.0.1 }
relay pleroma {
listen on egress port 4000
forward to <pleroma_server> port 4000 check http "/" code 200
}
こちらを有効化して、起動しましょう:
$ doas rcctl enable relayd
$ doas rcctl start relayd
rc.d スクリプト
Pleroma をサービスとして公開する上で、もう一つ問題が残っています。 デーモンとして登録されていません。
この点をクリアするために、rc.d スクリプトをつくりましょう:
$ doas nvim /etc/rc.d/pleroma
以下のように記述します:
#!/bin/ksh
daemon="cd /var/www/pleroma; env LC_ALL=en_US.UTF-8 MIX_ENV=prod mix"
daemon_user="_pleroma"
daemon_flags="phx.server --no-compile"
. /etc/rc.d/rc.subr
rc_cmd $1
余談ですが、私は cd ...;
を使う代わりに daemon_execdir="/var/www/pleroma"
を使う方法も試しました。しかしうまく行きませんでした。
ファイルのパーミッションを設定しましょう:
$ doas chmod a+x /etc/rc.d/pleroma
有効化して、起動します:
$ doas rcctl enable pleroma
$ doas rcctl start pleroma
なお別のやり方もあります。まだ無効な状態のままにしておきたい場合は、-f
オプションを使って一時的に起動することも可能です: doas rcctl -f start pleroma
というコマンドを実行すれば良いです。
おわりに
ブラウザで http://127.0.0.1:4000/
にアクセスしてみましょう。フロント・ページが表示されるでしょう !!
サイン・インすると、ダッシュボードが現れるはずです 🐡
Fediverse の遊泳を楽しんでください :)