CentOS7でmastodonを建てる

#この記事のターゲット
- ますどん日本語情報の激しい欠乏に苦しんでいる人
- インスタンスをブチあげて楽しみたいけど英語を見ると蕁麻疹が出てしまう人
- Linuxサーバの基本的なことはわかっているけど、Dockerはちょっと…な人

今回は自分のインスタンス( https://mastodon.motcha.tech )の立ち上げの流れを記載し、
躓いたポイントやヒントになりそうなことを挙げていきます
なお筆者はぺーぺーの鯖缶、非プログラマかつgitやRuby周りの知識が
果てしなく浅いのでビンビンに間違っていると思われますので、ご指摘大歓迎です。
作業は[ここ](https://hackernoon.com/deploying-mastodon-on-digital-ocean-f54b94c7f5b8)をベースにしました。thx!

#環境（例）
- さくらVPS 1Gコース　CentOS7
- お名前.comのドメイン（DNSはお名前のサーバにお任せ）
- sudo権限持ち一般ユーザ（作業で使用）
- 負けない心

#mastodonインストールの前準備
まずは素っ裸のCentOSに最低限のセキュリティ対策。
SSH、firewalldを利用して対策しておきます。
任意のSSHポート、80、443を開けておきましょう。
Dockerが内部ネットワーク構築の際にこちょこちょするので
ufwを使うとハマりそうな予感がします。
素直にfirewall-cmdから--add-port,--add-serviceしたほうがいいです。

## nginx(CentOS上プロキシとして機能）
その後、yum -y updateしてからnginxをインストール。
このnginxがプロキシになって、loの3000番で待ち受けている
Dockerコンテナとやりとりします。
コンテナを準備してから設定します。一旦存在を忘れて構いません。

##Docker環境の構築
いっぱいあるのでググってくだしあ
git,docker,docker-composeが使えれば最低限OKのはずです。
この辺うろ覚えなので「〇〇足りないやんけ！」って突っ込大歓迎です。
ちなみに、mastodon本体に必要なミドルウェア達はすべて
Dockerコンテナ内部で勝手に用意されます。
CentOS上に直接必要なのはnginxとDockerだけです。

#mastodon本体の構築
まずはますどん本体を拾ってきて、うちの子に仕上げていきます。
##git clone
お好きな場所で
```git clone https://github.com/tootsuite/mastodon.git
cd mastodon```
これで最新のmastodonの情報が降ってきます。
以降、このフォルダで作業をします。

##.env.productionの設定
mastodonの動作に必要な情報（DB、メールなど）を記載するファイルです。
まずはお手本ファイルをコピーして、実際に読み込まれる名前に。
```cp .env.production.sample .env.production```
以後、本番ファイルを編集していきます。
訳がわからなくなったらお手本ファイルを参考に。

###ドメイン/SSL設定
\#Federation以下の二つを設定
現代っ子なのでHTTPSは当然アリで動かしましょう letsencryptを後で使います
```LOCAL_DOMAIN=お使いのドメイン名
LOCAL_HTTPS=true```

###DB周り設定
\# Service dependencies
DockerコンテナとしてDBを動かす際に利用するユーザ名、DB名を指定しておきます
コンテナを起こした後でこの情報に合わせて設定するので、どこかにメモしておきましょう
```DB_USER=お好きなユーザー名（あとで作ります）
DB_NAME=お好きなDB名（あとで作ります）
DB_PASS=お好きなパスワード（あとで使います）```

ここまで終わったら一旦保存してファイルを閉じます。

###各種secretの作成
(いまいち理解しきってないのですが)サーバが利用する鍵的なファイルを
自分で生成し、設定する必要があります。
mastodonフォルダにいる状態で
```docker-compose run --rm web rake secret```
というコマンドを実行した結果を利用します。
PAPERCLIP_SECRET,SECRET_KEY_BASE,OTP_SECRETの3個必要なので、
3回実行して結果をメモしておいてください。
再度.env.productionを開き、値を各項目に記載します。

###メール設定
登録時にメールを送信する必要があります。
情報が少なく、mstdn.jpもメール周りでごたごたしたので要注意の項目です。

設定ファイル上ではMailgunやSparkPost、他のサイトではSendGridなどの
メール送信代行サービスがおすすめされています。
自分は[SparkPost](https://www.sparkpost.com/)を利用したので、その設定の流れと例を記載します。
一日に何通まで無料で送れますよ、という枠があるので
課金等はとりあえず心配いらない、はず。

（蛇足：mstdn.jpのように大きくなってしまうと送信枠が不足しますが、
mastodonの思想は分散と小さなコミュニティを旨とするので、
本来であれば不足するほど一つのインスタンスに集中する事態が誤りです。
管理者は適切なサイズになったら登録を締め切ることが大切です。NO MONOPOLY HERE.）

ブラウザを開いてSparkPostに登録します。

1. メールアドレスのverifyを受ける 
登録時に利用した個人的なメールアドレスが有効なものかどうか確認をしておきます。
しておかないと進まない？のかな？

2. メール転送に利用するドメインを設定する
代行サービスがドメイン名を利用するために、
TXTレコードを自分のドメインに登録する必要があります(DKIM Record)。
サイトにログインしてから
Sending Domains -> New DOMAIN　で自分のドメイン名を記載しましょう。
DKIMレコードが現れるので、自分のドメインにTXTレコードとして登録します。
Testからサービス側がレコードを認識したか確認できるので、
ちょっぴり待ってから確認しましょう。

3. 転送ドメインの登録（任意）
別ドメインからメールを送りたい、そんな人はbounce domainから登録できます。
CNAMEを登録できる任意のドメインを登録可能ですので、
なにかしらしたい人はどうぞ。

4. APIキーの取得
API Keys -> NEW API KEYからmastodon本体がsparkpostへログインする際に
利用するAPI鍵を生成します。
名前はなんでもかまいません。
セキュリティ上の観点から、最初の生成時から後は管理者であっても
再度鍵を全文表示させることはできません。
後から確認できるしいーや、ではなくしっかりとメモしておきましょう。

ここまで行けばSparkPost側での作業は終了です。サーバーに戻りましょう。
```SMTP_SERVER=smtp.sparkpostmail.com
SMTP_PORT=587
SMTP_LOGIN=SMTP_Injection
SMTP_PASSWORD=生成したAPI鍵を記載
SMTP_FROM_ADDRESS=好きな名前@DKIM/CNAMEを登録したドメイン名
SMTP_AUTH_METHOD=plain
SMTP_OPENSSL_VERIFY_MODE=none
SMTP_ENABLE_STARTTLS_AUTO=true```
で設定しました。突っ込みどころがあればお願いいたします（真顔）

##コンテナ立ち上げ（DB設定等）
さあいよいよ、コンテナを立ち上げていきますよ！
gitしたmastodonフォルダ内にいないとdocker-composeが
正しい情報を拾ってくれないので、作業場所は固定で。
```docker-compose build```
このコマンドでmastodonフォルダ内部にあるデータを使って、
コンテナ構築の準備をしてくれます。
あの設定がやっぱり間違っていた！とかgit pullして更新した！というときは
再度buildを掛けることになります（よね？自分も曖昧ですが…）。
コンテナ群の停止には```docker-compose stop```を使いましょう。
```docker-compose down```するとイメージごと消えてしまうので、設定もデータも吹き飛びます。
既存のコンテナ群に設定変更を加えたときは
stop -> build -> up　で変更を適用してくれるので、downせぬようご注意ください。

暫定的にmastodonのコンテナ群を立ち上げます。
```docker-compose up -d```
-dを忘れると標準入出力をコンテナに持っていかれるので気を付けましょう。

##DB設定とmigrate
立ち上がってきたDBコンテナに入って、DBのユーザ情報を設定していきます。
先ほど.env.productionで記載したDB関連のデータを使うのでメモを握りしめて作業します。
```docker exec -it mastodon_db_1 /bin/bash```

既定で入っているpostgresユーザを使います
```su - postgres```

まずはユーザの作成
```createuser -P お好きな名前```

DBも作成します。所有者は今作ったユーザを指定します
```createdb お好きなDB名 -O 今作ったユーザ名```

コンテナ内部での作業完了です。

##仕上げ
exitコマンドを2回打ってコンテナからCentOSに戻ってきてから
```docker-compose run --rm web rails db:migrate```
でDBのマイグレーションをしましょう。だーっと様子が流れます。

```docker-compose run --rm web rails assets:precompile```
でアセット（動的ページで利用する画像とかスクリプトのデータ群）を
事前コンパイルしておきます。

アセット周りになにか問題が起きたときは
```docker-compose run --rm web rails assets:clean```
もしくは
```docker-compose run --rm web rails assets:clobber```
してから再度プリコンパイルするといい気がします。
権限回りで怒られてデプロイ後のサイトでアセットが全然表示されないときは、
コマンドの末尾にRAILS_ENV=productionを付けるとよさそうです。

仕上げにコンテナ群を再起動しておきましょう。
```docker stop $(docker ps -a -q) && docker-compose up -d```
もしほかのdockerコンテナを動かしている場合、道連れで落ちるのでdocker-compose stop && docker-compose up -d等で代用してください。
たぶん、きっと動くはず。

ここまでくれば```curl localhost:3000```でmastodonが動いていることが確認できるはずです！ぱおーん！

##nginxとSSL設定
##自ドメイン用のSSL鍵を取得する
[ここ](https://tsuchikazu.net/lets-encrypt-nginx/)とか参考にしつつcertbotをインストールし、
httpsに必要な鍵をゲットしましょう。
何も触っていないので、比較的シンプルに必要な鍵を確保できるかと思います。
nginx側への適用設定は、mastodonへのプロキシ設定を兼ねて行います。
##プロキシ設定
[外の世界] - 80,443[nginx] - 3000,4000[Dockerコンテナ]
ますどんのネットワーク超簡易構成図は上の通りです。
nginxがリバースプロキシとして機能します。
自分が利用したバージョンはnginx/1.10.2。

まず設定を書き込むファイルを新規作成して編集していきます。
```vim /etc/nginx/conf.d/mastodon.conf```
中に書き込むのは[この公式サイト](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md)に掲載されている設定例(nginx)です。
vimの置換機能で```:%s/example.com/自分のドメイン名/g```すると楽ちんです。

自分はトラブルシューティングの際に別ログを吐いてほしかったので
443で待ち受けるserverディレクティブの中に
```error_log /var/log/nginx/mastodon/error.log warn```
```access_log /var/log/nginx/mastodon/access.log main```
と追記しました。```mkdir /var/log/nginx/mastodon```しておかないと後で怒られます。

次に、デフォルトの設定をもろもろコメントアウトしておきます。
```vim /etc/nginx/nginx.conf```
で開いて、80番,443番で待ち受けている
serverディレクティブをすべてコメントアウトしました。
（ここはさっぱり分かってないところなので多分に間違っている気がします…）

各種設定が終わったら```systemctl start nginx```しましょう。
お疲れさまでした。外の世界とますどんが繋がりますよ！

#サーバーの動作確認
一番乗りでログインしましょう。好きな名前を取り放題ですよ、グヘヘ。
nginxがエラーを吐いて403等が見えているときは
```tail /var/log/nginx/mastodon/error.log```をチェック。journalctlも役に立つんじゃないかな。

#管理業務について
まずは、サーバーの管理者として自分のアカウントに管理権限を付与しておきましょう。
~~サーバが走っている状態で適当なサーバに入ります
```docker exec -it mastodon_db_1 /bin/sh```~~
追記：どうやら、mastodon_web_1に入る必要があったようです。
```docker exec -it mastodon_web_1 /bin/sh```
勉強不足でした。教えて頂いてありがとうございます！！！

付与コマンド
```RAILS_ENV=production bundle exec rails mastodon:make_admin USERNAME=alice```
これで自インスタンス内のユーザーaliceが管理者権限持ちに変化します。
権限持ちのユーザーでmastodonにログイン後、
設定画面に管理者専用の設定項目が追加されます。

ついでなので、管理者として実行できるコマンドと説明について
この機会に見ておくといいでしょう。
```RAILS_ENV=production bundle exec rails rake -T```

#(4/23)追記
[購読が切れてしまう](http://cryks.hateblo.jp/entry/2017/04/18/125351)事象が起きるようです。
どうも、Dockerで手なりに構築しただけでは
DailyのRakeタスクが走ってくれません。
連合が機能しないのは大問題ですので、
[ここで説明されている手順](http://qiita.com/clworld/items/bc3d8f97d38f2ba58492)を参考にどうぞ。

自分はCentOS（ホストOS側）のcronで
```cd /作業フォルダー/ && docker-compose run --rm web rake mastodon:daily
```
と記載しました。

それでは、思う存分パオり倒してください！