Edited at

DockerでMastodonのインスタンスを立てる。とりあえずメールサーバーはホストOSで。

More than 1 year has passed since last update.

VPSでMastodonのインスタンスを立ち上げてみました。

Qiitaの記事を参考に構築したのですが一部想定どおりに動作しなかったので他のサイトを参考に変更しました。

メールの配信は、とりあえずホストOS上にPostfixを構築してSMTP認証なしで行っています。


ネットワークを作成する

メールの配信はホストOS上のPostfixで行い、かつ、Postfixの構築を簡単にするためにSMTP認証なしにします。

ホストOSのPostfixから見るとコンテナ上で動作するMastodonは他サーバーで動作しているように見えるので、サブネットを指定してDockerのネットワークを作成してPostfixのmynetworksに設定します。

リバースプロキシとWebサーバー間のネットワークを172.20.0.0/16、Mastodon内のネットワークを172.21.0.0/16とします。

docker network create --driver bridge --subnet 172.20.0.0/16 front

docker network create --driver bridge --subnet 172.21.0.0/16 mstdn


リバースプロキシの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

letsencrypt-nginx-proxy-companionがLet's Encryptを使ったSSL証明書の発行や更新してくれます。

発行されたSSL証明書などは、docker-compose.ymlと同じ階層のcertsディレクトリ以下に保存されます。

proxyのdocker-compose.ymlのあるディレクトリで

docker-compose build

docker-compose up -d

で、proxyの各コンテナをビルドして起動します。


Mastodonのdocker-compose.ymlを編集

Mastodonのリポジトリをcloneして、docker-compose.ymlを編集します。


  1. Nginxコンテナを追加する

  2. 画像等をNginxで返すようにするためNginxのコンテナでassets,packs,systemをマウントする

  3. Nginxのポート番号は9091とする

  4. 各コンテナをmstdnネットワークで繋ぐ

  5. Nginxはリバースプロキシとやり取りするので、frontとmstdnの両方のネットワークに繋ぐ

  6. データを永続化するために、dbとredisのvolumesのコメントアウトを解除

  7. コンテナのTimeZoneをAsia/Tokyoにするために/etc/localtimeをマウントする

version: '2'

services:

nginx:
image: nginx:1.11.10-alpine
container_name: mstdn-nginx
ports:
- 9091:9091
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
- ./public/assets:/mastodon/public/assets
- ./public/packs:/maastodon/public/packs
- ./public/system:/mastodon/public/system
- /etc/localtime:/etc/localtime:ro

volumes_from:
- container:proxy-nginx
networks:
- front
- mstdn

db:
restart: always
image: postgres:alpine
container_name: mstdn-db
volumes:
- ./postgres:/var/lib/postgresql/data
- /etc/localtime:/etc/localtime:ro

networks:
- mstdn

redis:
restart: always
image: redis:alpine
container_name: mstdn-redis
volumes:
- ./redis:/data
-/etc/localtime:/etc/localtime:ro

networks:
- mstdn

app:
build: .
image: gargron/mastodon
container_name: mstdn-app
restart: always
env_file: .env.production
volumes:
- /etc/localtime:/etc/localtime:ro
networks:
- mstdn

web:
extends:
service: app
container_name: mstdn-web
restart: always
env_file: .env.production
command: bundle exec rails s -p 3000 -b '0.0.0.0'
depends_on:
- db
- redis
volumes:
- ./public/assets:/mastodon/public/assets
- ./public/packs:/mastodon/public/packs
- ./public/system:/mastodon/public/system
networks:
- mstdn

streaming:
extends:
service: app
container_name: mstdn-streaming
restart: always
env_file: .env.production
command: npm run start
depends_on:
- db
- redis
networks:
- mstdn

sidekiq:
extends:
service: app
container_name: mstdn-sidekiq
restart: always
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:
- mstdn

networks:
front:
external: true
mstdn:
external: true


mstdn-nginxコンテナのNginxの設定ファイルを追加

mastodonのdocker-compose.ymlがあるディレクトリにsetting/nginx/conf.d/default.confを作成します。

※sample.localは実際のサイトのドメインに置き換えてください。


default.conf

map $http_upgrade $connection_upgrade {

default upgrade;
'' close;
}

server {
listen 9091 ssl;
server_name mastodon.sample.local;

ssl_protocols TLSv1.2;
ssl_ciphers EECDH+AESGCM:EECDH+AES;
ssl_ecdh_curve prime256v1;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

ssl_certificate /etc/nginx/certs/mastodon.sample.local/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/mastodon.sample.local/key.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;

location / {
try_files $uri @proxy;
}

location ~ ^/(assets|system/media_attachments/files|system/accounts/avatars) {
add_header Cache-Control "public, max-age=31536000, immutable";
}

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;
}



.env.productionを編集

.env.production.sampleをコピー&リネームした、.env.productionを編集していきます。Mastodonの設定とリバースプロキシ用の環境変数も追記します。

smtpサーバーはホストOS上に構築したpostfixを使用するのでMastodon内のネットワークに指定したサブネット172.21.0.0/16の172.21.0.1を設定します。また、smtp認証はしないのでユーザー名とパスワードは設定しません。

編集するところを抜粋します。

# リバースプロキシ用の設定

VIRTUAL_HOST=mastodon.sample.local
VIRTUAL_PORT=9091
VIRTUAL_PROTO=https
LETSENCRYPT_HOST=mastodon.sample.local
LETSENCRYPT_EMAIL=mail@sample.local
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=mastodon.sample.local
LOCAL_HTTPS=true

# Use this only if you need to run mastodon on a different domain than the one u
sed for federation.
# You can read more about this option on https://github.com/tootsuite/documentat
ion/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 s
ecret` if you use docker compose)
PAPERCLIP_SECRET=`docker-compose run --rm web rake secret`を実行して出力された文字列を設定する
SECRET_KEY_BASE=`docker-compose run --rm web rake secret`を実行して出力された文字列を設定する
OTP_SECRET=`docker-compose run --rm web rake secret`を実行して出力された文字列を設定する


# Leaving them blank is not enough for authentication method 'none'.
SMTP_SERVER=172.21.0.1
SMTP_PORT=25
SMTP_LOGIN=
SMTP_PASSWORD=
SMTP_FROM_ADDRESS=mstdn@sample.local
#SMTP_DOMAIN= # defaults to LOCAL_DOMAIN
#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=none
SMTP_ENABLE_STARTTLS_AUTO=false


config/environments/production.rbの修正

.env.productionにSMTP_LOGINとSMTP_PASSWORDを設定していなくてもSMTPサーバーにuser_nameとpasswordを送信してエラーになるのでuser_nameとpasswordをコメントアウトします。

           ・

           ・
# E-mails
config.action_mailer.smtp_settings = {
:port => ENV['SMTP_PORT'],
:address => ENV['SMTP_SERVER'],
# :user_name => ENV['SMTP_LOGIN'],
# :password => ENV['SMTP_PASSWORD'],
:domain => ENV['SMTP_DOMAIN'] || config.x.local_domain,
:authentication => :plain,
}
           ・
           ・


Google Analyticsを導入します

Google Analyticsを導入しますを参照してGoogle Analyticsを導入します。


次回アップデートのために修正した「app/views/home/index.html.haml」をリポジトリに追加してコミットする。

git add app/views/home/index.html.haml

git commit -m "V1.4.1" ... とりあえず現在のバージョンをコメントにする。


Postfixの設定

main.cfを変更します。

1. mynetworksに172.21.0.0/16を追加します。

2. 受信先で迷惑メールに振り分けられないようにsmtpd_use_tlsとsmtp_use_tlsをyesにします。


# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_use_tls=yes


mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 172.0.0.0/8 172.21.0.0/16


SPFレコードの設定

受信先で迷惑メールに振り分けられないようにDNSにSPFレコードを設定します。

※xxx.xxx.xxx.xxxはホストOSのip4アドレス,yyyy:yyyy:yyyy:yyyy::yyyy:yyyyはホストOSのip6アドレスです。

sample.local.      IN TXT "v=spf1 +a:sample.local +ip4:xxx.xxx.xxx.xxx ip6:yyyy:yyyy:yyyy:yyyy::yyyy:yyyy +mx -all"

以上で設定は終了です。


mastodonをビルドしてデータベースを初期設定する

mastodonのdocker-compose.ymlのあるディレクトリで

docker-compose build

docker-compose run --rm web rails db:migrate
docker-compose run --rm web rails assets:precompile
docker-compose up -d

を実行することで、


  1. mastodonの各コンテナをビルド

  2. データベースを初期化

  3. アセットをプリコンパイル

  4. mastodonの各コンテナを起動

起動まで時間がかかりますので、ログを参照します。画面のスクロールが止まるまで待ちます。

docker-compose logs -f

ctrl-fで中断できます。


管理者ユーザーを設定する

管理者ユーザーとして使うユーザーを登録して、ログインした後に、管理者権限を設定する。

docker-compose run --rm web rails mastodon:make_admin USERNAME=管理者ユーザーとするユーザーID

ログインしてサイトの設定をします。


更新情報


mstdn-nginxコンテナのNginxの設定ファイルの誤りを訂正


default.conf

  location /api/v1/streaming {



proxy_pass http://web:4000;

proxy_pass http://streaming:4000;


次回アップデートのために修正した「app/views/home/index.html.haml」をリポジトリに追加してコミットする。

git add app/views/home/index.html.haml

git commit -m "V1.4.1" ... とりあえず現在のバージンをコメントにする。


参考にした情報