21
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

僕もマストドンを立てた系Qiita記事が書きたかった(AWS使用・Docker不使用)

Last updated at Posted at 2017-04-18

最近、マストドンが各所で立っていますね。
tootsuite/mastodon

たていすのメモ - Mastodonを設置したときのメモ
PixivInside - 実際に運用してみてわかった、大規模Mastodonインスタンスを運用するコツ
Qiita - Dockerを利用しないでマストドン(Mastodon)をCentOSにインストールする

これらの記事を読んでるとなんだか羨ましくなったので、手探りで自分のAWS上にも立ててみました。
この記事ではその作業の顛末をご紹介します。

【注意!】下記は、絶対にベストプラクティスではありません。コピペは自己責任でお願いします。

要件

  • とりあえず動くマストドンがどんなものか見たい
  • 外部からのアクセス制限をかけたい
  • ユーザー数は最大20人程度

構成

Untitled Diagram (3).png

シンプルですね。

手順

ドメイン取得

今回はサブドメインを使用したため新規には取得しませんでしたが、実運用の際には必要になるかと思います。
(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 #{作成時に設定したスーパーユーザー名}

Qiita - PostgreSql コマンドの覚え書き

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
shell/.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

/etc/nginx/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にインストールする

/etc/nginx/conf.d/mastodon.conf
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 の画面が表示されるでしょう。

スクリーンショット 2017-04-15 18.15.25.png

所感

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 での運用のほうが楽だったりするんでしょうか。
こちらもやってみて、比較してみたいなと思います。

21
24
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?