Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
11
Help us understand the problem. What is going on with this article?
@gorillaimo

Ubuntu16.04にDockerでMastodonインスタンスを立てる

More than 3 years have passed since last update.

はじめに

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の内容は以下の通り。
これはどんな環境でも変わりはなさそうです。

~/proxy/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

ファイルの内容は以下の通り。
【】内を自身の環境に合わせて編集して下さい。

~/apps/mastodon/.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

ファイルの内容は以下の通り。

~/apps/mastodon/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

ファイルの内容は以下の通り。

~/apps/mastodon/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を使ったのですが、それでもうっすらと概要を理解できました。

11
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
gorillaimo
SE 兼 通信大学生(経済学部)です。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
11
Help us understand the problem. What is going on with this article?