マストドン(mastodon)のインスタンスをAWS(Amazon Web Service)に構築する手順をご紹介します。
もくじ
実は難易度の高い構築
本記事は執筆から2年以上経過しているので状況が変わっている可能性があります。
単純なWebアプリケーションなんだから、DB作ってサーバーにコードをアップロードして終わりでしょ、と思いがちなのですが、実は結構難しいです。
マストドンはRuby on RailsというメジャーなWebフレームワークで作られていますが、その他に周辺技術が多く使われています。
Redis、Docker、Reactなどの比較的新しい技術やメールなどの外部サーバーと連携するような機能も必要になってきます。
なので、マストドンインスタンスを構築するだけで、それなりの技術力が必要だと言えます。それに、公式サイトの説明はそこまで丁寧ではなく、手順を説明している記事もまだ多くありません。
ネット上には、結構「意外と簡単だったー。」「公式ドキュメントが親切ですぐできた。」などの声も上がっているのですが、信じてはいけません。
かなり技術力を持っている人がマウンティングしている可能性があります。
少なくとも、WordPressなどを構築するのに比べるとずっと難しいです。
でも、この手順をそのまんまやればエンジニアではない方でも数時間で構築できるようにはなっています。
なぜAWSを使うのか
AWSであれば、もしあなたのインスタンスが人気になりユーザーが急増し負荷が増大しても、スケールアウトして負荷に対処することが比較的容易です。
また、AWSはクラウドサービスでは一番メジャーなので、AWSの使い方を知っておけば、違うプロジェクトでも重宝される可能性が高いです。
そして、個人的にはAWSだとSSL証明書が無料になるというのも大きなメリットだと思います。
マストドンを構成する技術
マストドンを構築する上で、知っておくとわかりやすい技術について解説します。ただ、React.jsのようなフロントエンドまわりなどは、構築時に意識しなくてもいいので触れていません。図にするとざっくり次のような感じです。

技術名 | 役割 |
---|---|
Nginx | Webサーバー。 ユーザーからのアクセスを受付、レスポンスを返す。 |
Rails | アプリケーション。 メインの処理ロジックが動く。 |
Postgresql | リレーショナルデータベース。 データを保存しておく。 |
Redis | キャッシュ。 永続しないデータを扱う。非同期処理のために使われる。 |
SMTPサーバ | メールを送るために使う。 |
Docker | 一種のVMを作る技術。通常の完全仮想化より高速。それぞれの構成要素を分離して管理・デプロイするのが容易になる。 |
公式READMEの方法だと、Rails、Postgresql、RedisはそれぞれのDockerコンテナ上に載りますが、NginxはDockerコンテナに載せるようになっていません。なのでNginxは普通にインストールする必要があります。公式READMEではNginxを使う前提の説明が多いのでDockerコンテナに載せない理由がよくわかりません。WEBサーバーは環境により様々な状況が想定されるから、各人に任せているのかもしれません。
ちなみに、Nginxをインストールしなくても、Railsに内蔵されているPumaというWebサーバだけでも動きますが、大規模運用に備えてやはりNginxを使うことにします。
技術要素については、一度お手元のパソコンに開発環境を構築すると理解がしやすいと思います。次の記事に詳しく手順をまとめました。

このチュートリアルの構成
いきなり商用レベルの要件を構築するとわかりずらいし、挫折する方も出てしまうかもしれないので、このチュートリアルでは少しずつステップアップしていく構成にしています。
スポンサーリンク
お手軽な手順
まず、1つのVMで、 https://yourdomain.com/などの独自ドメインで、HTTPSで利用できるようにします。
SMTPサーバはAWSのメールサービス、SESに任せます。それ以外は1つのEC2内に入れます。EC2というのは汎用的なVMのことです。
SSL証明書はLet’s Encryptという無料のものを使用します。

普通に運用するだけならこれでOKだと考えていますが、大規模に運用していきたい人は次以降の手順を参考にしてください。
ロードバランサーの導入
お手軽な手順が済んだ状態から、ロードバランサー(ELB)を追加します。
後々のサーバー増設にそなえ、SSL証明書はEC2側ではなくELBにつけるようにします。AWSではELBにつけるSSL証明書を無料で発行してもらえます。
ちなみに、ユーザーはELBまでHTTPSでアクセスしますが、ELBはHTTPでEC2内のNginxに割りふります。

負荷に合わせてEC2をスケールアウトする
もしユーザーが増えてきた場合、EC2を増設する必要が出てきます。ELBを追加してあるので、EC2を追加するだけで負荷対策ができるのですが、データをそれぞれのEC2から一か所で共有できるようにする必要があります。
なので、PostgresとRedisは各EC2から切り出し、RDS、ElasticCacheというように、AWSの専用サービスを使うことにします。なので、DockerコンテナはRails用のものだけになります。

お手軽な手順
EC2インスタンスの作成
EC2のダッシュボードからEC2インスタンスを作成していきます。

ここでは、「Ubuntu Server 16.04 LTS (HVM), SSD Volume Type 」を選びます。

インスタンスのスペックを選びます。何でもよいのですが、リーズナブルなt2.nanoを選びます。

インスタンスの詳細設定は特に変えずに進みます。

ストレージのサイズは20GiBくらいにしておきます。

Tagは特に追加せずに進みます。
セキュリティグループの設定にて、HTTP、HTTPSを追加します。

「インスタンス作成の確認」で、「作成」を押すと、インスタンスにログインするためのキーペアを選びます。既存でもいいですし、新規に作ってもOKです。

「インスタンスの作成」を押すと、作成が開始されます。完了まで5分くらいかかりました。
完了したかどうかは、インスタンスの一覧画面にて、以下のように表示されているかどうかでわかります。

インスタンス一覧画面で、作成したインスタンスを選択すると、画面の下に情報が表示されます。そこで、「IPv4パブリックIP」の値を控えておいてください。

スポンサーリンク
Route53でHosted Zoneを作る
Route53のコンソールに移ります。
当方が運営しているのはマストドンインスタンスは https://everydon.com/というURLなので、あなたのドメインに置き換えて読んでください。
対象のドメインで確認メールを受け取るために、Route53でHosted Zoneを作ります。

対象のドメインを入力します。


先ほど控えたIPv4パブリックIPを入力します。

4つのNSの値を控えます。クリックすると右側にコピペできるフィールドで表示されます。

対象のドメインをAWSで使えるようにするため、ドメインを購入したレジストラ側の管理画面からネームサーバーの値として先ほど控えた値に設定します。
当方はムームードメインを使っていますが、ムームードメインの場合は、NSの値の最後のドットは削除して入力します。

SSHでログインする
ターミナルのアプリケーションを開きます。MacなどのUNIXコマンドが使えるOSを想定していますが、Windowsでもターミナル系のアプリケーションをインストールすれば同じようなことができるはずです。
ちなみに、以下コードにある行頭の $はプロンプトです。これより右にある文字列が実際に入力するコマンドです。
まずログインします。キーペアのファイルを下のように指定し、XX.XX.XX.XXには先ほど確認したIPv4パブリックIPを入れます。
このコマンドはキーペアのファイルがあるディレクトリで実行していますが、違うディレクトリの場合は、フルパスなり相対パスなりで指定する必要があります。
1 |
$ ssh -i mastodon-arks.pem.txt ubuntu@XX.XX.XX.XX |
1 |
Are you sure you want to continue connecting (yes/no)? |
と聞かれた場合は、’yes’と入力してください。
Let’s EncryptでSSL証明書を取得する
Let’s Encryptのクライアントのcertbotを使うとマジックのように簡単です。
certbotをダウンロードし、実行権限をつけます。
1 2 |
$ wget https://dl.eff.org/certbot-auto $ sudo chmod a+x certbot-auto |
certbotを実行します。
1 |
$ ./certbot-auto |
実行中に
1 |
Do you want to continue? [Y/n] |
と聞かれるので
Yと入力します。
1 2 |
Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): |
と聞かれるので、あなたのメールアドレスを入力します。
1 |
(A)gree/(C)ancel: |
と聞かれるので
Aと入力します。
1 |
(Y)es/(N)o: |
と聞かれますが、これは
Yでも
NでもOKです。ただ、
Yだとお知らせメールが来るようになるので、私は
Nにしています。
これで証明書がとあるディレクトリーに生成されます。
次にdhparamを生成します。
1 |
$ sudo openssl dhparam 2048 -out /etc/ssl/certs/dhparam.pem |
ミドルウェアの設定
t2.nanoだとメモリ容量がたりない可能性があるので、スワップの設定をします。
1 2 3 4 5 |
$ sudo fallocate -l 4G /swapfile $ sudo chmod 600 /swapfile $ sudo mkswap /swapfile $ sudo swapon /swapfile $ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab |
aptを最新にします。
1 2 |
$ sudo apt-get update $ sudo apt-get upgrade |
sudo apt-get upgrade実行時に下のようなメッセージが出る場合がありますが
Yと入力してください。
1 2 |
After this operation, 35.8 kB of additional disk space will be used. Do you want to continue? [Y/n] |
さらに
sudo apt-get upgrade実行時に複数回下のようなメッセージが出る場合があります。
1 2 3 4 5 6 7 8 9 10 11 |
A new version of /boot/grub/menu.lst is available, but the version installed currently has been locally modified. What would you like to do about menu.lst? install the package maintainer’s version keep the local version currently installed show the differences between the versions show a side-by-side difference between the versions show a 3-way difference between available versions do a 3-way merge between available versions (experimental) start a new shell to examine the situation |
その場合は、2つ目の「keep the local version currently installed」を選びます。
十字キーで選択して、Enterで決定します。
ミドルウェアをインストールします。
1 2 |
$ sudo apt-get install -y python3-pip unzip docker.io nginx $ sudo pip3 install docker-compose |
Nginxの設定ファイルを修正します。
1 |
$ sudo vim /etc/nginx/sites-enabled/default |
中身は以下とします。公式のドキュメントにあったサンプルを若干修正したものです。
ドメインを私のものにし、33行目の
rootをubuntuの環境に合わせただけです。この手順に従っているなら、
everydon.comをあなたのドメインに置換すればそのまま使えるはずです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; listen [::]:80; server_name everydon.com; # Useful for Let's Encrypt location /.well-known/acme-challenge/ { allow all; } location / { return 301 https://$host$request_uri; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name everydon.com; ssl_protocols TLSv1.2; ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_certificate /etc/letsencrypt/live/everydon.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/everydon.com/privkey.pem; ssl_dhparam /etc/ssl/certs/dhparam.pem; keepalive_timeout 70; sendfile on; client_max_body_size 0; root /home/ubuntu/live/public; 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"; add_header Content-Security-Policy "style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'self'; img-src data: https:; media-src data: https:; connect-src 'self' wss://everydon.com; upgrade-insecure-requests"; location / { try_files $uri @proxy; } location ~ ^/(assets|system/media_attachments/files|system/accounts/avatars) { add_header Cache-Control "public, max-age=31536000, immutable"; 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://127.0.0.1:3000; 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; } |
マストドンのセットアップ
githubからソースコードを持ってきます。
1 2 3 |
$ git clone https://github.com/tootsuite/mastodon.git live $ cd live $ git checkout $(git tag | tail -n 1) |
環境変数のファイルを作成します。
1 |
$ cp .env.production.sample .env.production |
docker-composeの設定ファイルを修正します。
1 |
$ vim docker-compose.yml |
dbとredisのセクションを修正します。以下でいうと、5〜6、12〜13行目のコメントアウトを外します。これをしないと、運用中にDBに入ったデータが
docker-compose downする度に消えてしまいます。これにより、Dockerコンテナ側のデータのあるディレクトリと、EC2側のディレクトリを同期することになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
db: restart: always image: postgres:alpine ## Uncomment to enable DB persistance volumes: - ./postgres:/var/lib/postgresql/data redis: restart: always image: redis:alpine ## Uncomment to enable REDIS persistance volumes: - ./redis:/data |
ちなみに、EC2にはEBSをつけているので、EC2を停止してもデータが消えることはありません。なので、EC2を停止して、EC2のスペックを変えることも可能です。ユーザーが増えてきたらスケールアップしてもいいかもしれません。ただ、一つのEC2で運営している場合は、ダウンタイムが発生するので、ユーザーが使っていない深夜などにやったほうがいいかもしれません。
あと、EC2を停止する前に、一応 sudo docker-compose downでDockerを停止しましょう。
docker-compose buildします。これは5〜10分かかります。
1 |
$ sudo docker-compose build |
次に、後で環境変数ファイルに記入する鍵(長い文字列)を3つ生成します。以下を3回実行します。
1 |
$ sudo docker-compose run --rm web rake secret |
以下のような長い文字列の鍵が表示されます。3回分メモしておいてください。
1 |
4b804c1e71d14951a50cbc52f3b8a7ef9d1bf993e2774227cdf637102022f4a5af188aa4fa4c236b31e4ed6970469d1527e06097b678edfb0ed9e6d85c18d805 |
ただ、初回だけ以下のように長い出力となる場合がありますが、必要なのは最後の行のみです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
$ sudo docker-compose run --rm web rake secret Creating network "mastodon_default" with the default driver Pulling db (postgres:alpine)... alpine: Pulling from library/postgres 627beaf3eaaf: Pull complete 2d555ba539f4: Pull complete f829d456f997: Pull complete 0ed44e989a3a: Pull complete 64960f1d9c23: Pull complete 299245faa0f0: Pull complete a0b381a833e6: Pull complete bacfe251908e: Pull complete Digest: sha256:b2eb0b1194dfc7a42d496fc2c333ffad8c38e552a0d5411450c7b307a7c9774b Status: Downloaded newer image for postgres:alpine Pulling redis (redis:alpine)... alpine: Pulling from library/redis 627beaf3eaaf: Already exists a503a4771a4a: Pull complete 72c5d910c683: Pull complete 6aadd3a49c30: Pull complete adf925aa1ad1: Pull complete 0565da0f872e: Pull complete Digest: sha256:9cd405cd1ec1410eaab064a1383d0d8854d1eef74a54e1e4a92fb4ec7bdc3ee7 Status: Downloaded newer image for redis:alpine Creating mastodon_db_1 Creating mastodon_redis_1 4b804c1e71d14951a50cbc52f3b8a7ef9d1bf993e2774227cdf637102022f4a5af188aa4fa4c236b31e4ed6970469d1527e06097b678edfb0ed9e6d85c18d805 |
環境変数ファイルを修正します。
1 |
$ vim .env.production |
修正する部分は3点です。
1点目は、Federationの部分で、
LOCAL_DOMAINをあなたのドメインにします。
1 2 |
# Federation LOCAL_DOMAIN=everydon.com |
2点目は、先ほど生成した3つの鍵を
.env.productionに記入します。
以下の3つの
=以降にそれぞれ記入します。
1 2 3 4 5 |
# Application secrets # Generate each with the `rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose) PAPERCLIP_SECRET= SECRET_KEY_BASE= OTP_SECRET= |
3点目は、お好みで言語を日本語にします。
1 2 3 |
# Optionally change default language # DEFAULT_LOCALE=de DEFAULT_LOCALE=ja |
migrationしてテーブルを作ります。
1 |
$ sudo docker-compose run --rm web rails db:migrate |
jsやcssをprecompileします。
1 |
$ sudo docker-compose run --rm web rails assets:precompile |
ここでNginxを再起動します。
1 2 |
$ sudo systemctl stop nginx $ sudo systemctl start nginx |
ここでようやく、
docker-compose upします。
1 |
$ sudo docker-compose up |
バックグラウンドで実行する場合は、
-dをつけます。
1 |
$ sudo docker-compose up -d |
これで
https://everydon.com/(あなたのドメイン)にアクセスすると、マストドンのログイン画面が表示されるはずです。

さぁ、早速ログインして使うぞ!と思っても、まだ使用することはできません。
Mastodonでのユーザー登録は、デフォルトではメールアドレス認証が必要です。
なので、登録したメールアドレスに送られる認証リンクをクリックして、ようやくログインできるようになります。
スポンサーリンク
メールの設定
メールはAWSのメールサービスSESを利用します。
SESの送信制限を解除する
SESは初期設定では、送信制限がかかり、SAND BOXモードになっており、次のような制限がかかっています。
- 事前に認証したメールアドレス以外には送信できない
- 1日当たり200通までしか送信できない
- 1秒当たり1通までしか送信できない
認証したメールアドレスにしかメールが送信されない状態です。
以下から、この送信制限を解除するための申請をします。
http://aws.amazon.com/ses/extendedaccessrequest/
次の内容で申請しました。

私の場合は、申請の翌日に英語の承認メールが来て、制限が解除されていました。
翌日まで待たずにすぐに動かしたい方は、次の「送信元に設定するアドレスの認証」と同じ手順で、送信先のアドレスも認証すると、とりあえずそのアドレスだけには送れるようになります。
送信元に設定するアドレスの認証
ユーザーに送られるメールの「送信元」に設定するメールアドレスが自分のものであることを、SESで認証する必要があります。
SESのコントロールパネルを開くと、東京リージョンはSESがないので、他のリージョンを選ぶ必要があります。日本に近いオレゴンをクリックします。


送信元に設定したいメールアドレスを入力します。Gメールなどの無料アドレスでもOKです。

そのアドレスに確認メールが届きますので、メール内のリンクをクリックします。

リロードボタンをクリックすると、verifiedと表示されたら認証完了です。

SMTP Credentialsの作成
次に、SMTPサーバーを利用するためのSMTP Credentialsを作成します。
まず、「Server Name」を控えておきます。
そして、「Create My SMTP Credentials」をクリックします。


「認証情報をダウンロード」をクリックすると、credentials.csvというファイルがダウンロードされるので、保存します。

環境変数ファイルへのSMTP情報の設定
ターミナルの作業に戻ります。
環境変数ファイルのSMTPの部分を修正します。
1 |
$ vim .env.production |
1 2 3 4 5 |
SMTP_SERVER=email-smtp.us-west-2.amazonaws.com SMTP_PORT=587 SMTP_LOGIN=XXXXXXXXXXXXXXXXX SMTP_PASSWORD=XXXXXXXXXXXXXXXX SMTP_FROM_ADDRESS=XXXXXX@gmail.com |
先ほど控えた「Server Name」とcredensitals.csvの中に記載されている値を設定します。以下のように対応しています。
.env.productionでの呼称 | AWSでの呼称 |
---|---|
SMTP_SERVER | Server Name |
SMTP_LOGIN | Smtp Username |
SMTP_PASSWORD | Smtp Password |
SMTP_FROM_ADDRESSは先ほどSESで認証したメールアドレスを記載します。
変更を反映するために、Dockerコンテナを再起動します。
「controlキー+C」でDockerコンテナは停止されます。
バックグラウンドで起動している場合は、以下を実行します。
1 |
$ sudo docker-compose down |
起動します。
1 |
$ sudo docker-compose up |
これで、登録時にメールアドレス確認メールがきちんと送信されるはずです。
cronの設定
Mastdonは生き物です!
急に取り乱してすみません。Mastodonは、息をするかのように、日々データを更新したり、他インスタンスとの連合を行っているので、定期的にメンテナンス処理をする必要があります。それをcronに登録します。
1 |
$ sudo vim /etc/crontab |
以下を追記します。
1 2 3 4 5 6 |
#いろいろやってくれるタスク 0 3 * * * cd /home/ubuntu/mastodon && sudo docker-compose run --rm web rake mastodon:daily #1週間以上前の他インスタンスから取得した画像動画キャッシュを削除してくれる(週一で動作) 0 3 * * 1 cd /home/ubuntu/mastodon && sudo docker-compose run --rm web rake mastodon:media:remove_remote #毎週土曜日の06:00にcertbot-autoを更新し、nginxを再起動 0 6 * * 6 sudo systemctl stop nginx && ~/certbot-auto renew && sudo systemctl start nginx |
3つタスクを追加していますが、上二つはマストドンのデータをメンテナンスする処理です。
参考: Mastodonで他インスタンスの情報が正常に表示されない場合の対処
最後の一つは、Let’s Encryptは90日で期限が切れるので、更新する処理をしています。90日ごとにやればよいのですが、念のため毎週動かしています。
以上でお手軽な手順を終了です。
大抵のインスタンスはこれで十分だと思います。負荷が増えてきたら、とりあえず、EC2のスペックをスケールアップしていけば当分はしのげるはずです。
ロードバランサーの導入
ここからは、負荷対策に備えてロードバランサーを追加する手順をご紹介します。
SSL証明書の取得
SSL証明書を取得するために、対象のドメインの所有者があなたであることを証明する必要があります。
そのために、AWSからあなたのドメインのメールアドレス宛てに確認メールを送り、それをクリックすることで確認をします。
あぁ、受信するためにメールサーバー立てなきゃいけないのかぁ、と思うかもしれませんが、AWSではS3バケットをメールボックスに簡単にすることができます。
SESでドメインを認証する
SESのコンソールに移ります。

対象のドメインを入力します。



pending verificationと表示されます。

Route53のコンソールで先ほど作ったHosted Zoneを見ると、2つレコードが挿入されているはずです。

SESでメールの受信ルールを作る
SESのコンソールにて、確認メールを受けるため、ルール(どこ宛てのメールはどこに届く)を作ります。

ルールの名前は適当でOKです。




確認メールが保存されるS3バケットの名前を決めます。



ACMでSSL証明書を作成する
ACM(Amazon Certificate Manager)のコンソールを開きます。
なお、SESはオレゴンリージョンを使っていましたが、ACMは後で作るELBと同じリージョンでないとダメのようです。なので、当方は東京リージョンのACMコンソールで行いました。

ここは対象のドメイン名を入力して下さい。


S3のコンソールで、先ほど作成したS3バケットの中身を見ると、確認メールが送られているはずです。下のようなファイルがいくつか入ってきています。どれでもいいので一つダウンロードします。

ダウンロードしたファイルを開くと、メールフォーマットなので見づらいですが、下のような部分があるはずです。そこに記載されているURLをコピーします。

コピーしたURLをブラウザで開くと下のようなページが表示されるので、「I Approve」をクリックします。

ACMのコンソールで「続行」をクリックします。

「発行済み」と表示されれば、SSL証明書の作成は完了です。

NginxをHTTPで待ち受ける設定にする
「お手軽な手順」では、HTTPSでユーザーからのアクセスを受け付けるNginxの設定ファイルになっています。
ここでは、SSLはELBが担当するため、NginxはHTTPで待ち受けるようにします。
1 |
$ sudo vim /etc/nginx/sites-enabled/default |
内容は以下になります。
everydon.comは、あなたのドメインに置換してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
map $http_upgrade $connection_upgrade { default upgrade; '' close; } #server { # listen 80; # listen [::]:80; # server_name everydon.com; # return 301 https://$host$request_uri; #} server { listen 80; listen [::]:80; server_name everydon.com; #listen 443 ssl; #listen [::]:443 ssl; #server_name everydon.com; #ssl_protocols TLSv1.2; #ssl_ciphers EECDH+AESGCM:EECDH+AES; #ssl_ecdh_curve prime256v1; #ssl_prefer_server_ciphers on; #ssl_session_cache shared:SSL:10m; #ssl_certificate /etc/letsencrypt/live/everydon.com/fullchain.pem; #ssl_certificate_key /etc/letsencrypt/live/everydon.com/privkey.pem; keepalive_timeout 70; sendfile on; client_max_body_size 0; root /home/ubuntu/live/public; 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 / { 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://127.0.0.1:3000; 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; } |
公式ドキュメントに記載されたものとの違いは、まずはHTTPS接続はしないので、基本はHTTPで接続する設定にしています。
Nginx再起動して変更を反映します。
1 2 |
$ sudo systemctl stop nginx $ sudo systemctl start nginx |
スポンサーリンク
ELBの作成
ELB(ロードバランサー)を作成します。


名前を適当につけ、リスナーにHTTPSを追加します。

少し下にスクロールし、二つのアベイラビリティゾーンをチェックし、「次の手順」をクリックします。

「証明書の名前」にて、先ほど作成した証明書を選択します。


ターゲットとは、そのELBからアクセスを割り振られるEC2インスタンスのことです。一つのELBから複数のECインスタンスへアクセスを割振るのでそれらを「ターゲットグループ」と呼びます。
名前は適当でOKです。ヘルスチェックのパスは /aboutとします。

最初の手順で作成したEC2のインスタンスを選択し、「登録済みに追加」をクリックします。



これで、ELBが作成できました。
ELBに独自ドメインを割り当てる
Route53の対象のドメインのHosted Zoneで先ほど作成したAレコードを修正します。Alias Targetには作成したELBを選択します。このプルダウンはなかなか選択肢が表示されないことがあります。その場合、ELBのDNS名をここに貼り付けたりしてると表示されるようになります。

これで https://everydon.com/のような独自ドメインからアクセスできるようになったはずです。
EC2の不要なポートを閉じる
実は今の状態だと、まだELBを経由せずにEC2に直接アクセスできます。
なので、HTTPやHTTPSでどこからでもアクセスできるルールを削除します。ただし、それを削除するとELBからEC2への通信もできなくなってしまうので、ELBからのHTTPアクセスは許可するようにします。
まず、ELBが所属しているセキュリティグループを確認します。

対象のインスタンスを選択し、下に表示されるセキュリティグループをクリックします。

編集をクリックします。

不要なルールを削除していきます。そして、先ほど調べたELBのセキュリティグループを送信元に入力したHTTPを追加します。
なので、作業用のSSHと追加したHTTPの2ルールだけが残る形になります。

Let’s Encrypt更新cronの削除
SSLはELBが担うので、Let’s Encryptを更新するcronは削除します。
1 |
$ sudo vim /etc/crontab |
以下の部分は削除してください。
1 2 |
#毎週土曜日の06:00にcertbot-autoを更新し、nginxを再起動 0 6 * * 6 sudo systemctl stop nginx && ~/certbot-auto renew && sudo systemctl start nginx |
負荷に合わせてEC2をスケールアウトする
鋭意執筆中です。しばらくお待ちください。
スポンサーリンク
Railsのスキルがない場合
マストドンを構築・運営するだけなら、正直Railsのスキルがなくてもできます。
ただ、先行するインスタンスと差別化していくためには、やはり独自にカスタマイズする必要がでてきます。Railsのスキルがないと、多分トップページの背景色を変えることもできないと思います。
なので、やはりRailsで開発がすらすらできる人が有利になります。
Railsのおすすめ入門教材についてまとめたので、よろしければご覧ください。

手っ取り早く短期間でマスターしたい方は、スクールでプロから学んでしまうのもアリかもしれません。次の記事がまとまっています。
個人的には、オンラインで質問し放題で現役のエンジニアが教えてくれるテックアカデミーがいいと思います。他のスクールは結構学生とかが講師やってます。。。
どのようにレッスンが進むか、無料説明会動画を視聴するとよくわかるので、興味がある方はそれだけでも見てみるといいかもしれません。
さいごに
いかがでしたでしょうか?
ぜひあなたらしいMastodonインスタンスを立ち上げてみてください!
ところで、開発環境の構築は済みましたか?
これからユーザーを集めるためには、先行インスタンスとの差別化を図る必要がありますよね。そのために、デザインや独自機能などをカスタマイズする必要があるのではないでしょうか?
本番環境のソースを弄るのも危険なので、お手元のパソコンでやはり開発環境を作っておきたいところです。
Macでの開発環境の構築方法を詳細に説明したので、そちらも合わせてご覧ください。

さらに話は変わりますが、
実名制SNS市場でのFacebookの独占体制ってよくないと思いませんか?
Facebookはフェイクニュース(偽ニュース)への対策が甘いと批判を受けています。また、Facebookはユーザーの画面を勝手に操作し、モルモットのようにユーザーを心理実験をしているというニュースもありました。
やはり独占体制によってあぐらをかいているのでしょう。
まだ、実名制をうたっているインスタンスはありません。
なので、Mastodon界のFacebook、いやFacebook打倒を目指して、実名限定のインスタンスを立ち上げました!世界初です。
その経緯はこちら。

なので、実名出したくない方は、登録しないでくださいね。アカウント停止作業が割と大変なので。
ただ、今ならまだ若いユーザー番号が手に入ります。
Twitterでもそうですが、桁が小さいユーザー番号だったり登録日付が超初期だったりすると、情報感度が高いという永遠の称号になります。後悔したくない方はお早めに。
あと、この記事をシェアする場合は、実名で登録してくれそうな友達がいる方のみお願いします。スパイのように匿名で入る人にたくさん来られても困るので。
とはいえ、これがもっと広まれば、Facebookへのプレッシャーもかけられるはずです。
一緒にFacebookの独占体制を打ち破りましょう!