概要
Docker および Docker Compose を使い、Mastodon および関連サービス(Nginx)、SSL 証明書(certbot + Let's Encrypt)動作環境をセットアップします。LinuxやDockerに慣れている方であれば、所要時間は10分程度です。
作成するサービス(コンテナ)、ボリューム、ネットワークの関係は、下図の通りです。
前提知識
Docker Compose の基本操作(応用チュートリアル:WordPress)の理解が望ましいです(必須ではありません)。
6/28(水)ハンズオン用の補足情報
- 希望者に「
任意の名称
.sakuradon.jp 」の DNS 設定を発行します(当日のみ) - サーバの IP アドレスを講師までお知らせください
環境構築(CentOS 7.3)
Docker のセットアップ
# curl -sSL https://get.docker.com/ | sh
# systemctl enable docker
# systemctl start docker
Docker Compose のセットアップ
# curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
チュートリアル内容について
GitHub の Mastodon リポジトリで docker-compose.yml が提供されています。しかし、こちらは Mastodon 単体であり、Nginx フロントエンドやメールサーバ等の設定は含まれていません。また最新版(latest)ではイメージをビルドできなかったり、Docker Hub上のlatestタグのイメージに不具合があったりします。
そのため、公式ドキュメントの手順に準じながら、一通り Mastodon を動かすために必要なサービスを、Docker を通して管理できるようにします。
本チュートリアル(ハンズオン)では、Docker Hub 上から最新安定版(今日現在v1.4.6)のDockerイメージを取得し、実行します。
1. 作業用アカウントの作成
root 権限で mastodon
アカウントを作成します。また、このアカウントは docker
グループにも所属します(docker
グループに所属しているユーザは root
権限としてコンテナを実行可能です。つまり、サーバ上で事実上の root 権限を持っているのと同じ状態のため、セキュリティ上の取り扱いにご注意ください)。
# /usr/sbin/groupadd -g 991 mastodon
# /usr/sbin/adduser -g mastodon -u 991 mastodon
# usermod -aG docker mastodon
ユーザを作成した mastodon
切り替えます。
# su - mastodon
それから docker version
コマンドを実行し、バージョン情報を確認します。「Server:」 のバージョン情報が表示されていれば正常です。表示されない場合は Docker Engine が起動しているかどうかや、mastodon アカウントが docker グループに所属しているかどうか、確認します。
$ docker version
Client:
Version: 17.05.0-ce
API version: 1.29
Go version: go1.7.5
Git commit: 89658be
Built: Thu May 4 22:06:25 2017
OS/Arch: linux/amd64
Server:
Version: 17.05.0-ce
API version: 1.29 (minimum version 1.12)
Go version: go1.7.5
Git commit: 89658be
Built: Thu May 4 22:06:25 2017
OS/Arch: linux/amd64
Experimental: false
2. Let's Encrypt 証明書の作成
Mastodon のフロントエンドには SSL 通信に対応した Nginx を設定します。そこで使うための SSL 証明書を作成します。作成には certbot
と呼ばれるツールを作成します。
ここでは certbot
プロジェクトの公式 Docker イメージを使います。また certbot
という名称の Docker ボリュームを作成し、そのボリューム内の /etc/letsencrypt
ディレクトリ内に証明書を保存します。
まずはじめに証明書を作成するためのテスト(ドライ・ラン)を実行します。次のコマンドの実行にあたり、 <ホスト名>
には Mastdon にアクセスする URL で使いたいホスト名(例:social.example.jp
)を、<メールアドレス>
には Let's Encrypt の通知用に使う自分のメールアドレスを入力します。
$ docker container run -it --rm -v certbot:/etc/letsencrypt \
-v /var/log/letsencrypt:/var/log/letsencrypt \
-p 443:443 \
certbot/certbot \
certonly --standalone --agree-tos --dry-run -n \
-d <ホスト名> --email <メールアドレス>
実行後、次のように The dry run was successful.
(ドライ・ランの成功)と表示されれば正常です。
IMPORTANT NOTES:
- The dry run was successful.
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
つぎは、先ほどのコマンドから ---dry-run
を削除して実行します。
$ docker container run -it --rm -v certbot:/etc/letsencrypt \
-v /var/log/letsencrypt:/var/log/letsencrypt \
-p 443:443 \
certbot/certbot \
certonly --standalone --agree-tos -n \
-d <ホスト名> --email <メールアドレス>
実行すると、次のようにメールアドレスを EFF で共有するかどうか訊ねてくる場合があります。その場合は Yes
または No
を入力します。
-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o:
最終的に、次のように表示されていれば、作成完了です。
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/social.zem.jp/fullchain.pem. Your cert will
expire on 2017-08-21. To obtain a new or tweaked version of this
certificate in the future, simply run certbot again. To
non-interactively renew *all* of your certificates, run "certbot
renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
これでボリューム certbot
の中に証明書が格納されました。
docker volume ls
コマンドで確認しましょう。
$ docker volume ls
DRIVER VOLUME NAME
local certbot
また、次のコマンドを実行することで、証明書関連ファイルを確認できます。
$ docker run -it -v certbot:/cert/ --rm alpine ls -al /cert/archive/ここにホスト名/
total 24
drwxr-xr-x 2 root root 4096 Jun 28 01:30 .
drwx------ 3 root root 4096 Jun 28 01:30 ..
-rw-r--r-- 1 root root 1805 Jun 28 01:30 cert1.pem
-rw-r--r-- 1 root root 1647 Jun 28 01:30 chain1.pem
-rw-r--r-- 1 root root 3452 Jun 28 01:30 fullchain1.pem
-rw-r--r-- 1 root root 1708 Jun 28 01:30 privkey1.pem
3. SSL 用設定ファイルの作成
SSL通信で使う鍵交換用パラメータ・ファイルを作成するために、openssl コマンドを実行可能なイメージを作成します。
$ cd
$ git clone https://github.com/zembutsu/mastodon-docker.git
$ cd ~/mastodon-docker/myopenssl
$ docker image build -t myopenssl - < ./Dockerfile
次に、鍵交換用パラメータ・ファイルを作成します。コマンドの実行後、1~2分ほど待ちます。
$ docker container run -it --rm -v certbot:/certbot myopenssl openssl dhparam -out /certbot/dhparam.pem 2048
4. Mastodon GitHub リポジトリの取得と設定ファイルの設置
GitHub リポジトリから、Mastodon 関連ファイルを取得します。
$ cd
$ git clone https://github.com/tootsuite/mastodon.git live
$ cd live
それから、設定ファイルを複製、または Docker 関連設定ファイルを上書きします。
$ cp .env.production.sample .env.production
$ cp ~/mastodon-docker/docker-compose.yml .
$ cp ~/mastodon-docker/Dockerfile .
$ cp -r ~/mastodon-docker/frontend .
$ cp ~/mastodon-docker/.env.smtp .
次に、設定ファイルを開きます。
$ vi .env.production
ファイルを開き、15行目付近の LOCAL_DOMAIN
を編集し、今回使う「ホスト名」にします。これは Mastodon のアクセスに使うための URL です。また、50行目付近のメールサーバ設定も次のように書き換えます。
# Federation
LOCAL_DOMAIN=<ホスト名 mastodon.example.jp など>
LOCAL_HTTPS=true
(省略)
SMTP_SERVER=mta
SMTP_PORT=25
SMTP_LOGIN=
SMTP_PASSWORD=
SMTP_FROM_ADDRESS=who@example.com ←※要編集(メールの From: アドレスです)
SMTP_DOMAIN=example.com ←※要編集(メールサーバ自身のホスト名、ここでは Mastodon を動かすホスト名を指定)
なお、この .env ファイルでは、 #
(コメント)の位置に注意が必要です。値の後に #
を使うと、 #
込みの値として処理されますので、値の後には書かないようにします。
# 作業用アドレスを使用
SMTP_FROM_ADDRESS=hoe@example.com
SMTP_FROM_ADDRESS=hoe@example.com # 作業用アドレスを使用
次に、メールサーバ用(exim4)設定ファイルを編集します。
$ vi .env.smtp
ファイル内容を編集します。
MAILNAME=example.com ←ここのホスト名を変更します
RELAY_NETWORKS=192.168.0.0/24
PORT=25
Nginx 用設定ファイルを編集します。
$ vi frontend/nginx-default.conf
ファイルを開いたら example.com
の箇所を、今回使うホスト名に変更します(5箇所)。vim の場合は一括置換(ESC
-> %s /example.com/自分のホスト名/g
)が便利です。
5. イメージの構築と取得
関連イメージの構築と取得を行います。build には数秒、pull はファイル容量が大きいため約1分半程かかります。
$ docker-compose build
$ docker-compose pull
※ docker-compose pull
実行時、最後に mastodon_frontend
イメージが pull できないというエラーが表示されますが、問題ありません(Docker Hub上に mastodon_frontend イメージは存在しないからです)。
6. 内部通信用ネットワーク作成
docker network create
コマンドで、Mastodon 内部通信用のネットワークを作成します。これは内部での名前解決を行うためと、データのやりとりや SMTP サーバを外部のパブリックなネットワークから切り離し、安全性を高めるためです。
$ docker network create --subnet=192.168.0.0/16 mastodon
ネットワーク mastodon
が作成されているか docker network ls
コマンドで確認します。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
7d9b04de513f bridge bridge local
babeb8b623d2 host host local
949a22119e80 mastodon bridge local
e49989f1bbd0 none null local
7. シークレットの作成と設定反映
シークレット(APIで言う所のトークンに相当)を3つ必要なため、次のコマンドを3回実行します。
$ docker-compose run --rm web rake secret
実行後、文字列が表示されますので、エディタ等に控えておきます。
そして .env.production
ファイルを開き、以下の行の =
のあとに追加します。
PAPERCLIP_SECRET=8979dee487...
SECRET_KEY_BASE=74a137afd0b0...
OTP_SECRET=aae3d46591fb057...
8. データベースの初期化とアセットのプリコンパイル
初期設定用のコマンドを実行します。
$ docker-compose run --rm web rails db:migrate
$ docker-compose run --rm web rails assets:precompile
これで特にエラーが出ていなければ、準備完了です。
9. Mastodon 起動と管理用設定
$ docker-compose up -d
実行後は docker-compose ps
で各サービスが起動しているかどうか、確認できます。各サービス(コンテナ)の状態(State)が起動中(Up
)なのを確認します。
$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------------------
live_db_1 docker-entrypoint.sh postgres Up 5432/tcp
live_frontend_1 nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
live_mta_1 /bin/entrypoint.sh exim -b ... Up 25/tcp
live_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp
live_sidekiq_1 bundle exec sidekiq -q def ... Up 3000/tcp, 4000/tcp
live_streaming_1 npm run start Up 3000/tcp, 0.0.0.0:4000->4000/tcp
live_web_1 bundle exec rails s -p 300 ... Up 3000/tcp, 4000/tcp
また、起動まで時間がかかるので、ログを取得し、画面のスクロールが止まるまで待ちます。
$ docker-compose logs -f
次のようなログが出れば問題ありません。
Attaching to live_web_1
web_1 | => Booting Puma
web_1 | => Rails 5.0.2 application starting in production on http://0.0.0.0:3000
web_1 | => Run `rails server -h` for more startup options
web_1 | Creating scope :cache_ids. Overwriting existing method Notification.cache_ids.
web_1 | [1] Puma starting in cluster mode...
web_1 | [1] * Version 3.8.2 (ruby 2.4.1-p111), codename: Sassy Salamander
web_1 | [1] * Min threads: 5, max threads: 5
web_1 | [1] * Environment: production
web_1 | [1] * Process workers: 2
web_1 | [1] * Preloading application
web_1 | [1] * Listening on tcp://0.0.0.0:3000
web_1 | [1] Use Ctrl-C to stop
web_1 | [1] - Worker 0 (pid: 14) booted, phase: 0
web_1 | [1] - Worker 1 (pid: 16) booted, phase: 0
ログの表示は Ctrl+C
で中断できます。
あとは、ブラウザから https://<ホスト名/
にアクセスし、アカウント登録を済ませます。
アカウント登録を済ませたら、対象アカウントを管理者として設定します。
$ docker-compose run --rm web rails mastodon:make_admin USERNAME=<ここにアカウント名>
コマンド実行後の URL から、サイトに関する管理情報を編集できるようになります。
最後に cron の設定を済ませます。crontab -e
を実行し、次の内容を追加します。
@daily cd /home/mastodon/live && /usr/local/bin/docker-compose run --rm web rake mastodon:daily > /dev/null
@weekly cd /home/mastodon/live && docker container run -it --rm -v certbot:/etc/letsencrypt -v /var/log/letsencrypt:/var/log/letsencrypt certbot/certbot renew && /usr/local/bin/docker-compose restart frontend > /dev/null
以上で設定完了です。
補足:手動でメールアドレスの許可
何らかの理由によりメールが送信できない場合、次のコマンドで手動許可できます(送信先メールの本文に含まれるURLをクリックした状態にします)。
docker-compose run --rm web rake mastodon:confirm_email USER_EMAIL=<ここにメールアドレス>
後片付け
次のコマンドを実行すると、Mastodon に限らず システム上の全てのockerコンテナ・イメージ・ネットワーク・ボリューム領域を 強制破棄 します。
$ cd ~/live/
$ docker-compose down
$ docker system prune