西川和久の不定期コラム

Ubuntu 22.04を使ってMastodon(非Docker)を動かす!正式リリースされたストア版WSL2で起動

 長らくWindowsのLinux環境としてWSL(Windows Subsystem for Linux)が使われていたものの、Microsoftストア版が正式リリースされたのは昨年(2022年)11月。そこで、リアルLinuxにどこまで迫る環境になったのか、Mastodonを非Dockerで動かしてみたい。

WSLバージョン1.0.0リリースで完成度高まる

 約5年前(2017年)、Mastodonがリリースされた直後のタイミングで、Hyper-V+Dockerを動かす記事を書いている。同じ手法で設定したLinux+Dockerで、しばらくの間Mastodonサーバーを運営していたのは今となっては懐かしい話。

 そして忘れたころに、例のTwitter騒動でMastodonが再注目されだしたのはご存知の通り。当時のバージョンはv1系だったが、現在v4系と随分上がっている。そう言えば、ストア版WSL2も正式版になったので入るかな?と考えたのが、この記事を書き出したきっかけとなる。

 WSL1とWSL2の違いをざっくり言うと、前者がAPI変換、後者はほぼVMで動いている。従ってWSL1はお手軽だがWSL2より互換性は低い。

 ほぼVMならHyper-VやVMwareでLinuxを入れればいいのでは?という話になるかもしれないが、インストール自体はアプリストアからダウンロードして起動するだけでOK。VMにLinuxをインストールするような手間はかからない。またWindowsとファイルやコマンドなどが共有できるのも強みだ。

 以前からWSL2は少し触っていたが、これまでsystemdが動かず(systemctl reload nginxなど)、サーバーのバックエンド系で試すには結構辛かった経緯がある。ところが昨年9月にsystemd対応となり、11月にストア版のWSLがバージョン1.0.0として正式リリース。完成度が一気に上がった。

【下準備1】WSL2とUbuntu 22.04.1 LTSをインストール

 Mastodonを動かすにあたっての下準備として、WSL2とUbuntu 22.04 LTSを入れてみたい。手順は以下の通り。今回はWindows 11 Pro(22H2)を使用した。

手順(1)

 「設定」→「アプリ」→「オプション機能」→「Windowsのその他の機能」で、「Linux用Windowsサブシステム(WSL)」と「仮想マシンプラットフォーム」にチェックを入れて、OKをクリック。Windows再起動する。

「設定」→「アプリ」→「オプション機能」→「Windowsのその他の機能」

手順(2)

 「Windows Subsystem for Linux」をMicrosoftストアからインストール。

アプリストアにあるWindows Subsystem for Linux

手順(3)

 「Ubuntu 22.04.1 LTS」をストアからインストールして起動。

アプリストアにあるUbuntu 22.04.1 LTS

 執筆時のWSL2のバージョンは以下の通り。「wsl --update」で確認したが、このタイミングでの更新はなかった。

PS C:\Users\pcwatch> wsl -v
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
MSRDC バージョン: 1.2.3575
Direct3D バージョン: 1.606.4
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windowsバージョン: 10.0.22621.963
PS C:\Users\pcwatch> wsl --update
更新プログラムを確認しています。
Linux 用 Windows サブシステムの最新バージョンは既にインストールされています。

 なお、Ubuntu操作中に失敗か何かして、Ubuntu 22.04をいったん削除、再インストールする場合は、削除後に事前にPowerShellで以下を実行しないと、うまく動かないケースがある。

PS C:\Users\pcwatch> wsl --unregister Ubuntu-22.04

手順(4)

 スタートメニューの「Ubuntu 22.04.1 LTS」のアイコンをクリックすると、Ubuntuが起動。初期設定でユーザー名とパスワードを入力すれば、bashのプロンプト$で入力待ちの状態となる。

 まずいつものおまじないと、この段階では先に書いたsystemdが有効になっておらず(下記の/etc/wsl.confの部分)、その設定をする必要がある。

sudo apt update;sudo apt upgrade -y
sudo sh -c 'cat <<EOF >> /etc/wsl.conf
[boot]
systemd=true
EOF'

手順(5)

 systemdを有効にするため、PowerShellでwslをいったんシャットダウンする。

wsl --shutdown

手順(6)

 Ubuntu再起動して準備完了だ。なお、ほかのマシンからsshで操作したいときには、systemdを有効にした後、以下のような感じでproxyを設定し、ホストマシンのIPアドレスへsshすれば使えるようになる。

 このとき、WSL側のIPアドレスは起動するたびに変わるので再設定が必要(127.0.0.1/::1/localhostのみホストマシンと共用)。ここでは手動でIPアドレスを調べて設定しているが、ネットを検索すれば、自動設定できるスクリプトがいろいろ出てくるので、興味のある人は別途調べてほしい。

sudo apt install openssh-server -y
※sshサーバーをインストール
New-NetFireWallRule -DisplayName 'WSL2 Firewall Unlock' -Direction Inbound -LocalPort 22 -Action Allow -Protocol TCP
※sshのFireWall解除
wsl -e hostname -I
172.17.120.169
※WSL側のIPアドレス取得。WSLを起動するたびに変わるので要注意
netsh interface portproxy add v4tov4 listenaddress=* listenport=22 connectaddress=172.17.120.169 connectport=22
※proxyの設定。IPアドレスは上記で調べたものを使う
netsh interface portproxy show all
※proxyの確認
netsh interface portproxy delete v4tov4 listenport=22 listenaddress=*
※proxyの削除

【下準備2】必要な環境を構築

 Mastodonが必要とする環境を構築する。すべてsudo su後、rootで操作。何度もコピペで確認しているので安心して操作してほしい。 内容としては、必要なパッケージなどをapt install、Node.js系、PostgreSQL(mastodonユーザーを設定)、Rubyとなる。

手順(1)

 以降、rootで操作。

$ sudo su

手順(2)

 必要なパッケージなどをインストール。

# apt install git software-properties-common make apt-transport-https redis-server optipng pngquant jhead jpegoptim gifsicle imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file g++ libprotobuf-dev protobuf-compiler pkg-config gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev libidn11-dev libicu-dev libjemalloc-dev -y

手順(3)

 Node.jsをインストール。

# curl -sL https://deb.nodesource.com/setup_16.x | bash -
# apt install nodejs -y
# curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarnkey.gpg >/dev/null
# echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | tee /etc/apt/sources.list.d/yarn.list
# apt update;apt install yarn -y

手順(4)

 PostgreSQLのインストールと設定。

# apt install postgresql postgresql-contrib -y
# systemctl start postgresql
# sudo -u postgres -i psql
postgres=# CREATE USER mastodon;
postgres=# ALTER USER mastodon createdb;
postgres=# \q

手順(5)

 Rubyのインストール。

# apt install ruby ruby-dev -y

Mastodonをインストール

 いよいよMastodonのインストールだ。これもすべてsudo su後、rootで実行する。やっていることは、mastodonユーザー作成、そのホームディレクトリでMastodonをGitHubからclone、v.4.0.2(執筆時の最新版)でcheckout、bundlerをインストールして、設定開始。最後の一行を実行すると対話式のセットアップとなる。

# adduser mastodon --system --group --disabled-login
# cd /home/mastodon
# git clone https://github.com/tootsuite/mastodon.git live
# chown -R mastodon:mastodon live
# cd live
# sudo -u mastodon git checkout v4.0.2
# gem install bundler
# sudo -u mastodon bundle config deployment 'true'
# sudo -u mastodon bundle config without 'development test'
# sudo -u mastodon bundle install -j$(getconf _NPROCESSORS_ONLN)
# sudo -u mastodon RAILS_ENV=production bundle exec rake mastodon:setup

 以下、入力の必要な部分だけ。ほかはデフォルト[Enter]でいい。adminユーザーを作ったときのパスワードはどこかにメモしておく。

Domain name: mastodon.local
※VirtualHost名

Do you want to enable single user mode? no
※お一人様仕様にするときはyes

Are you using Docker to run Mastodon? no
※Dockerは使わない

Do you want to send e-mails from localhost? yes
※メールは飛ばないので、設定が簡単なlocalhostに

Send a test e-mail with this configuration right now? no
※メールは飛ばないので確認しない

Do you want to create an admin user straight away? Yes
Username:
※デフォルトはadmin。お好みで変更

E-mail: xxxxx@xxxx.com
※ログイン時に使うメールアドレス(確認はないので何でも大丈夫)

You can login with the password: d38f1a9b767fc0d5566d7d2a6d559b83
※初期ログイン時のパスワード。どこかにメモしておく

You can change your password once you login.

 以降は、Mastodon関連サービスの設定と起動。このとき、.rbenv下にあるbundleではなく、/usr/local/bin/bundleを使うのでsedで書き換える。

# cp /home/mastodon/live/dist/mastodon*.service /etc/systemd/system/
# sed -i 's/home\/mastodon\/.rbenv\/shims/usr\/local\/bin/g' /etc/systemd/system/mastodon-*.service
※~/.rbenvは使わない

# systemctl daemon-reload
# systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming
# systemctl status mastodon-web mastodon-sidekiq mastodon-streaming
※動作確認。3つすべてActive: active (running)になっていればOK

 動作確認すると、mastodon-web.service、mastodon-sidekiq.service、mastodon-streaming.service、3つのサービスが動いているのが分かる。これでMastodon側の準備は整った。

仕上げはNginxの設定だが……

 仕上げはWeb側、Nginxの設定となる。ここで以前と変わったところは、.env.productionの記述でLOCAL_HTTPS=falseが使えなくなったこと。つまり、現在のMastodonはhttp非対応なのだ。

 ローカルで動かすのにhttpsにしなくても……と、Nginxのconfをいろいろ触ってhttpでも動くように挑戦したが、コードのどこかでhttpsを決め打ちしている部分があるのか完全には動作しなかった。

 今回のようにローカルPCで試したいときや、AWS/ELB側でSSL証明書を設定することもあり、LOCAL_HTTPS=falseが使えないと、ちょっと面倒な話になる。復活してほしいところ。

 設定自体は以下の通り(同じくrootで実行)。Mastodon固有の/etc/nginx/conf.d/mastodon.confに関しては2箇所書き換え、2行追加となる。

# apt install nginx -y
# cp /home/mastodon/live/dist/nginx.conf /etc/nginx/conf.d/mastodon.conf
# nano /etc/nginx/conf.d/mastodon.conf
server {
  listen 80;
  listen [::]:80;
  server_name mastodon.local;
  ※example.comから書き換え

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name mastodon.local;
  ※example.comから書き換え

  # Uncomment these lines once you acquire a certificate:
  # ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
  # ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
  ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
  ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
  ※上の2行を追加。どのみちlocalhostだと正式なSSL証明書は発行できず、ブラウザで警告が出るため、(何でもいいので)始めからあるものを使う

 さらにもう一箇所。/etc/nginx/nginx.conf。ここはNginx全体の設定。デフォルトはユーザーがwww-dataになっているが、root(サイトの/)が/home/mastodon/live/publicで、ユーザー:グループがmastodon:mastodonになっているため、ここをmastodonへ書き換え、関連するディレクトリのユーザー:グループも変更。nginx -tでconfの文法チェックでOKを確認し、nginxを再起動する。

# nano /etc/nginx/nginx.conf
user mastodon;
※user www-dataから書き換え

# mkdir -p /var/nginx/cache/
# chown -R mastodon:mastodon /var/nginx/cache
# chown -R mastodon:mastodon /var/lib/nginx

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# systemctl reload nginx

 最後にWindows側のhostsファイルを書き換える。このとき、管理者権限で書き換える必要があるので要注意!

C:\Windows\System32\drivers\etc\hosts
127.0.0.1       localhost
::1             localhost
127.0.0.1       mastodon.local
::1             mastodon.local
※上の2行を追加

Mastodon起動!

 これでWebブラウザからhttps://mastodon.localとすれば、「接続がプライベートではありません」と警告が出て、mastodon.localへ進む(安全ではありません)で続行するとMastodonの画面が現れる。ログインは右の[ログイン]をクリックし、先に設定したメールドレスと、表示された初期パスワードを使う。

 そして、マシン環境にもよるがここまでコピペなら10分未満。手順が確定するまで何度もインストールし直したが(笑)、決まってしまえばこの程度でMastodonが起動する(ただしメールは飛ばず、DBのパスワードなどセキュリティ系未設定、外からはアクセスできない……という限定仕様)。

https://mastodon.local/
ログイン画面
ログイン/ユーザー設定/外観
Sidekiq/ダッシュボード

 久々にMastodonを触った感想であるが、「他インスタンスのアカウントをフォローできる」という最大の特徴があるため、(広告目的でなければ)立ち上げたサーバーに人を集める必要もなく、それこそお一人さま仕様にして、気になる外部アカウントをフォロー、マイクロブログ的に使う手がある。また趣味趣向が合う仲間だけ招待/承認で集めてフォロワーのみに公開、昔の草の根BBS的な運用も可能だ。

 極端な話になるが、たとえばスマホのOSにMastodon@お一人さま仕様的なシステムを入れ、呟きはもちろん、位置情報やら心拍数やらライフログ的なものも発信。家族や友人、知り合った人などを公開レベルを分けて……と言ったシステムが考えられる。初めましての連絡先もこれでOK。個人情報や通信量/バッテリの問題があり現実的ではないものの、この手の分散型システムは、最終的には個人レベルまで落とせればまた違った世界が見えるような気がする。

 いかがだろうか。WSL2がsystemdに対応したこともあり、Mastodonの基本部分はまったく変更なく、そのまま動いてしまうのがお分かりいただけたと思う(触ったのは環境依存部分のみ)。

 正式版のWSL2はなかなか良い存在となった。ひと手間かければsshもできるので、Visual Studio Codeなどからも普通にアクセス可能。内容的には、PostgreSQL、Redis、Node.js、Ruby(Rails)、Nginxが動作し、ありがちな開発環境なので、これらが普通に動くならリアルなLinuxより手頃となるケースも多いだろう。

 ただLinux側のIPアドレスが、Bクラスのプライベートアドレスで、しかも起動するたびに変わるのがちょっと面倒なところ(ChromeOSのLinux環境もこの点はよく似ているが)。ここだけはHyper-VやVMwareでブリッジ接続のネットワーク環境(ホストマシンと同じセグメントに割当てられる)でLinuxを起動するのと大きく異なる部分となる。

 とは言え、WSL2で構築した環境をネットへそのまま出すことは考えにくく、この仕様でも事実上、特に問題はない(先のsshの設定でポートを80や443にすればほかのLAN上のマシンからもWebブラウザなどでアクセスできる)。

 最後に余談になるが、実はこの原稿を書く前にリアルなUbuntu 22.04.1 LTS ServerにMastodonを同じく非Dockerでインストールした。というのも、そもそもこれができないと、WSL2へインストールしてうまくいかなかったとき、インストール方法が悪いのか、WSL2の問題なのか分からないためだ。

 rootを/var/www/mastodonにしたり、PostgreSQLにパスワードを設定したり、上記より数行ほど余計なことをしているが、ほとんど同じ操作となっている。また、せっかく入れたので、ネットへも公開した。もし連合で見かけたらお手柔らかに……と言ったところ(笑)。


 以上、正式リリースとなったストア版WSL2 + Ubuntu 22.04.1 LTSを使い、Mastodonを非Dockerで起動してみた。systemd対応となったことで、そのまま動いてしまうのがうれしいところ。毎回変わるIPアドレスやファイルシステムが少し遅いのは気になるが、今後の改善に期待したい。