Pleroma 2.5.0 の構築 - 環境: Elixir 1.11 on OpenBSD 7.1

作成
( 更新 )
@nabbisen

はじめに

Pleroma は Fediverse (フェディヴァース) の実装の一つです。マイクロブロギング用途に開発されていて、TwitterMastodon に近いです。Elixir (言語) が使用されています。それにより「Erlang (言語) の VM 上で動くため、低レイテンシで / 分散処理を行えて / フォールト・トレラントな (耐障害性を有する) システム」であることが期待できます。

こちらが初期状態のランディング画面です:

pleroma フロントページ

最新のメジャーマイナーバージョンである 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 を使うことが、ApacheCaddy と比較して、多い印象です。

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/ にアクセスしてみましょう。フロント・ページが表示されるでしょう !!

サイン・インすると、ダッシュボードが現れるはずです 🐡

pleroma-user

Fediverse の遊泳を楽しんでください :)

参考

Series

Fediverse on OpenBSD
  1. Pleroma 2.5.0 の構築 - 環境: Elixir 1.11 on OpenBSD 7.1

Comments or feedbacks are welcomed and appreciated.