Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

AWSでMastodonインスタンスを作るまで。自分まとめ

More than 1 year has passed since last update.

だいたいネットのチュートリアル通り

http://webfood.info/mastodon-aws-tutorial/
だいたいこの通りにやると構築できます。

とするのも寂しいので、自分の環境で再現できるように、手順と詰まりやすい所を残しておきますね。

注意

version1.4.1からトップページがhttpsにリダイレクトする形になり、
SSL接続での構築が必須になりました。
上記の手順ではCertEncryptを使ってSSL接続を作っていますが、
自分はAWSのAmazon Cretificate ManagerでSSL接続を作っています。
そのためNginxとかの設定が一部変わっています、Amazon Cretificate Managerで認証する場合はこっちを使うといいかもです。
Nginx詳しく知らないので解説出来ない・・・(´・ω・`)

1.VPCを作る Virtual Private Cloud

A. まず、AWSから借りるサーバーをひとまとめにする仮想イントラネット、VPCを作ります。

image.png

この時、CIDR ブロックは XX.0.0.0/16をお勧めします。
ウィザード通りで大丈夫かと
image.png

↓ここからはVPCでトラブった時の雑学 CIDR ブロックについて若干おさらい。

VPCってなんだっけ。情報の授業のおさらい

VPCはAWSの仮想イントラネットです。VPCはサブネットマスクを使って自身のネットワーク内に
あるサーバーや更なるサブネットのアドレスを割り当てます。

こんな感じ、0が自分のネットワーク内で使えるアドレス

XX.0.0.0.0/24のサブネットマスク
11111111.11111111.11111111.00000000
0の数が8つ
2^8 = 256 のIPを割り振る事ができる。

XX.0.0.0.0/16のサブネットマスク
11111111.11111111.00000000.00000000
0の数が16
2^16 = 65536 のIPを割り振る事ができる。
これが分かってないと時々サブネットが作れず詰みになったりします。

情報の授業終わり

パブリックサブネットを作る

外部からSSH接続できるように仮想ルーターを配置します。
VPCの作成ウィザードで作成されてると思いますが、作られてなかったら、

A' VPCダッシュボードからインターネットゲートウェイインターネットゲートウェイの作成で仮想ルーターを作ります。

仮想ルーターが出来たら、VPCにアタッチで作成したVPCとルーターを繋ぎます。
これで仮想ネットワークがインターネットに接続されました。

ですが、まだルーターがあるだけです。どのサブネットを作り、ルーターと接続します。
B' サブネットの作成をクリックして先ほど作ったVPCにサブネットを作ります。
サブネットに割り当てるCIDRはXX.0.0.0.0/24がおすすめ

そして作成したサブネットをチェックし、ルートテーブルタブをクリック。
現在のルートテーブルを編集し、サブネットとインターネットゲートウェイをつなぎます。
image.png

rtb-XXXXXXXをクリックして編集します。

image.png

ルートタブから別ルートの追加 送信先を0.0.0.0/0 ターゲットをigw-XXXXXX(先ほど作成したインターネットゲートウェイのID)
を指定します。
これで、このサブネットにある仮想コンピューターはすべてインターネットからアクセスできるようになりました。
↑ここまで、VPCでトラブるケース。

2.インスタンスを作る。

A. Mastodonを実行するインスタンスを作ります。
インスタンスの作成をクリック
image.png

GithubのREADMEがUbuntuを推奨しているのでOSはUbuntuを選択するのがいいと思います。
一応はAmazon Linuxでも動く模様。
インスタンス詳細は先ほど作成したVPCサブネットを選択

image.png

ストレージは8Gだとすぐいっぱいになるっぽい。
20GBだとそれなりー、との噂を聞いたかも(曖昧)

セキュリティグループの設定

B. SSH接続からインスタンスを操作するようにセキュリティグループを作ります。

image.png

マイIPを選択し、自分のコンピューターからSSHポートが繋がるようにします。

image.png

画面には移りませんがSSH接続するのに、RSA暗号を使います。
インスタンスを作成時にキーペアが作成されるので自分用の秘密鍵を大切に保管してください。(秘密鍵が漏れて、自分の仮想コンピューターで好き勝手されて、20万の請求が来たとかいう話も)
これを失くすとインスタンスに接続できません。必ず漏れないように大切に保管してください。

C. 外部から接続できるようにインスタンスにパブリックIPを設定します。
サービス > EC2インスタンス > Elastic IP
から新しいアドレスの割り当てでパブリックIPを取得します。
パブリックIPが取得出来たらアクション > IP の関連付けで先ほど作成したインスタンスにIPを割り当てます。

3インスタンスに接続する。

A. まず、自分はwindowsなのでSSHクライアントをダウンロードします。
Putty」でググってダウンロード
image.png

B. インストーラーをダウンロードしてウィザードに従ってインストールします。

C. Puttyをインストールしたら、ダウンロードした秘密鍵をPutty形式に変換します。
PuTTYgenを起動してLoadをクリック

先ほど保存した秘密鍵ファイルを選びます。

image.png

選択したらsave private keyを選択し、秘密鍵を保存します。

A. いよいよインスタンスに接続します。
Puttyを起動します。
左のタブから SSH > Auth からBrowseボタンを押して、先ほど保存した秘密鍵を選択
image.png

秘密鍵を読み込んだら、
sessionを選択
Host Nameubuntu@XX.XX.XX(インスタンスに割り当てたパブリックIP)を入力
ここまで言ったら接続設定を保存しましょう
Saved Sessions適当な名前を入れて接続設定を保存します。

image.png

接続設定を保存したら、Openをクリック

image.png

こういう系の画面が出たら成功です。
これでLinuxサーバーが操作できます。

4.マストドンのセットアップ

ここからは完全に上述のテキスト通りです。

まず、メモリが足りないっぽいので、スワップファイルを作ります。

先ほどのコンソールにコマンドを打ち込みます。

$ 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

パッケージを最新にします。

$ sudo apt-get update
$ sudo apt-get upgrade

途中grub関連(?)の更新が聞かれますが

keep the local version currently installed

を選択してください。(どっちでも大丈夫だとは思うけど念のため)

マストドンのビルドetcに必要なソフトを入れます

$ sudo apt-get install -y python3-pip unzip docker.io nginx
$ sudo pip3 install docker-compose

上のテキスト通り、nginxの設定ファイルを編集します。

$ sudo vim /etc/nginx/sites-enabled/default

(vimの使い方はいいよね(´・ω・`))

元々機能してた部分は#でコメントアウトします。
XX.XX.XX.XXの部分はインスタンスのパブリックIP

置き換える内容は以下の通りで。

map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

#server {
#  listen 80;
#  listen [::]:80;
#  server_name XX.XX.XX.XX;
#  return 301 https://$host$request_uri;
#}

server {
  listen 80;
  listen [::]:80;
  server_name XX.XX.XX.XX;
  #listen 443 ssl;
  #listen [::]:443 ssl;
  #server_name XX.XX.XX.XX;

  #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/mastodon/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;
}

こんな感じになってるはず。
image.png

Nginxを再起動します。

$ sudo systemctl start nginx

これで、インスタンスのセキュリティグループをHTTPを任意のIPにすることでサーバーに接続できるはずです

Githubからマストドンのソースを持ってきます。

$ git clone https://github.com/tootsuite/mastodon

念のため、最新版を確認

$ cd mastodon
$ git tag -l
$ git checkout -b x.x.x refs/tags/vx.x.x(x.x.xは最新版のバージョン)

これでマストドンのソースがダウンロードされるはずです。

設定ファイルをコピーします。

$ cp .env.production.sample .env.production

dockerの設定ファイルの中でDBの永続化設定をします。

docker-compose.yml
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

dbとradisにある

  volumes:
    - ./nanntoka

の部分のコメントアウト(#)を外します

いよいよマストドンのビルドです
下記のコマンドを実行

$ sudo docker-compose build

5.マストドンの設定

マストドンが使うカギを生成します。
下記のコマンドを3回実行し、文字列をそれぞれどこかにコピーします。

$ sudo docker-compose run --rm web rake secret

こういう感じの文字列が出力されます。
3回コピーしてください。

4b804c1e71d14951a50cbc52f3b8a7ef9d1bf993e2774227cdf637102022f4a5af188aa4fa4c236b31e4ed6970469d1527e06097b678edfb0ed9e6d85c18d805

設定ファイルをもう一回いじります。

$ vim .env.production

ドメインの設定、後でもう一度設定し直します。
XX.XX.XX.XXはインスタンスのパブリックIP

# Federation
LOCAL_DOMAIN=XX.XX.XX.XX
LOCAL_HTTPS=false

秘密鍵を入力します
=の先に3つの秘密鍵を入力

# 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=

日本語設定はパス

DBのマイグレーションをします。
マストドンが使うデータベースの初期設定ですね。

$ sudo docker-compose run --rm web rails db:migrate

マストドンが使う固定ファイルを生成します。

$ sudo docker-compose run --rm web rails assets:precompile

ここで、Nginxを再起動します。
マストドンはport3000とport4000で動きますが、
以降は80ポートに来たアクセスをNginxがport3000とport4000に割り振ります。

マストドンへのアクセスの玄関口になる訳ですね。

$ sudo systemctl stop nginx
$ sudo systemctl start nginx

マストドンを起動します

$ sudo docker-compose up -d

マストドンが起動しました。

インスタンスにHTTP接続できるようにします。
インスタンスから作成したインスタンスにチェックを入れ セキュリティグループをクリック。
インバウンドからHTTP 任意のIPを追加し、どのIPでもHTTP接続できるようにします。

その状態で

http://XX.XX.XX.XX/

にアクセスするとマストドンのトップページに飛ぶはずです。
最新バージョンだと行かないかも

curl http://localhost:3000

コマンドを実行しても起動が確認できます。

<html><body>You are being <a href="http://localhost:3000/about">redirected</a>.</body></html>

とか

<html><body>You are being <a href="https://localhost/about">redirected</a>.</body></html>

と表示されたら起動成功です

mastodon-top.png

6.連携ソフトの設定

ドメインの入手。

まずは公開するURLを決めましょう
AWSのドメイン登録サービス Route53からドメインを購入します。

Route53に移動

ドメインは世界で唯一の名前にしないといけません。
好きな名前を決めましょう
名前を決めたら後ろにつく文字(トップレベルドメイン)を決めます。
.comや.net他が割安ですね。.jpは人気ですが年に90$(現状約9000円)するので財力のある方に。

image.png

checkでドメインが使えるか判定したら、add to cart > continueで購入手続きへ。

domein.png

ドメインの管理者の情報を登録します。cityで市町村、Zip Codeは郵便番号です。
基本的にドメインの管理者には連絡が取れるようなルールになっています。個人情報を見せたくない場合、Hide contact information if the TLD registry, and the registrar, allow itにチェック。
continueをクリック。

契約内容を確認したら
I have read and agree to the AWS Domain Name Registration Agreementにチェックを入れてComplete Purchace(購入を完了)をクリック。

ドメイン情報登録時に入力したメールアドレスに認証メールが来ます。そのリンクをクリックしたら
ドメインの購入は完了です。
これで、世界で一つだけ、あなただけのドメインが手に入りました。

メールサーバーの設定

マストドンが利用するメールサービスを設定します。
メールはAWSのメールサービスSESを利用します。

image.png

残念な事にSESはまだ日本でサービスが開始されていません。サービスを使う地域を選択。

image.png

Verify New Email Addressでメールサーバーがメールの送受信に使うアドレスを登録します。
新規にGmailとかで登録するのがいいと思います。(ドメインからの送受信はS3バケットの分料金かかるのと、まだ良く分かっていないので省略)

その後、Amazonから確認メールが来るのでメールに送信されたリンクをクリックします。
Statusが「verified」になったらメールの登録は完了です。

SESの送信制限を解除する。

image.png

登録はしましたが、このメールサーバーは不特定多数のメール送信に制限がかかっています。
サポートセンターに連絡して、制限を解除してもらいましょう。

サポートのダッシュボードに移動 > ケースの作成
からサービス制限の増加にチェックを入れ、申請理由を記入します。
こんな感じで大丈夫でした。

image.png

1日か二日程度でAmazonのサポートセンターから連絡が来ると思います。テカテカして待ちましょう。

マストドンがSESのメールを使えるようにする

SESのメールが使える様になったら、マストドンがメールを使えるようにします。
SMTP Settingから以下の部分をコピー
image.png

その後 Create My SMTP Credentialsをクリック。

image.png

SESにアクセス出来る権限ユーザーを作成します。作成をクリック。

その後、ユーザー名とパスワードを表示できる画面が出ます。
AKIAUSERNAMEBLABLAみたいな文字列。
これを必ずコピーしてください。これ以降、AWSに確認を取ることが出来ません。

この情報をマストドンに登録します。

$ vim .env.production

でマストドンの編集ファイルを開きます。

mailserver.png

SMTP_SERVERにSMTP Settingで確認したSESのサーバー名
ポートもSESのポート
SMTP_LOGINには権限ユーザーのユーザー名とSMTP_PASSWORDにパスワードを登録
そしたら保存してvimを閉じます。

一度マストドンを落として・・・

$ sudo docker-compose down

設定を反映させます。

$ sudo docker-compose up -d

これでマストドンにメールサーバーの設定が反映されました。
このインスタンスには(http://XX.XX.XX.XX)から ユーザー登録が出来るはずです。

SSL証明書を取得。

マストドンにはメールアドレスやらパスワードやら、大事な情報が入ります。
ですので、ドメインに接続する準備として、通信を暗号化します。

マストドン公式はLets Encryptを推奨してるみたいですが、
今回はAWSなのでAWSの機能でSSL通信を作ります。やり方の選択は趣味

Amazon Cretificate Managerに移動

image.png

確認とリクエストをクリックしてSSL証明書をリクエストします。
しばらくするとドメイン情報のメールに確認メールが来るので、リンクをクリックしてSSL証明絵所を取得します。

このSSL証明書は無料ですがAWS内でしか使うことが出来ません。

ssl.png

状態が発行済みとなったらSSL証明書の発行完了です。

ロードバランサの作成

このSSLを通してインスタンスにアクセスするようにします。
サービス > EC2 > ロードバランサーからロードバランサーの作成を選択。

image.png

Application Load Balamcerを選択して次へ

image.png

リスナーにHTTPSを追加し、VPCにマストドンのインスタンスがあるものを選択します。
※Applicaion Load Balancer は二つ以上のサブネットがあるVPCに対してしか動作しません!
VPCとサブネットの設定を間違えた人はVPCの設定を直すか、旧Elastic load Balancerを使ってください!(ELBでも一応動くはず)

次へ セキュリティ設定の構成

証明書の選択で、先ほど取得したSSL証明書を選択します。

AWS 証明書マネージャ (ACM) から、既存の証明書を選択するから
証明書の名前で先ほど取得したSSL証明書を選択。

image.png

次へセキュリティグループの設定

このロードバランサーは不特定多数からアクセスを受け付け、インスタンスのNginxサーバーにアクセスを渡します。

image.png

新しいセキュリティグループからポート80とポート443が任意のIPを受け付けている事を確認します。(デフォルトでそうなっているはず)

次へ ルーティングの設定

image.png

ロードバランサはインスタンスが動いてる時にのみアクセスを割り振ります。
よってチェックするテストアクセス(ヘルスチェック)を設定します。確かデフォルトでも大丈夫です。(駄目な場合はパスに/about を設定

ターゲットの登録をクリック

ロードバランサがアクセスを割り振るターゲットのインスタンスを決めます。
マストドンが動いているインスタンスをチェックし、登録済みに追加をクリック
image.png

最後確認してロードバランサの作成は完了です。

ここまで正常に動いているなら、ロードバランサのDNS「mymastodoalb-1145141919810.ap-northeast-1.elb.amazonaws.com」みたいなアドレスに、ブラウザからアクセスした時、マストドンに飛ぶはずです。

そうでないなら設定の見直し。だいたいはセキュリティグループのミスかと思います(インスタンスのセキュリティがロードバランサからのアクセス許可してないとかそういうの)

ドメインとロードバランサを紐付ける

割と最終工程。

ドメインにアクセスしたとき、ロードバランサに飛ぶようにします。
Route 53に移動します。

Registerd domainから取得したドメインを選択
さらにManage DNSからGo to Record Setsをクリックして、ドメイン情報を編集します。

domindns.png

Create Rcord SetからType Aを選択。AliasをYesにして
Alias Targetから先ほど作成したロードバランサを選択します。

Save Record SetでDNS情報を保存します。
domindns2.png

これで取得したドメイン http://mydomain.com からマストドンにアクセス出来るようになったはずです。

7. Http接続をSSL接続にリダイレクトする

今のままだと安全でない接続が開いています。
安全でない接続をSSL接続に飛ばしちゃいましょう。

インスタンスのコンソールから

$ sudo vim /etc/nginx/sites-enabled/default

でNginxの設定を開きます。

image.png

server_name XX.XX.XX.XX;

の XX.XX.XX.XXを取得したドメインに直し・・・

location / {
  try_files $uri @proxy;
}

location / {
  if ($http_x_forwarded_proto != 'https') {
    rewrite ^ https://$host$request_uri? permanent;
  }
  try_files $uri @proxy;
}

に直します。
80ポートでアクセスした時だけ、443ポートで再アクセスするように設定を書き加えました。
if(ヘッダー情報 != 'https')としているのは、ロードバランサが443ポートを受けた後、もう一度インスタンスで80ポートで受けるからです。
これがないとリダイレクトループを起こします。

次にマストドンの設定ファイルを修正します。

$ cd ~/mastodon
$ vim .env.production
 LOCAL_DOMAIN=XX.XX.XX.XX

これをドメイン名に修正。
あと、

LOCAL_HTTPS=false

trueにしておきます。これがfalseのままだと連合の通信が相手インスタンスに拒否られるとの噂(未確定)

ここまで着たら
Nginx と マストドンを再起動します。

$ sudo systemctl stop nginx
$ sudo systemctl start nginx

$ sudo docker-compose down
$ sudo docker-compose up -d

最後にマストドンが毎日実行するべきdailyタスクをlinuxに自動でやってもらう登録をします。

$ sudo vim /etc/crontab 

cronの設定ファイルを開き、
以下の情報を登録します

25 4,17 * * * /bin/bash -l -c 'cd /home/ubuntu/mastodon && sudo docker-compose run --rm web rake mastodon:daily'

こんな感じ
image.png

編集したら保存してvimを終了。
これでcronが自動で回るはずです。

ここまでで、最小構成のマストドンは運用できます。お疲れ様でした。

最後にEC2の不要なポートを閉じます。
HTTPの項目で送信元をロードバランサのセキュリティグループに変更します

domindns2.png

これでロードバランサを通じてしか、インスタンスにアクセスできなくなりました。

8.おまけ、ちょっとリッチな構成。

ちょっとデータベースは外部の高速サーバーに変えてみましょう。
RDSをクリック
インスタンスからDBインスタンスの作成をクリック

PostgreSQLを選択 次へをクリック

image.png

データベースの種類は無料枠と有料枠がありますが、その変は趣味で。
次へをクリック

image.png

DBの名前とアクセス出来るユーザーとパスワードを決めます。好きな名前を入力したら次へをクリック

VPCにインスタンスと同じネットワークを設定して。
新しいセキュリティグループの作成インスタンスからのアクセスを受け付けるようにします。

データベースに名前を入れてDBインスタンスの作成をクリック

image.png

しばらくすると、詳細をクリックすると、こんな感じのDBサーバーが立ち上がっていると思います。
domindns2.png

インスタンスからのアクセスを通すように(インスタンスのセキュリティグループを登録)DBサーバーのセキュリティのインバウンドを変更して・・・

domindns2.png

vim .env.production

から接続先DBを変更します。

DB_HOST=接続先のエンドポイント
DB_NAME=設定したデータベースの名前
DB_PASS=設定したパスワード
DB_PORT=設定したポート おおよそ5432

domindns2.png

接続先を設定したら反映させます。

$ sudo docker-compose down

今立てたDBサーバーにマストドンの持ってるテーブル情報をマイグレーションして反映させます

$ sudo docker-compose run --rm web rails db:migrate

これでpgadminとかからDBの反映が確認できたら成功です。
pgadminから見るとこんな感じのDB構成になってるのが見えると思います。

image.png

もう一度起動

$ sudo docker-compose up -d

これでDBサーバーの移行が完了です

最後に

個人的にマストドンのブームをきっかけにLinuxサーバーとかを触ってくれる人が増えたら嬉しいのですが、

初心者がこれを1日でやるのは絶対無理です!

慣れてる人でも2,3時間、という所っぽいです。
ですがこれをきっかけにサーバーを触る人も増えています。
みなさんもぜひ,オリジナルのサーバーを立てて、パオって見てください。

それでは!楽しんで!

shibafu
SESプログラマ Djangoが大好き プログラミングはいつも初学者
https://msdnaart.net/@pratula_admin
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away