はじめに
Dockerの勉強がてらに、今更感がありますが、Mastodonのインスタンスを立ててみました。
リバースプロキシや、サーバ証明書の自動更新をすべてDockerで
動かしたかったので以下の記事を参考にさせていただきました。
Docker🐳でMastodon🐘のインスタンスを立てるドン
リバースプロキシ + https + 全てコンテナ、な Mastodon インスタンス(無料)を構築してみたメモ
構築にあたっては、基本的に、ほとんど参考記事に従っただけですが、異なる部分や、何点かハマッたポイントもありましたので、備忘録として残しておこうと思います。
0. 前提条件
0.1. 環境
- サーバ:さくらVPS
- OS:Ubuntu16.04
- Mastodon:v1.3.3
0.2. 構築のポイント
- Nginxによるリバースプロキシを立てる
- Let's Encrypt によるサーバ証明書自動更新を行う
- 上記を含め、すべてDockerで動かす
- メールは手抜きでGmailを使用
0.3. 注意点
- 証明書を取得するのに、Aレコードに登録した独自ドメインが必要。
- Let's Encryptには証明書作成の制限がある。 (知らずに作って潰して繰り返してたら制限掛かった)
- Mastodonは、バージョンタグを指定してcheckoutする。
1. 事前準備
1.1. ポートの開放
$ sudo iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
$ sudo iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
1.2. Dockerのインストール
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
$ sudo apt-get install apt-transport-https \
ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce
$ sudo apt-get upgrade
$ sudo docker run hello-world
$ sudo groupadd docker
$ sudo usermod -aG docker $USER
$ exit
$ docker run hello-world
$ sudo systemctl enable docker
1.3. Docker-composeのインストール
$ sudo -i
$ curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose
$ exit
1.4. Dockerネットワークを作成する
フロント(リバースプロキシ)側と
Mastodon側のDockerネットワークをそれぞれ作成します。
$ docker network create --driver bridge front
$ docker network create --driver bridge back-mstdn
2. リバースプロキシの設定と起動
ホームディレクトリ配下にproxyというディレクトリを作成し、
その中にまとめました。
2.1. docker-compose.ymlを作成する
#ディレクトリを作成
$ sudo mkdir -p proxy
$ cd proxy
#ファイルを新規で作成して編集
$ sudo vi docker-compose.yml
docker-compose.ymlの内容は以下の通り。
これはどんな環境でも変わりはなさそうです。
version: '2'
services:
proxy:
image: jwilder/nginx-proxy:alpine
container_name: proxy-nginx
ports:
- 80:80
- 443:443
restart: always
tty: false
privileged: true
volumes:
- ./certs:/etc/nginx/certs:ro
- /var/run/docker.sock:/tmp/docker.sock:ro
- /etc/nginx/vhost.d
- /usr/share/nginx/html
networks:
- front
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: proxy-letsencrypt
restart: always
tty: false
privileged: true
volumes:
- ./certs:/etc/nginx/certs:rw
- /var/run/docker.sock:/var/run/docker.sock:ro
volumes_from:
- proxy
networks:
- front
networks:
front:
external: true
2.2. コンテナ起動
$ docker-compose up -d
#起動後のプロセスやログを確認する場合
以下のコマンドを実行する。
$ docker-compose ps
$ docker-compose logs -f
3. Mastdonのビルドする
他のアプリケーションを動かす場合に備えて、
ホームディレクトリ配下にappsディレクトリをして、
その中にまとめる。
3.1. Mastodonのクローン
$ sudo mkdir ~/apps
$ cd ~/apps
$ sudo git clone https://github.com/tootsuite/mastodon.git
3.2 Mastodonのビルド
注意点は、きちんとバージョンタグを指定してチェックアウトすること。
タイミングが悪いと、何やっても動かなかったりします。
以下はv1.3.3の例です。
$ cd mastodon
#バージョンタグの確認
$ git tag -l
#バージョン指定
$ sudo git checkout refs/tags/v1.3.3
#環境変数ファイルのコピー
$ sudo cp .env.production.sample .env.production
#ビルド実行
$ docker-compose build
4. Mastodonの設定
4.1. 環境変数ファイルの編集
以下のコマンドを三回実行して、それぞれ出力された値をメモしておく。
$ docker-compose run --rm web rake secret
続いて、環境変数ファイルを編集する。
$ sudo vi .env.production
ファイルの内容は以下の通り。
【】内を自身の環境に合わせて編集して下さい。
VIRTUAL_HOST=【自分のドメイン】
VIRTUAL_PORT=9090
VIRTUAL_PROTO=https
LETSENCRYPT_HOST=【自分のドメイン】
LETSENCRYPT_EMAIL=【自分のメールアドレス】
LETSENCRYPT_TEST=false
# Service dependencies
# You may set REDIS_URL instead for more advanced options
REDIS_HOST=redis
REDIS_PORT=6379
# You may set DATABASE_URL instead for more advanced options
DB_HOST=db
DB_USER=postgres
DB_NAME=postgres
DB_PASS=
DB_PORT=5432
# Federation
LOCAL_DOMAIN=【自分のドメイン】
LOCAL_HTTPS=true
# Use this only if you need to run mastodon on a different domain than the one used for federation.
# You can read more about this option on https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md
# DO *NOT* USE THIS UNLESS YOU KNOW *EXACTLY* WHAT YOU ARE DOING.
# WEB_DOMAIN=mastodon.example.com
# Application secrets
# Generate each with the `rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose)
PAPERCLIP_SECRET=【3.3でコマンド実行して1回目に出力された値】
SECRET_KEY_BASE=【3.3でコマンド実行して2回目に出力された値】
OTP_SECRET=【3.3でコマンド実行して3回目に出力された値】
# Registrations
# Single user mode will disable registrations and redirect frontpage to the first profile
# SINGLE_USER_MODE=true
# Prevent registrations with following e-mail domains
# EMAIL_DOMAIN_BLACKLIST=example1.com|example2.de|etc
# Only allow registrations with the following e-mail domains
# EMAIL_DOMAIN_WHITELIST=example1.com|example2.de|etc
# Optionally change default language
DEFAULT_LOCALE=ja
# E-mail configuration
# Note: Mailgun and SparkPost (https://sparkpo.st/smtp) each have good free tiers
# If you want to use an SMTP server without authentication (e.g local Postfix relay)
# then set SMTP_AUTH_METHOD to 'none' and *comment* SMTP_LOGIN and SMTP_PASSWORD.
# Leaving them blank is not enough for authentication method 'none'.
SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
SMTP_OPENSSL_VERIFY_MODE=none
SMTP_LOGIN=【自分のメールアドレス※ユーザ登録時の送信元になる】
SMTP_PASSWORD=【Gmailのパスワード】
SMTP_FROM_ADDRESS=【自分のメールアドレス※ユーザ登録時の送信元になる】
SMTP_DOMAIN=gmail.com
#SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail
#SMTP_AUTH_METHOD=plain
#SMTP_CA_FILE=/etc/ssl/certs/ca-certificates.crt
#SMTP_OPENSSL_VERIFY_MODE=peer
#SMTP_ENABLE_STARTTLS_AUTO=true
# Optional user upload path and URL (images, avatars). Default is :rails_root/public/system. If you set this variable, you are responsible for making your HTTP server (eg. nginx) serve these files.
# PAPERCLIP_ROOT_PATH=/var/lib/mastodon/public-system
# PAPERCLIP_ROOT_URL=/system
# Optional asset host for multi-server setups
# CDN_HOST=assets.example.com
# S3 (optional)
# S3_ENABLED=true
# S3_BUCKET=
# AWS_ACCESS_KEY_ID=
# AWS_SECRET_ACCESS_KEY=
# S3_REGION=
# S3_PROTOCOL=http
# S3_HOSTNAME=192.168.1.123:9000
# S3 (Minio Config (optional) Please check Minio instance for details)
# S3_ENABLED=true
# S3_BUCKET=
# AWS_ACCESS_KEY_ID=
# AWS_SECRET_ACCESS_KEY=
# S3_REGION=
# S3_PROTOCOL=https
# S3_HOSTNAME=
# S3_ENDPOINT=
# S3_SIGNATURE_VERSION=
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
# S3_CLOUDFRONT_HOST=
# Streaming API integration
# STREAMING_API_BASE_URL=
# Advanced settings
# If you need to use pgBouncer, you need to disable prepared statements:
# PREPARED_STATEMENTS=false
# Cluster number setting for streaming API server.
# If you comment out following line, cluster number will be `numOfCpuCores - 1`.
STREAMING_CLUSTER_NUM=1
4.2. Mastodonのdocker-compose.ymlを編集
$ sudo vi docker-compose.yml
ファイルの内容は以下の通り。
version: '2'
services:
nginx:
image: nginx:1.11.10-alpine
container_name: mstdn-nginx
ports:
- "9090:9090"
restart: always
tty: false
env_file: .env.production
links:
- web
- streaming
volumes:
- ./setting/nginx/conf.d:/etc/nginx/conf.d:ro
- ./setting/nginx/conf:/etc/nginx/conf:ro
volumes_from:
- container:proxy-nginx
networks:
- front
- back-mstdn
db:
restart: always
image: postgres:alpine
container_name: mstdn-db
volumes:
- ./postgres:/var/lib/postgresql/data
networks:
- back-mstdn
redis:
restart: always
image: redis:alpine
container_name: mstdn-redis
volumes:
- ./redis:/data
networks:
- back-mstdn
web:
restart: always
build: .
image: gargron/mastodon
container_name: mstdn-web
env_file: .env.production
command: bundle exec rails s -p 3000 -b '0.0.0.0'
ports:
- "3000:3000"
depends_on:
- db
- redis
volumes:
- ./public/assets:/mastodon/public/assets
- ./public/system:/mastodon/public/system
networks:
- back-mstdn
streaming:
restart: always
build: .
image: gargron/mastodon
container_name: mstdn-streaming
env_file: .env.production
command: npm run start
ports:
- "4000:4000"
depends_on:
- db
- redis
networks:
- back-mstdn
sidekiq:
restart: always
build: .
image: gargron/mastodon
container_name: mstdn-sidekick
env_file: .env.production
command: bundle exec sidekiq -q default -q mailers -q pull -q push
depends_on:
- db
- redis
volumes:
- ./public/system:/mastodon/public/system
networks:
- back-mstdn
networks:
front:
external: true
back-mstdn:
external: true
4.3. Nginxの設定ファイルを新規作成
ディレクトリを作成して、ファイルを編集する。
$ sudo mkdir -p setting/nginx/conf.d
$ sudo vi setting/nginx/conf.d/default.conf
ファイルの内容は以下の通り。
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 9090 ssl;
server_name 【自分のドメイン】;
ssl_protocols TLSv1.2;
ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_ecdh_curve prime256v1;
ssl_certificate /etc/nginx/certs/【自分のドメイン】/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/【自分のドメイン】/key.pem;
ssl_dhparam /etc/nginx/certs/dhparam.pem;
keepalive_timeout 70;
sendfile on;
client_max_body_size 0;
root 【mastodon配下の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";
add_header Content-Security-Policy "style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'self'; img-src data: https:; media-src data: https:; connect-src 'self' wss://【自分のドメイン】; upgrade-insecure-requests";
location / {
try_files $uri @proxy;
}
location ~ ^/(assets|system/media_attachments/files|system/accounts/avatars) {
add_header Cache-Control "public, max-age=31536000, immutable";
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://web: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://streaming: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;
}
5. Mastodonの起動
5.1 データベースのマイグレーション
$ docker-compose run --rm web rails db:migrate
5.2. アセットプリコンパイルの実行
$ docker-compose run --rm web rails assets:precompile
5.3. Mastodonの起動
$ docker-compose up -d
#起動後のプロセスやログを確認する場合
以下のコマンドを実行する。
$ docker-compose ps
$ docker-compose logs -f
6. 起動後
6.1. 起動確認
自分のドメインにアクセスして、接続出来るか確認。
サインアップの画面が表示されれば成功。
もし、「we're sorry, but something went wrong」というメッセージが出るようだったら、データベースのマイグレーションが出来ていない可能性があるので、再度コマンドを実行すると、たぶん動きます。
6.2. 管理者登録
アクセスした画面からサインアップを行った後、以下のコマンドを実行して
管理者に登録します。
$ docker-compose run --rm web rails mastodon:make_admin USERNAME=【登録ユーザー名】
あとがき
Mastodonは、dockerを学ぶにはとてもよい題材だと感じました。
今回、初めてDockerを使ったのですが、それでもうっすらと概要を理解できました。