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から出ます。
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_KEY
とVAPID_PUBLIC_KEY
です。1回実行すると2つの文字列が出力されるので、PRIVATEとPUBLICを間違えずに貼り付けてください。
データベースのセットアップ
まず、config/database.ymlを編集します。1行、template: template0
を追加します
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つ開きます。
cd ~/live
RAILS_ENV=production PORT=3000 bundle exec puma -C config/puma.rb
cd ~/live
RAILS_ENV=production DB_POOL=5 bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push
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周り)というのがありましたら是非コメントお願いします。