# マストドン導入について②

2017/04/23

centOS 7上でApacheをすでに動かしている環境でマストドンを稼働させました。公式ではホスト側のWebサーバとしてnginxがおすすめされていますが、結局Apacheのリバースプロキシ機能でマストドンとWordPressを同居させることにしました。ちなみにメール周りが未設定なので、完了し次第追記します。まだアカウント登録はできません。

# 方針の変更

前回投稿した方針を変更しました。

  • 既存のサーバ(CentOS 7.3)にDocker環境を構築し、そこにマストドンのコンテナを乗せる

  • マストドンとWordPressを同居させるために、nginxをリバースプロキシサーバとして用いる。マストドンへのアクセスはコンテナに、WordPressへのアクセスはApacheに振り向ける(既存のApacheもリバースプロキシ機能を持っているが、SNSのような小さなリクエストを大量にさばくのには不向き)

  • マストドンとWordPressを同居させるため、既存のWebサーバであるApache 2.4.6をリバースプロキシサーバとしても用いる。

つまりどういうことかというと、

# before

a.jpg

# after

b.jpg

今からMastodon、Dockerに加えてnginxも習得するのは時間的に厳しいと判断。ApacheがMastodonへの少量かつ大量の処理をさばけるか疑問ですが、そうなったらそうなったときで。ユーザー数もそんなに多くならないと思うので大丈夫だと思う。

# 構築手順

# gitのインストール

Mastodon本体をgithubから引っ張ってくるのに使います。インストール後にきちんとインストールできたか確認。

# yum install git
# git --version
1
2

# dockerのインストール

Mastodonはdockerコンテナとして動きます。コンテナを用いないインストール方法もあるのですが、dockerのハンズオンがてら今回はdockerで。

# yum install docker
1

dockerを起動させ、自動起動設定をしておく。

# systemctl start docker
# systemctl enable docker
1
2

# Docker-composeのインストール

簡単にいうと、複数のコンテナが協調して動くようなシステムの管理を容易にするツール。Web-DBシステムをコンテナでやろうとすると、起動順序とかを気にしないといけないため長いシェルスクリプトを書かないといけない。そんなのを.ymlファイル一発で設定し、勝手にやってくれるツール。

今回は2017/04/16現在の最新版1.12.0を落としています。

# curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
1

実行権を付与し、きちんとインストールされたか確認。

# chmod +x /usr/local/bin/docker-compose
# docker-compose --version
1
2

# マストドンのインストール

git、docker、docker-composeをインストールし、ここまでで下準備は完了。マストドン本体をインストールします。

# cd "mastodonをインストールするディレクトリ"
# git clone https://github.com/tootsuite/mastodon.git
1
2

# マストドンの設定

マストドンをインストールしたディレクトリ内にある.env.productionを編集しマストドンの設定を、同ディレクトリ内にあるdocker-compose.ymlを編集しdocker-composeの設定を行います。

# cd mastodon
1

サンプルファイルがあるので、コピーして編集。

# cp .env.production.sample .env.production
# vim .env.production
1
2

コンテナを用いる場合、rediusやdbの設定はデフォルトでOK。まずはドメイン名とhttpsを用いるかどうかを設定する。公式ではhttpsが強く推奨されています。

LOCAL_DOMAIN=mstdn.serotoninpower.club
LOCAL_HTTPS=true
1
2

メール周り……後日追記します。

ここでいったん.env.prodctionの編集は終わり。続いて.ymlファイル。

# vim docker-compose.yml
1

こちらも特に難しい設定はしません。ただし、データの永続化設定はしておいてください。マストドンはデフォルトではデータをコンテナ内に保持します。これが何を意味するかというと、コンテナを落とした場合データが消えるということです。データはコンテナの外に出すようにしましょう。

## Uncomment to enable DB persistanceと記載されている下の二行と、### Uncomment to enable REDIS persistanceと記載されている下の二行をアンコメント。

これでデータはコンテナの外に出されます。データの配置場所もここでいじれるので、変更する場合はアンコメントした部分に記載のディレクトリを変更してください。ちなみにAWSのS3上にデータを保存することもでき、それ用の設定項目もありますが、今回は用いません。いったん編集終わり。

# secretの生成

コンテナ間の通信に必要な鍵を生成します。実はここなんなのかよくわかってない。

以下のコマンドを3回叩き、出力された文字列をコピーし、.env.productionPAPERCLIP_SECRET,SECRET_KEY_BASE,OTP_SECRETにそれぞれ貼り付け。初回コマンド実行時のみいろいろ走るので時間がかかります。

# docker-compose run --rm web rake secret
1

# データベースのマイグレーションとアセットのプリコンパイル

以下のコマンドでデータベースをマイグレーション。

# docker-compose run --rm web rails db:migrate
1

以下のコマンドでアセットをプリコンパイル。ログを見た感じAWS上に保存されている画像データなどを引っ張ってきて、ローカル上で使用できるようにしてるっぽい。

# docker-compose run --rm web rails assets:precompile
1

# マストドンの起動

コンテナ群のdockerイメージを構築します。起動後に設定ファイルを変更した場合、またこれが必要になります(コンテナ群をstopしてから実行してください)。

# docker-compose build
1

時間がかかるので待機。終わったらいよいよコンテナ群を立ち上げます。ここで-dオプションをつけないとホストの標準入出力がdockerに持っていかれるので注意。

# docker-compose up -d
1

けっこう時間がかかります。以下のコマンドで立ち上がっていく様子を見ることができます。

# docker-compose logs -f
1

ログ出力が止まったらctrl+Cで抜けます。ここまででようやくマストドンが立ち上がります。ただし、まだファイアウォールの設定や、リバースプロキシの設定がのこっています。

# iptablesの設定

私の環境ではファイアウォールにiptablesを使用しています。firewalldを利用されている方は適宜読み替えてください。

dockerがインストールされると、docker仮想ブリッジがホストのアダプタ直結で作成されます。私は外部から直接コンテナへアクセスされたくないので、ホストアダプタからのdocker仮想ブリッジへのアクセスをすべて拒否します。

# iptables -I DOCKER -i eth0 -j DROP
1

あとは保存してiptablesを再起動。

# iptables-save > /etc/sysconfig/iptables.save
# systemctl restart iptables
1
2

# Apacheのモジュール確認

今回は名前ベースのバーチャルホストとしてリバースプロキシし、動かします。httpsでリバースプロキシを行うために必要なモジュールが有効になっているか確認。

# httpd -M | grep -e ssl -e proxy -e rewrite
1

大抵デフォで必要なものは有効になっていると思いますが、ssl_moduleproxy_moduleproxy_balancer_moduleproxy_http_moduleproxy_connect_moduleproxy_wstunnel_modulerewrite_module有効化されていない場合は有効化しておいてください。

Apacheは設定ファイルを分割できるので、ここからの設定は直接http.confに書くなりconf.dやconf.modules.dに別ファイル作るなりしてください。

# http通信のリバースプロキシ設定

<IfModule mod_proxy.c>
#フォワードプロキシ無効にして、リバースプロキシを有効に
ProxyRequests Off

<VirtualHost *:80>
#既存のWordPressの方の設定。
#マストドンのほうだけVirtualHostを定義すれば良いわけではなく、一つでもVirtualHostディレクティブを記載するのならば、全てをVirutualHostとして扱う必要がある。
#なお、ここで80番ポートを指定しておかないと、443番ポートまで一緒に処理されてしまうので、ポートにワイルドカードは使用せず80番と指定しておく。
ServerName www.serotoninpower.club
DocumentRoot /var/www/html
</VirtualHost>

<VirtualHost *:80>
ServerName mstdn.serotoninpower.club
#マストドンの方の設定。基本的にhttpsへmod_rewroteを使ってリダイレクトさせる。
#ただし、Let's Encrypt(後述)が使用するファイルのみは書き換えない。
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule "^/.well-known/acme-challenge" "-" [END]
RewriteRule "^/(.*)" "https://mstdn.serotoninpower.club/$1"
</IfModule>
</VirtualHost>
</IfModule>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# https通信の設定とそのリバースプロキシ設定

conf.d/ssl.confにデフォルトの値が記載されているので、それを利用します。

複数のVirutalHostを定義するために、<VirtualHost _default_:443>をコメントアウトし、<VirtualHost *:443>に書き換え。

まずは既存のWordPressの方から。サーバーネームとドキュメントルートのみ変更。書く内容はhttpd.confやhttp通信のproxy設定で書いた内容と同じ。

ServerName www.serotoninpower.club
DocumentRoot /var/www/html
1
2

あとはデフォルト値でOK。SSLCertificateFileとSSLCertificateKeyFile、SSLCertificateChainFileはssl通信用の鍵を入手したら入力します。

続いてマストドンの設定。上記で編集した<VirtualHost *:443>から</VirtualHost>までの内容をだばーっとコピペし、その下に貼り付け。それを編集していきます。まずはサーバーネームの編集。

ServerName mstdn.serotoninpower.club
1

続いてDocumentRootを行ごと削除。SSLCertificateFileとSSLCertificateKeyFile、SSLCertificateChainFileはさっき同様あとで。ここからは新規にディレクティブを追加していきます。

# フォワードプロキシ無効にして、リバースプロキシを有効に
ProxyRequests off
#SSL通信を用いたプロキシ機能をonに
SSLProxyEngine on
#プロキシ設定。マストドンのWebサーバは3000番ポートで待ち受けているが、
# Streaming API(データを取得し続けるAPI。よくわかってない)は
# 4000番ポートで待ち受けており、またプロトコルもWebSocketであるため、それを明示する。
ProxyPass /api/v1/streaming ws://localhost:4000/
ProxyPass / http://localhost:3000/
ProxyPassReverse /api/v1/streaming ws://localhost:4000/
ProxyPassReverse / http://localhost:3000/
# バックエンドのマストドンがhttpsでリダイレクトを発行するよう指示。
# これがないとリダイレクトが無限ループする。
RequestHeader set X-Forwarded-Proto "https"
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# SSL証明書の発行

あとひといき。Let's Encryptを利用して無料でSSL証明書を発行してもらいます。

Let's Encryptは80番ポートを利用して証明書発行を行うため、いったんhttpdを止める。

# systemctl stop httpd
1

EPELリポジトリからcertbotをインストール。これがクライアントとしてLet's Encryptからの証明書の発行を自動化してくれる。

# yum install epel-release
# yum install certbot
1
2

証明書を発行。-dオプションを複数つけると、いっぺんに複数ドメインの証明書を要求できる。

# certbot certonly -standalone -d www.serotoninpower.club -d mstdn.serotoninpower.club
1

メアドを求められるので入力。利用規約に同意。これで証明書の発行が完了。

SSL証明書が発行できたので、さきほどのSSLプロキシ設定のところで後回しにしていた部分を埋める。

WordPress側

SSLCertificateKeyFile /etc/letsencrypt/live/www.serotoninpower.club/privkey.pem SSLCertificateFile /etc/letsencrypt/live/www.serotoninpower.club/cert.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.serotoninpower.club/chain.pem
1
2

マストドン側

SSLCertificateKeyFile /etc/letsencrypt/live/mstdn.serotoninpower.club/privkey.pem SSLCertificateFile /etc/letsencrypt/live/mstdn.serotoninpower.club/cert.pem
SSLCertificateChainFile /etc/letsencrypt/live/mstdn.serotoninpower.club/chain.pem
1
2

最後にhttpdを起動し、設定を読み込ませて終了。ブラウザから無事アクセスできるか確認してください。

# systemctl start httpd
1

# まとめ

非常にしんどかった。知識不足を感じた。まだ設定作りこめていない部分もあるので、随時ブラッシュアップしていきます。メールサーバが用意できてアカウントが登録できるようになったらまた通知します。