Mastodon 1.4.x (Docker) の assets:precompile が失敗するので Bash on Ubuntu on Windows 上で実行して切り抜けた件

Mastodon v1.4 系へのアップデート時に実行した assets:precompile が失敗するため、Docker for Windows と Bash on Ubuntu on Windows で Mastodon のビルド環境を作ってそこで実行してアップデート作業を進めた際の手順をまとめます。

自分専用の Mastodon (マストドン) インスタンス (所謂 「お一人様インスタンス」 ですね) を立てましたという記事と、それに関連する記事を以前書いています (下記参照)。

で、これらの記事を書いているときに稼働していた Mastodon は v1.3.x だったんですけども、その後、v1.4 系がリリースされまして、バージョンアップをしたのですが、その課程で docker-compose run --rm web rails assets:precompile すると、プロセスの途中でコケるという症状にハマってうまくいきませんでした。

v1.3.3 → v1.4.1 へのアップデート時にハマった問題

アップデート時に出ている症状としては下記のリンク先で Issue として挙がっている内容と同じ。

当時、リアルタイムでこの Issue を追っかけていた時は、「サーバのメモリが足りないんじゃないの?」 的な一応の結論が出てきたので、「俺の環境、実メモリ 2GB 積んでんだけどそれでも足りないの?」 などとは思いながらもサーバ側 (以前の記事で書いたとおり、サーバは 「さくらの VPS」 プランは 「2G」 を使ってます) で Swap 領域を足してみたりして色々やったのですが、症状は変わらず。

自分の中ではサーバ環境との相性とか、そういうもので、メモリは関係ないなと結論づけたのですが、他に解決策もないので、とりあえず手持ちの MacBook (普段はあまり使わない) を引っ張り出して、そこで docker-compose run --rm web rails assets:precompile だけ回して生成されたファイルを救出、サーバに移動してという手順で、当時最新だった v1.4.1 まで上げてひと段落しました。

v1.4.1 → v1.4.3 へのアップデートで BoW を使ってみる

それでしばらくは特に何もなかったのですが、つい先日、v1.4.2 がリリース (直後にホットフィックスが出て v1.4.3 が最新に) されましたのでアップデートしようかなと思ったときに、そういえばまた assets:precompile でコケるのかなぁと思ってダメ元でアップデート作業を進めてみたところ、案の定、同じところでコケますと。

面倒だけどまた MacBook の出番かなと思っていたら、そういえば 4月の 「Windows 10 Creators Update」 で、「Bash on Ubuntu on Windows (以下、「BoW」)」 が使えるようになってるじゃんと気がつき (私、メインの作業環境は Windows ですので)、早速調べてみたら Docker も動かせそう (正確には Docker for Windows を BoW から使えるという感じですが)。

ということで、BoW で Docker を使えるようにして、assets:precompile を実行し、ファイルを救出するついでに、これらファイルを Mastodon が稼働しているサーバではなく、Amazon S3 の方に上げて運用するところまでをやったので、その手順についてまとめてみたいと思います。多分すごく狭い範囲の方々にしか役に立たないと思いますが備忘録として。

前提となる必要環境

まず、BoW で Docker を利用するために下記の環境が必要です。

  • 64bit 版 Windows 10 Pro (BoW 自体は Pro 以外でも使えますが、Docker for Windows に Hyper-V が必要なため)
  • Windows で 「開発者モード」 が有効になっている

Windows 10 Home だと Hyper-V が使えないため Pro へのアップグレードが必要ですからそこだけ注意してください。私の環境は元々 Pro だったのでそのままで問題なかったですが。

なお、BoW を利用可能にするところまでは、下記の記事がとても詳しく解説してくれていますので参考まで。

Bash on Ubuntu on Windows のインストール」 セクションから読めば、手順がわかると思います。BoW が立ち上がるところまで進めておいてください。

Docker for Windows のインストール

BoW の準備が整ったら、まずは、Docker for Windows をインストールします。基本的には下記の手順に従えば問題なし。

私の場合は、安定版を使ったので、「Get Docker for Windows (Stable)」 からインストーラーを取得し、あとはインストールウィザードに従って進めていくだけです。

インストール完了後、設定画面にて、Expose daemon on tcp://localhost:2375 without TLS にチェックを入れておきます (下記画像参照)。セキュリティ上は問題なのですが、今回はこれで何か運用するわけではないので TLS 関連の作業を省くためです。

Docker for Windows の設定で Expose daemon on tcp://localhost:2375 without TLS にチェックを入れます

Bash on Ubuntu on Windows で Docker などのセットアップ

続いて BoW 側で Docker のセットアップと、Mastodon のビルドを行っていきます。Ubuntu でのインストールについては、公式ドキュメントが下記にありますので手順を参考にします。

まず、BoW を立ち上げ、必要なパッケージのインストールを行います。

$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common

続けて、Docker 公式の GPG key を追加します。

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88

続いて、安定版のリポジトリを追加。

$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Docker をインストールします。

$ sudo apt-get install docker-ce

続いて、docker-compose をインストールしますが、pip によるインストールを行うため、先にインストールしてから、pip install docker-compose して docker-compose を入れます。

$ sudo apt-get install python-pip
$ sudo pip install docker-compose

docker コマンドを sudo なしで実行するため、下記のように現在のユーザーを docker グループに追加します。

$ sudo groupadd docker
$ sudo usermod -aG docker $USER

BoW 上の Docker から、Docker for Windows の Docker デーモンに接続するため、下記のように環境変数にパスを追加しておきます。

$ echo export DOCKER_HOST='tcp://localhost:2375' >> ~/.bashrc
$ source ~/.bashrc

Mastodon をビルド

Docker 関連の設定が終わったので、次に Mastodon を取得してビルドします。まずは git をインストール。

$ sudo apt install -y git

次に Mastodon を落としてきます。タグ 「v1.4.3」 にチェックアウトして、設定ファイル 「.env.production」 を有効にします。

$ git clone https://github.com/tootsuite/mastodon.git
$ cd mastodon
$ git checkout v1.4.3
$ cp .env.production.sample .env.production

ここからは通常の Mastodon インストール手順ですので、詳しくは 「さくらの VPS + CentOS7 で 俺専用 Mastodon インスタンスを立ててみた話」 を参考にしていただければよいのですが、まず下記のコマンドを 3回実行して、それぞれ発行された Key をメモ。

$ docker-compose run --rm web rake secret

.env.production ファイルの下記の項目に設定するほか、他の項目も実際に稼働している環境にあわせて設定しておきます (メール関連の設定などは使用しないので適当でよい)。

PAPERCLIP_SECRET=
SECRET_KEY_BASE=
OTP_SECRET=

DB 関連の設定も今回の用途であれば恐らく不要なんですが、一応やっておきました。ただ、データの永続化などは特に設定せず進めます。

そしたら、Mastodon の実稼働環境では問題が出ていた、assets:precompile を実行します。

$ docker-compose build
$ docker-compose run --rm web rails assets:precompile
$ docker stop $(docker ps -a -q) && docker-compose up -d

docker-compose run --rm web rails assets:precompile が問題なく完了すれば、目的はほぼ達したも同然になります。生成されたファイル一式を救出しましょう。

$ docker cp mastodon_web_1:/mastodon/public ~/mastodon_backup/public
$ cd ~/mastodon_backup
$ tar -zcvf public.tar.gz public

まず、Web コンテナから public ディレクトリ以下を取得し、/mastodon_backup/public 以下にコピーし、圧縮しておきましょう。

BoW は、Windows の各ドライブを、/mnt にマウントします。つまり、例えば D ドライブは BoW からは、/mnt/d/ からアクセスできるということになります。ということで、Windows から直接扱える場所に先ほどの圧縮ファイルを移動すれば、救出成功ということになります。

$ mv public.tar.gz /mnt/d/temp

ファイルを解凍して、「packs」 というフォルダを探しましょう。このフォルダ内の各ファイルが今回必要なファイル一式になります。

アセットファイルを Amazon S3 から読み込む

基本的には取得した 「packs」 フォルダ内のデータを、実稼働サーバの Mastodon インストールディレクトリ下にある、「public/packs」 にコピーして、あとは Mastodon のアップデート作業に入ればよいのですが、今回は、この各ファイルを Amazon S3 にアップロードして、そちらから読み込むようにしてみます。

Amazon S3 のセットアップは完了している前提で進めますが、詳しくは下記を参考にしてください。

まず、「packs」 フォルダ内のファイルを検索して、内容に /packs/ というパスを含むファイルを抽出します。CSS ファイルと、JavaScript ファイルがいくつか引っかかると思います。

各ファイルを開き、/packs/~ となっている部分を、https://[リージョン].amazonaws.com/[バケット名]/packs/~ に変換します。

次に、manifest.json をテキストエディタなどで開き、書かれているパス、例えば下記のような記述を

"Montserrat-Regular.ttf": "/packs/Montserrat-Regular-********.ttf"

下記のように書き換えます。

"Montserrat-Regular.ttf": "https://[リージョン].amazonaws.com/[バケット名]/packs/Montserrat-Regular-********.ttf"

これで必要なファイルの編集は完了。最後に 「.gz」 拡張子のファイルは必要ないので削除してしまいましょう。

Amazon S3 へのアップロードと Mastodon のアップデート

仕上げです。Amazon S3 のバケット直下に、先ほど編集したファイルを含む 「packs」 フィルダをそのままアップロードします。次に、manifest.json を、実稼働環境の Mastodon インストールディレクトリ直下にある 「public/packs」 内にコピーしておきます。

Amazon S3 へのアップロードと、manifest.json の設置が完了したら、いよいよ実稼働環境の Mastodon をアップデートしましょう。

アップデート手順について詳しくは各リリースを見ていただくのが確実ですが、v1.4.3 であれば下記のような手順になります (Mastodon が /opt/mastodon にインストールされている前提)。

# cd /opt/mastodon
# git fetch
# git checkout v1.4.3
# docker-compose build
# docker-compose run --rm web rails mastodon:maintenance:prepare_for_foreign_keys
# docker-compose run --rm web rails db:migrate
# docker-compose run --rm web rails r Rails.cache.clear
$ docker stop $(docker ps -a -q) && docker-compose up -d
# systemctl restart nginx

本来なら、db:migrate などとあわせて、assets:precompile も実行しますが、すでにファイルは用意できているので省略します。

Docker コンテナが正しく起動できたのを確認したら、実際の Web サイトにアクセスしてみましょう (コンテナ立ち上げ直後は 502 Bad Gateway が帰ってくる場合が多いので焦らずちょっと時間をおいてみるといいかも)。

問題なく、Mastodon にログインできて、サーバ情報で正しいバージョンが表示されていれば問題なしです。