最近、マストドンが各所で立っていますね。
tootsuite/mastodon
たていすのメモ - Mastodonを設置したときのメモ
PixivInside - 実際に運用してみてわかった、大規模Mastodonインスタンスを運用するコツ
Qiita - Dockerを利用しないでマストドン(Mastodon)をCentOSにインストールする
これらの記事を読んでるとなんだか羨ましくなったので、手探りで自分のAWS上にも立ててみました。
この記事ではその作業の顛末をご紹介します。
【注意!】下記は、絶対にベストプラクティスではありません。コピペは自己責任でお願いします。
要件
- とりあえず動くマストドンがどんなものか見たい
- 外部からのアクセス制限をかけたい
- ユーザー数は最大20人程度
構成
シンプルですね。
手順
ドメイン取得
今回はサブドメインを使用したため新規には取得しませんでしたが、実運用の際には必要になるかと思います。
(japari.com は当然ながらすでに取られたあとでした)
EC2 インスタンス
とりあえず動けばいいので適当に t2.micro で AWS Linux を起動しましたが、Pawoo 規模になると他インスタンス(記事によるとc4)への変更が必須みたいですね。
また、セキュリティグループなどの設定は各々の環境によると思いますので省略します。
ec2-user でログインし、sudo できるユーザーを追加するなどします。
ここでは miko
ユーザーとします。
ありふれた手順ですが、わわわと書いておきます。
sudo useradd miko
sudo passwd miko
# wheel に miko を追加
sudo vi /etc/group
# wheel を sudoers に追加(コメントを外す)
sudo vi /etc/sudoers
# ssh ログイン設定
sudo mkdir /home/miko/.ssh
sudo vi /home/miko/.ssh/authorized_keys
sudo chmod 700 /home/miko/.ssh
sudo chmod 600 /home/miko/.ssh/authorized_keys
# miko ユーザーでログインする
Route53
こちらも普通に設定します。
先程起動したインスタンスのパブリックIPを、自家用マストドンのサブドメインに紐付けましょう。
マストドンをひっぱってくる
git
sudo yum install -y git
git clone
cd /home/miko/
git clone https://github.com/tootsuite/mastodon.git
マストドンに必要なものをインストール
ffmpeg
sudo yum install http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
sudo yum install -y ffmpeg
ImageMagick
sudo yum install -y ImageMagick
ruby
install libs
sudo yum install -y gcc gcc-c++ make
sudo yum install -y openssl-devel readline-devel zlib-devel
# こちらはEC2からRDS上のpostgresにログインするために使います
sudo yum install -y libpq-fe libpq postgresql-devel
rbenv
rbenv
とくにrubyを使い分ける必要がなければ、rbenv をインストールする必要はないです。
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
. ~/.bash_profile
install 2.4.1
cd /home/miko/mastodon
rbenv install 2.4.1
rbenv versions # エイリアス確認
bundle
gem install bundle
RAILS_ENV=production bundle install
node
install nvm
git clone https://github.com/creationix/nvm.git ~/.nvm
nvm install 6.10.2
npm install
npm install .
ElastiCache Redis
マストドンはメール送信のキューイングに sidekiq を使っているので、Redis を用意する必要があります。
AWS の ElastiCache でとくにハマりどころもなく立てました。
Status が available になったら Primary Endpoint が表示されるので、そちらを控えておきましょう(マストドンの設定に使用します)。
RDS PostgreSQL
AWS RDS 上に PostgreSQL のインスタンスを立てます。
起動したら、エンドポイントを控えておきましょう。
DB の用意
psql -h #{エンドポイント} -p 5432 -U #{作成時に設定したスーパーユーザー名}
create database mastodon; # 変更可能です
CREATE USER #{マストドンに使用させるユーザー名} ENCRYPTED PASSWORD '#{パスワード}';
GRANT ALL ON DATABASE mastodon TO #{マストドンに使用させるユーザー名};
SES
実際のメール送信に使用するSMTPサーバに、AWS SESを利用することにしました。
設定手順はこちらが詳しいです。
http://dev.classmethod.jp/cloud/aws/amazon-ses-build-and-practice/
加えて、AWS SES 管理画面左端メニューから「SMTP Settings」を選び、「create my STMP credentials」ボタンを押して、AMIロールを追加、対応するログインIDとパスワードを発行してもらってください。
.env.production に設定を追加する
.env.production の雛形をコピー
cd /home/miko/mastodon
cp .env.production.sample .env.production
rake secret
PAPERCLIP_SECRET
SECRET_KEY_BASE
OTP_SECRET
に使用するランダムな文字列を発行する。
# 3回実行し、それぞれ控えておく。
rake secret
rake secret
rake secret
.env.production を書き換える
vi ./.env.production
# Service dependencies
REDIS_HOST=#{hoge}.cache.amazonaws.com # ElastiCache で立てた Redis の Endpoint
REDIS_PORT=6379
# REDIS_DB=0
DB_HOST=#{hoge}.rds.amazonaws.com # RDS に立てた PostgreSQL の Endpoint
DB_USER=miko # mastodon に使用させる PostgreSQL のユーザー
DB_NAME=mastodon # mastodon に使用させる PostgreSQL のデータベース
DB_PASS=#{hoge} # DB_USER のパスワード
DB_PORT=5432
# Federation
LOCAL_DOMAIN=hogehoge.com # mastodon へのアクセスに使用するドメインとパス
LOCAL_HTTPS=true
# Use this only if you need to run mastodon on a different domain than the one used for federation.
# Do not use this unless you know exactly what you are doing.
# WEB_DOMAIN=mastodon.example.com
# Application secrets
# Generate each with the `rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose)
PAPERCLIP_SECRET=#{hoge} # さきほど発行した secret
SECRET_KEY_BASE=#{hoge} # さきほど発行した secret
OTP_SECRET=#{hoge} # さきほど発行した secret
# Registrations
# Single user mode will disable registrations and redirect frontpage to the first profile
# SINGLE_USER_MODE=true
# Prevent registrations with following e-mail domains
# EMAIL_DOMAIN_BLACKLIST=example1.com|example2.de|etc
# Only allow registrations with the following e-mail domains
# EMAIL_DOMAIN_WHITELIST=example1.com|example2.de|etc
# Optionally change default language
# DEFAULT_LOCALE=de
# E-mail configuration
# Note: Mailgun and SparkPost (https://sparkpo.st/smtp) each have good free tiers
SMTP_SERVER=email-smtp.#{hoge}.amazonaws.com # SES の SMTP サーバホスト
SMTP_PORT=587
SMTP_LOGIN=#{hoge} # SES で発行した credential のログインID
SMTP_PASSWORD=#{hoge} # SES で発行した credential のパスワード
SMTP_FROM_ADDRESS=hoge@hoge.com # 送信元メールアドレス
#SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail
#SMTP_AUTH_METHOD=plain
...
...
(以下略)
migration
RAILS_ENV=production bundle exec rails db:migrate
# 確認
psql -h #{エンドポイント} -p 5432 -d #{データベース名} -U #{ユーザー名} -W
\dn # スキーマ一覧が表示される
assets precompile
RAILS_ENV=production bundle exec rails assets:precompile
unicorn
systemd でなく unicorn を使用しています。
単に慣れているからそうしたというだけで、systemd を採用する場合は Pawoo の事例などをご参考ください。
nginx+unicorn+rails の設定は以下が詳しいです。
Qiita - 【CentOS 7】Nginx + Unicorn で Rails アプリケーションを本番環境で立ち上げる方法
install unicorn
cd /home/miko/mastodon
vi ./Gemfile
最下行の group :production do 〜 end
の中に gem 'unicorn'
を追加。
RAILS_ENV=production bundle install
設定ファイル、起動スクリプトの用意など
上記記事を参照のこと。
nginx
install nginx
sudo yum install nginx
sudo chmod a+rw /var/log/nginx
update nginx.conf
(前略)
#root /usr/share/nginx/html;
root /var/www/html; # お好みでどうぞ
(中略)
# コメントアウトする
#location / {
# auth_basic "Restricted";
# auth_basic_user_file /var/www/html/.htpasswd;
#}
(後略)
add mastodon.conf
こちらを参考にさせていただきました。
Qiita - Dockerを利用しないでマストドン(Mastodon)をCentOSにインストールする
upstream rails-unicorn {
server unix:/tmp/unicorn.sock;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name #{hoge}; # ホスト名
keepalive_timeout 70;
sendfile on;
client_max_body_size 0;
root /var/www/html/mastodon; # お好みでどうぞ
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
add_header Strict-Transport-Security "max-age=31536000";
location / {
# アクセスを特定IPに制限したかったので入れています。
set_real_ip_from 172.16.0.0/12;
real_ip_header X-Forwarded-For;
allow XXX.XXX.XXX.XXX;
deny all;
# 制限しない場合はここだけでよい。
try_files $uri @proxy;
}
location @proxy {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Proxy "";
proxy_pass_header Server;
proxy_pass http://rails-unicorn;
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
tcp_nodelay on;
}
location /api/v1/streaming {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Proxy "";
proxy_pass http://localhost:4000;
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
tcp_nodelay on;
}
error_page 500 501 502 503 504 /500.html;
}
run nginx
nginx
#確認
ps aux | grep nginx
# 再起動は nginx -s reload
Application Load Balancer
EC2 のロードバランサーメニューから、アプリケーションロードバランサーを追加します。
SSL の設定など詳細は省略しますが、今回の場合は ALB で SSL を処理させて、EC2 インスタンスには80番のアクセスだけが行くようにしています。
sidekiq
起動
nohup RAILS_ENV=production bundle exec sidekiq -q default -q mailers -q pull -q push > out.log 2> err.log < /dev/null &
# とりあえずなのであまりにも男らしい起動方法を取っていますが、本番で運用される場合はちゃんとしてあげてください(丸投げ)。
キューの確認
# redic-cli のインストール
sudo yum install -y redis --enablerepo=epel
# アクセス
redis-cli -h #{hoge}.cache.amazonaws.com -p 6379
起動
cd /home/miko/mastodon
./script/unicorn.sh start
# 確認
ps aux | grep mastodon
# 終了は ./script/unicorn.sh stop
これで、Route53 に指定したアドレスへアクセスすれば、以下の /about の画面が表示されるでしょう。
所感
S3 をマウントすればよかった
マストドンは、デフォルトで public/system/media_attachments/files/
配下にディレクトリを掘って、ユーザーのアップロードした共有ファイルを保存するようなのですが、 AWS でやるのであればそういったファイルたちは S3 に保存したいものです。
Pawoo は S3 に保存するようにしているようなので、こちらを参考にすればよかったなと思いました。
S3 を EC2 にマウントするには適切な IAM ロールの追加と、EC2 インスタンス作成時の設定が必要とのことで、インスタンス起動前に作業しておく必要がありそうです。
余談ですが、配置するのはユーザーの投稿ファイルなので、ファイル添付のある投稿数が増加すればするほど、S3 の使用容量が増加していきます。
ある程度アンコントローラブルになってしまうので、お財布に不安のある場合は S3 を使用せず、冒頭の記事にあるような Minio を使用する運用を検討してみてもいいかもしれません。
PostgreSQL に慣れていないので MySQL にしたい
自分はもっぱらの MySQL ユーザーで、久々に [psql コマンド] とかでググりました。
正直なところ、実運用するときにはよりテンパりにくく他の人にも知見のある MySQL での運用を行いたいなあ、と思ってしまいます。
unicorn じゃなく systemd のほうがいいのだろうか
たまたま慣れているので unicorn を使ってしまいましたが、systemd での運用のほうが楽だったりするんでしょうか。
こちらもやってみて、比較してみたいなと思います。