Mastodonをdocker-composeで立てる(Ubuntu 18.04)
- tootsuite/mastodon: Your self-hosted, globally interconnected microblogging community
- Mastodon documentation
内容はコミットID44d5c6bc8ffd92cd201380dabe35748e50b6af68
、Mastodon Dockerイメージバージョンv3.2.1
(Digest:sha256:41cd5fb48d8b15ec806f08ab06fec98df33ec9b83a1f879e0fb30da9994018dc
)におけるもの。docker-compose
の設定ファイルバージョンは3
。
$ lsb_release -aNo LSB modules are available.Distributor ID: UbuntuDescription: Ubuntu 18.04.5 LTSRelease: 18.04Codename: bionic$ uname -r5.4.0-56-generic$ docker -vDocker version 19.03.14, build 5eb3275d40$ docker-compose -vdocker-compose version 1.27.1, build 509cfb99$ docker images tootsuite/mastodon --digestsREPOSITORY TAG DIGEST IMAGE ID CREATED SIZEtootsuite/mastodon v3.2.1 sha256:41cd5fb48d8b15ec806f08ab06fec98df33ec9b83a1f879e0fb30da9994018dc 37ca50fc92bd 6 weeks ago 1.86GB
今回はDocker Hub上のイメージを使用し、ローカルビルドをしない想定でいく(ごちゃごちゃするので)。
Mastodonを改造したい場合など、必要に応じてgithub:tootsuite/mastodon
をFork/Cloneし、自分で/CIでビルドして信頼できるDockerレジストリに登録すればいいと思う。
Mastodonのリポジトリからdocker-compose.yml
、.env.production.sample
をコピーしてくる。
環境変数設定ファイルである.env.production.sample
を.env.production
にリネームする。
ローカルビルドはしないので、web、streaming、sidekiqからbuild: .
の行を削除する。
また、image: tootsuite/mastodon:v3.2.1
のようにバージョンを固定しておく(実運用する場合は定期的に書き換えてバージョンアップ)。
DB、Redis、Mastodon各サービスのDockerイメージを取得する。
docker-compose pull
DB(PostgreSQL)のパスワードを生成する。
# 適当な長さで# rake secretを使ってもいいのだろうか?pwgen 32
docker-compose.yml
中のDB部分にDB名・ユーザ名・パスワードを設定する
(docker-compose.yml
に直接書きたくない場合は.env.db
などを作成、env_file:
以下にファイルパスを設定する。またはdocker-compose.override.yml
を作成する)。
healthcheck
のところのユーザ名の書き換え、DB名の書き換えを忘れないように注意(FATAL: role "postgres" does not exist
、FATAL: database "mastodon" does not exist
)。
db:restart: alwaysimage: postgres:9.6-alpineshm_size: 256mbnetworks:- internal_networkhealthcheck:test: ["CMD", "pg_isready", "-U", "mastodon", "-D", "mastodon_production"]volumes:- ./postgres:/var/lib/postgresql/dataenvironment:POSTGRES_USER: mastodonPOSTGRES_DB: mastodon_productionPOSTGRES_PASSWORD: YOUR_PASSWORD
Mastodonの環境変数設定ファイル.env.production
の編集に移る。
Federationのセクションにいき、LOCAL_DOMAIN
を編集する。
起動テスト目的なら適当なドメイン、またはngrokでHTTP 3000番(Mastodonのデフォルトポート)を開けておいてそのドメインを使うというのでいいと思う(そうした場合、実運用時は初期化した方がよさそうだが)。
ひとまずメールアドレス検証で送られるメールの確認リンクに使用されていた(適当なドメインを使用した場合はパスをコピーして使用すればよい)。
# Federation# ----------# This identifies your server and cannot be changed safely later# ----------LOCAL_DOMAIN=mstdn.example.com
Redisのセクションにいき、REDIS_HOST
を編集する。
docker-composeが作成するネットワークを使用するので、ホスト名redis
(サービス名)で接続できる。
# Redis# -----REDIS_HOST=redisREDIS_PORT=6379
PostgreSQLのセクションにいき、DB_HOST
、DB_PASS
を編集する。
docker-composeが作成するネットワークを使用するので、ホスト名db
(サービス名)で接続できる。
# PostgreSQL# ----------DB_HOST=dbDB_USER=mastodonDB_NAME=mastodon_productionDB_PASS=YOUR_PASSWORDDB_PORT=5432
ひとまず全文検索エンジンElasticSearchは無効化しておく。
# ElasticSearch (optional)# ------------------------ES_ENABLED=false
セッション用と二要素認証用の2つのシークレットをDocker Hub上のMastodonイメージ(docker.io/tootsuite/mastodon
)内のRakefile
を使って生成する。
標準出力にランダム文字列が吐き出されるのでコピーする。
# for SECRET_KEY_BASEdocker run --rm tootsuite/mastodon:v3.2.1 bundle exec rake secret# for OTP_SECRETdocker run --rm tootsuite/mastodon:v3.2.1 bundle exec rake secret
Web Pushの公開鍵・秘密鍵を生成する(環境変数を設定しないとエラー)。標準出力に.envの形式で吐き出されるのでコピーする。
docker run --rm --env-file ./.env.production tootsuite/mastodon:v3.2.1 bundle exec rake mastodon:webpush:generate_vapid_key
メールアドレス検証・通知などに使うメールサーバ(SMTPサーバ)を設定する。
今回は面倒なので自分のGoogleアカウントを使用する。 Googleアカウントの二段階認証が有効になっていることを確認し、 Googleアカウント設定からメールに使用するアプリパスワードを生成する。
実際は、SendGridなどのEメールプロバイダを使ってメールサーバを用意するのがよい。 手順はドメインプロバイダ/DNSサーバにレコードを追加する程度なので、それほど難しくない。
# Sending mail# ------------SMTP_SERVER=smtp.gmail.comSMTP_PORT=587SMTP_LOGIN=YOUR_NAME@gmail.comSMTP_PASSWORD=YOUR_APP_PASSWORDSMTP_FROM_ADDRESS=YOUR_NAME@gmail.com
オブジェクトストレージ接続機能はひとまず無効化しておく。
# File storage (optional)# -----------------------S3_ENABLED=false
設定ファイルの編集は以上。
DBの初期化と静的ファイル生成。
docker-compose run --rm web rails db:migratedocker-compose run --rm web rails assets:precompile
rails assets/precompile
の方は、プロキシ環境下でinfo There appears to be trouble with your network connection. Retrying...
のように表示されて止まってしまうことがある。自分のテスト環境では、docker-compose run --rm -e HTTP_PROXY -e HTTPS_PROXY web bash -c "yarn config set proxy \$HTTP_PROXY -g && yarn config set https-proxy \$HTTPS_PROXY -g && yarn config set network-timeout 1000000 -g && rails assets:precompile --trace"
のようにプロキシやタイムアウト時間を設定しても解決しなかった(traceを見る限り、assets:precompile
内のyarn install
で止まってしまう。Railsの該当部分のソースコード)。yarn
の実体はIMAGE_HOME/bin/yarn
のようだが、IMAGE_HOME/bin/yarn config
のようにしても変わらず、-g
を外しても変わらなかった)。結局解決方法はわからなかったが、プロキシ外で実行してもマウントしているディレクトリ(./public
)には今のところ何も生成されない(Everything's up-to-date. Nothing to do
)ようなのでこの手順は飛ばしても問題ないかもしれない..(DBを変更しているかどうかはわからないが)。
docker-compose run --rmでweb以外のコンテナが止まらないので一度すべてのコンテナを停止・削除する。 これにより永続化が正しく動作していることを確認できる。
docker-compose down
本起動。
restart: always
が設定されているためdocker-compose down
しない限りはホスト再起動時も自動で起動する。
docker-compose up -d
途中で操作間違えたり、DB初期化中にkillしたりして失敗したときはコンテナ・マウントディレクトリを削除して初期化 。
docker-compose downsudo rm -rf postgres/ public/ redis/
HTTP 3000番から接続し、ブラウザ上でアカウントを作成する。
検証メールが届く。
その後アカウントhoge
を管理者に設定する。
docker-compose run --rm web bundle exec bin/tootctl accounts modify hoge --role admin
またはコマンドで管理者アカウントを作成する。ランダムパスワードが生成され、標準出力に出力される。
docker-compose run --rm web bundle exec bin/tootctl accounts create hoge --email hoge@example.com --confirmed --role admin
http://localhost:3000
でうまく接続できないときやリモートマシンで立てたときは、ngrokを使うのが便利。
# ポート3000番をランダムURLで外部からアクセスできるようにするngrok http 3000
プロフィール画像アップロード時にエラーが出てしまった。
./public/system
をマウント時にdockerが作成しているためにroot
所有になっているのが原因。
Errno::EACCES (Permission denied @ dir_s_mkdir - /opt/mastodon/public/system/accounts)
docker-compose run --rm web id -u
の出力は991
だったので、ホスト側でsudo chown -R 991:991 ./public
を実行して所有者を書き換えて解決した。
多人数が利用する OR 長期的に利用する予定で、VPSでホストするような場合、添付ファイルがVPSの容量を喰いつぶしてしまうことが想定されるので、そのような場合オブジェクトストレージを用意したい。
一人専用サーバの場合、.env.production
に以下の設定を追加すると便利。/
へのアクセスをユーザページにリダイレクトしてくれるようになり、新規登録を停止する。
SINGLE_USER_MODE=true
HTTPS化のためnginxによるリバースプロキシを設定する。
GitHub上にあった設定フ ァイルを参考にしている。
おそらくX-Forwarded-Proto https
を設定しないとhttps://localhost
にリダイレクトされるという事象が起こるので注意。
証明書の設定は書いていないが、certbot
(Let's Encrypt)を使用する場合sudo certbot --nginx
で自動挿入してくれる。
Mastodon側のポート番号はデフォルトのローカルループバックアドレスへのbindをそのまま使うことを想定。
# https://github.com/tootsuite/mastodon/blob/master/nanobox/nginx-local.conf# https://github.com/tootsuite/mastodon/blob/54192a9b6f8ee68114e3bc9ebf241099456e85f6/nanobox/nginx-local.confupstream rails {server 127.0.0.1:3000;}upstream node {server 127.0.0.1:4000;}map $http_upgrade $connection_upgrade {default upgrade;'' close;}server {server_name mstdn.example.com;keepalive_timeout 70;client_max_body_size 80M;add_header Strict-Transport-Security "max-age=31536000";location / {try_files $uri @rails;}location @rails {proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-Host $host;proxy_set_header X-Forwarded-Server $host;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://rails;proxy_buffering off;proxy_redirect off;# WebSocketproxy_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-Host $host;proxy_set_header X-Forwarded-Server $host;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://node;proxy_buffering off;proxy_redirect off;# WebSocketproxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection $connection_upgrade;tcp_nodelay on;}}