Cloud9の無料アカウントでMastodonを起動させる


Mastodon

Mastodonは、オープンソースの分散型SNSで、技術的にはRailsアプリケーションの一つです。フロンドエンドにはReact + Reduxが使われていたりします。

Cloud9

Cloud9は、クラウド型のIDEで、ブラウザ上で動作するのが特徴です。(その気になればスマートフォンからでも扱えます。)
Cloud9のアカウントプランには無料のものがありますので、もちろん制約はありますが無料で様々な開発に使うことができます。

このCloud9ですが、WorkSpaceがほぼ完全なLinux(Debian)になっており、node.jsやApache HTTP serverなど多くのパッケージが最初から入っているため、このIDEで作業しながらデバッグ環境を動かすことができます。
今回は、これを利用してMastodonを稼働させられないかという試みの結果、意外といけると判明したので手順を記しておきます。

Cloud9無料アカウントのWorkSpaceはMemoryが512MB、Storageが2GBまでというMastodonにとっては非常に厳しい環境であるため、動いてもせいぜい開発用か、おひとり様インスタンスにしかならないかと思いますが、それでもという方は以下の手順で建てられます。所要時間は1時間半くらいは見ておいたほうがいいと思います。

手順

Cloud9アカウントの作成

これはCloud9のサイトから指示に従えば特に問題ないとは思いますが、クレジットカード情報が必要です。もちろん有料アカウントにしない限りは一切課金されません。

WorkSpaceの作成

アカウントを取得してマイページへ行くとこんな感じになっています。
私のアカウントのものですので既にWorkSpaceができていますが、最初は赤矢印で示したCreateボタンしかないはずです。

Createボタンをクリックすると、以下のようなページに飛ぶので、とりあえずWorkSpace nameに何か入力して、Privateを選択、choose a templateはblankを選択してCreateします。

するとしばらく待たされた後にお待ちかねのIDE画面が現れます。

下側にターミナル、上側にエディタ、左にディレクトリツリーというレイアウトになっています。右上にMEMORY, CPU, DISKと書かれたバーがありますが、まだ3つともほとんど使われていませんね。ここから下部のターミナルを使用して必要なものをたくさん入れていきます。

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

まず、Cloud9環境はセキュリティ関係の問題の影響(?)でDockerが動かせないので、Non-Dockerで動かします。
必要なパッケージ類の一覧はオフィシャルのProductionガイドを参考にしました。

注意

この先、aptを何度か使います。apt updateは頻繁に行いますが、apt upgrade絶対に行わないでください。最初から入っているパッケージ類をupgradeすると、それが最初から入っているものとして扱われなくなるのか、DISKの使用量が一気にかさんでしまいます。

node.js

すでに入ってるのでパス。$ node -vで確認できます。

yarn

Productionガイドではaptで入れることになっていますが、Cloud9環境ではなぜかこいつがインストールできないので、npmから入れます。

npm --global install yarn

rootへ切り替え

Cloud9では、rootへの切り替え権限も与えてくれるので、これからしばらくrootで作業します。

sudo su -

apt update

apt updateをしたいのですが、デフォルトのままではapt installの時にエラーが起こるので、それを回避します。
まず、原因となるudevを書き換えます。

nano /etc/init.d/udev

udevを開いたら、### END INIT INFOとある行の次の行に、exit 0と書き込んで保存します。
その後、以下を実行します。

dpkg --configure -a
apt update

そうしたら、先ほどの手順でもう一度udevを開き、先ほど書き込んだexit 0を削除して保存します。

諸々のパッケージ

必要なパッケージが多いので、以下を実行して一気に入れましょう

apt -y install imagemagick libpq-dev libxml2-dev libxslt1-dev file git-core g++ libprotobuf-dev protobuf-compiler pkg-config gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev redis-server redis-tools postgresql postgresql-contrib libidn11-dev libicu-dev

ffmpeg

これが非常にくせ者でした。Debianは「フリーライセンスのものしか提供しない」という方針で、MP3エンコーダなどを含むffmpegは提供していません。deb-multimediaというリポジトリを使用するといいという情報も見つけたのですが、色々試してもどうもapt経由だとunmet dependenciesが発生しインストールできません。なのでdeb-multimediaから必要なライブラリをインストールしたあと、仕方なくソースコードからビルドします。非常に時間がかかります。

先に下にある追記をお読みください

ソースからビルドする場合
echo 'deb http://www.deb-multimedia.org jessie main non-free' >> /etc/apt/sources.list
apt update
apt -y install deb-multimedia-keyring
apt update
apt -y install build-essential libmp3lame-dev libvorbis-dev libtheora-dev libspeex-dev yasm pkg-config libfaac-dev libopenjpeg-dev libx264-dev
mkdir software
cd software
wget http://ffmpeg.org/releases/ffmpeg-3.4.tar.bz2
cd ..
mkdir src
cd src
tar xvjf ../software/ffmpeg-3.4.tar.bz2
cd ffmpeg-3.4
./configure --disable-doc --disable-manpages --disable-ffplay --disable-ffprobe --disable-ffserver --enable-gpl --enable-postproc --enable-swscale --enable-avfilter --enable-libmp3lame --enable-libvorbis --enable-libtheora --enable-libx264 --enable-libspeex --enable-shared --enable-pthreads --enable-libopenjpeg --enable-nonfree
make
make install
/sbin/ldconfig

ビルドが終わったら、ソースコード類はディスク容量を食うだけなので削除します。また、rootから出ます

cd
rm -r src/* software/*
rmdir src software
logout

17/11/20 23:00 追記
Static-build版を持ってきて入れるという手がありました。動作確認はしていませんが、ソースからビルドすると平気で30分とか持っていかれるので、こっちのほうがいいのではないかと思います。下記のコマンドでffmpegを入れる場合は上記ソースからビルドするコマンドは一切不要です。インストールしたらrootから出ます。

static-build版を入れる場合
mkdir software
cd software
wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz
tar Jxfv ffmpeg-release-64bit-static.tar.xz
cp ffmpeg-3.4-64bit-static/ffmpeg /usr/bin/
cd
rm -r software/*
rmdir software
logout

PostgreSQLの設定

PostgreSQLは元から入っているのですが、設定を変更する必要があるのでやっておきます。まずはDBユーザの作成です

sudo su - postgres -c 'psql -c "CREATE USER mastodon CREATEDB;"'

次に、pg_hba.confを編集します。

sudo nano /etc/postgresql/9.3/main/pg_hba.conf

ファイル中、# "local" is for Unix domain socket connections onlyの下行local all all peerとなっているところを、

local all all trust

と変更します。変更したらサービスを再起動します。ついでにredisも再起動。

sudo service postgresql restart
sudo service redis-server restart

必要なnode.jsとRubyのパッケージを取得

いよいよMastodonのソースコードをとってきます。次にCloud9に元から入っているrvmを使ってRuby-2.4.2を入れます。

cd ~
git clone https://github.com/tootsuite/mastodon.git live
cd ~/live
git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)
rvm install ruby-2.4.2

bundlerとyarnを使って必要なパッケージを入れます。bundle installの引数は本番環境の場合のものです。development環境やtest環境で建てる場合は適宜変えてください。今後も本番環境として作業を進めます。

gem install bundler
bundle install --deployment --without development test
sudo yarn install --pure-lockfile

この辺でDISK容量がかなりやばいはずなので、yarnのキャッシュをクリアします

yarn cache clean

Mastodonアプリケーションの設定

アプリケーション設定を行います。

cd ~/live
cp .env.production.sample .env.production
nano .env.production

編集する項目は以下の通りです。

REDIS_HOST=localhost

DB_HOST=/var/run/postgresql
DB_USER=mastodon
DB_NAME=mastodon_production

LOCAL_DOMAIN=[注1]
LOCAL_HTTPS=true

PAPERCLIP_SECRET=[注2]
SECRET_KEY_BASE=[注2]
OTP_SECRET=[注2]

VAPID_PRIVATE_KEY=[注3]
VAPID_PUBLIC_KEY=[注3]

[注1]に入力するドメイン名は画像赤丸Shareをクリックし、Application:に書かれているURLからhttps://を取り除いたものになります。また、その右横にあるPublicのチェックボックスにチェックを入れて、外からアクセスできるようにしておきましょう。(Publicにするのは今でなくても大丈夫です。)

[注2]に入力するのは、ターミナルでRAILS_ENV=production bundle exec rake secretを実行して出力された文字列です。なので、これを計3回実行し、得られた3つの文字列をそれぞれの行に貼り付けてください。

[注3]に入力するのは、ターミナルでRAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_keyを実行して得られたVAPID_PRIVATE_KEYVAPID_PUBLIC_KEYです。1回実行すると2つの文字列が出力されるので、PRIVATEとPUBLICを間違えずに貼り付けてください。

データベースのセットアップ

まず、config/database.ymlを編集します。1行、template: template0を追加します

config/database.yml
default: &default
  adapter: postgresql
  pool: <%= ENV["DB_POOL"] || ENV['MAX_THREADS'] || 5 %>
  timeout: 5000
  encoding: unicode
  template: template0
以下略

その後、以下を実行しデータベースをセットアップします

RAILS_ENV=production SAFETY_ASSURED=1 bundle exec rails db:setup

CSSとJavaScriptファイルのプリコンパイル

RAILS_ENV=production bundle exec rails assets:precompile

しばらく時間がかかります。

Apache HTTP Serverの設定

ProductionガイドではNginxを使っていますが、Cloud9ではApacheが最初から入っているのでそれを使います。

sudo nano /etc/apache2/sites-enabled/001-cloud9.conf

内容は以下の通りです。おそらくこのまま使えます。

<VirtualHost *:8080>
    DocumentRoot /home/ubuntu/live/public
    ServerName https://${C9_HOSTNAME}:443

    LogLevel info

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    <Directory /home/ubuntu/live/public>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    ProxyPreserveHost On
    RequestHeader set X-Forwarded-Proto "https"
    ProxyPass /500.html !
    ProxyPass /sw.js !
    ProxyPass /robots.txt !
    ProxyPass /manifest.json !
    ProxyPass /browserconfig.xml !
    ProxyPass /mask-icon.svg !
    ProxyPassMatch ^(/.*\.(png|ico)$) !
    ProxyPassMatch ^/(assets|avatars|emoji|headers|packs|sounds|system|.well-known/acme-challenge) !

    ProxyPass /api/v1/streaming/ ws://localhost:4000/
    ProxyPassReverse /api/v1/streaming/ ws://localhost:4000/
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/

    ErrorDocument 500 /500.html
    ErrorDocument 501 /500.html
    ErrorDocument 502 /500.html
    ErrorDocument 503 /500.html
    ErrorDocument 504 /500.html
</VirtualHost>

ServerName https://${C9_HOSTNAME}
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

また、プロキシとして使うためのいくつかのモジュールを追加します。

sudo a2enmod proxy proxy_http proxy_html proxy_wstunnel headers xml2enc
sudo service apache2 restart

サービス起動

いよいよMastodonを起動させます。いくつかのプロセスが同時に動くので、ターミナルのタブの右にある「+」ボタンから、New Terminalを選んで新しいターミナルを3つ開きます。

new_terminal_1
cd ~/live
RAILS_ENV=production PORT=3000 bundle exec puma -C config/puma.rb
new_terminal_2
cd ~/live
RAILS_ENV=production DB_POOL=5 bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push
new_terminal_3
cd ~/live
NODE_ENV=production PORT=4000 npm run start

HTTPサーバ起動

そして最後にHTTPサーバを起動させてアクセスできるようにします。メニューバーのRun -> Run WithからApache httpdを選択すると、ターミナルが並んでいるところに新しくタブが追加されて、Apache HTTP Serverが起動します。

そしたら、右上のShareボタンをクリックし、Application:欄のリンクからサイトへ飛んでみましょう。

うまくいきましたか?

なお、メールサーバの設定を一切していないので、アカウント登録はターミナルに戻って手作業で行うことになります。

アカウント登録

ターミナルに戻って、以下を実行します。最後の1行は、ユーザを管理者に昇格させるためのコマンドです。
<ユーザID>・<メールアドレス>・<パスワード>はお好きなように書き換えてください。

RAILS_ENV=production bundle exec rails c
acc = Account.create!(username: '<ユーザID>')
usr = User.create!(email: '<メールアドレス>', password: '<パスワード>', account: acc)
usr.confirm
acc.save!
usr.save!
exit
RAILS_ENV=production bundle exec rails mastodon:make_admin USERNAME=<ユーザーID>

これで、<メールアドレス>・<パスワード>を使ってログインできるようになります。

まとめ

以上が、Cloud9上でMastodonを建てる雑な方法です。私が建てた結果では、トゥートはもちろん、リモートフォローや画像の投稿なども問題なくできています。しかし、メモリ使用量は常にギリギリなので、複数ユーザでの運用は厳しいのではないかと思います。

また、コマンドの間違いや「もっといい方法あるよ」(特にffmpeg周り)というのがありましたら是非コメントお願いします。