« ^ »

docker-composeでlocalにMastodonの環境を構築する

所要時間: 約 5分

使用しているツール/サービス

  • Git
  • GitHub
  • Docker
  • docker-compose
  • Nginx

Mastodonのsource codeをcloneする

ソースコードをGitHubから取得します。

git clone --depth 1 [email protected]:tootsuite/mastodon.git

取得したソースコードのディレクトリに移動します。

cd mastodon

SSL/TLSで使用する自己証明書を生成

SSL/TLSでリクエストを受け入れられるように自己証明書を作成します。 まずは証明書を配置するディレクトリを作ります。

mkdir -p ./nginx/cert

作成したディレクトリに移動しておきます。

cd ./nginx/cert

秘密鍵とサーバー署名書(自己証明書)の作成

openssl req -x509 -out localhost.crt -keyout localhost.key -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' -extensions EXT -config <(printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")

ファイルを確認すると秘密鍵とサーバー証明書が作成されています。

ls
localhost.crt
localhost.key

参考: https://letsencrypt.org/docs/certificates-for-localhost/

完了したらmastodonのリポジトリの一番上のディレクトリに戻っておきます。

cd ../../

Nginxの設定ファイルを追加

先ほど作成した証明書をNginxで利用するために、Nginxの設定ファイルを作成します。 まずはNginxの設定ファイルを配置するディレクトリを作ります。

mkdir -p ./nginx/conf.d

エディタでnginx/conf.d/default.confを開いて次をコピー&ペーストして保存します。

nginx/conf.d/default.conf::

map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

server {
  listen 80;
  listen [::]:80;
  server_name localhost;
  root /home/mastodon/live/public;
  # Useful for Let's Encrypt
  location /.well-known/acme-challenge/ { allow all; }
  location / { return 301 https://$host$request_uri; }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name example.com;

  ssl_protocols TLSv1.2;
  ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;

  ssl_certificate     /etc/letsencrypt/live/localhost/localhost.crt;
  ssl_certificate_key /etc/letsencrypt/live/localhost/localhost.key;

  keepalive_timeout    70;
  sendfile             on;
  client_max_body_size 80m;

  root /home/mastodon/live/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";

  location / {
    try_files $uri @proxy;
  }

  location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
    add_header Cache-Control "public, max-age=31536000, immutable";
    try_files $uri @proxy;
  }

  location /sw.js {
    add_header Cache-Control "public, max-age=0";
    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;
}

docker-composeでNginxを動作させる設定を追加

docker-compose.ymlというファイルがdocker-composeが読み込む設定ファイルです。 MastodonはSSL/TLSでの接続にリダイレクトする設定が有効になっているので今回はNginxを使ってSSL/TLS接続をできるようにします。 先ほどSSL/TLSで必要な秘密鍵とサーバー証明書は作成しました。

docker-compose.ymlを開いて次のコードを services: と記述されている次の行に挿入します。

docker-compose.yml::

#
  nginx:
    image: nginx
    networks:
      - external_network
      - internal_network
    ports:
      - "localhost:443:443"
    depends_on:
      - db
      - redis
      - web
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/cert:/etc/letsencrypt/live/localhost

この設定はdocker-composeでNginxを起動させる設定です。

image: では使用するDocker Imageを指定しています。今回は公式のNginxのイメージを使用しています。 https://hub.docker.com/_/nginx/

networks: ではこのNginxが使用できるネットワークを指定しています。Mastodonのdocker-composeの設定では2つのネットワークが用意されています。

  • external_network
  • internal_network

external_networkは外部からの接続用のネットワークです。ブラウザでアクセスするとこのネットワークを介してリクエストが送受信されます。 internal_networkは内部用のネットワークです。このネットワークはdocker-composeで起動しているコンテナ間の通信に利用されます。例えばMastodonとPostgreSQLの通信はこの内部用のネットワークを経由します。

ports: は外部からの接続を受け付けるポート番号を設定しています。127.0.0.1というのはループバックアドレスです。

depends_on: は起動する順番の依存関係を指定しています。今回の場合、db、redis、webが起動した後にnginxが起動するように設定しています。

volumes: は起動したコンテナにマウントするディレクトリを指定しています。今回は起動したNginxのコンテナで設定ファイルと証明書を直接読み込ませたいのでマウントの指定をしています。

  • localの./nginx/conf.dのディレクトリが、コンテナの/etc/nginx/conf.dのディレクトリにマウントされる
  • localの./nginx/certのディレクトリが、コンテナの/etc/letsencrypt/live/example.comのディレクトリにマウントされる

./nginx/conf.dにはNginxの設定ファイルが入ります。 ./nginx/certにはNginxが使うサーバ証明書と秘密鍵が入ります。

ループバックアドレス

ループバックアドレスとは、ネットワークカードなどに割り当てられた特殊なIPアドレスで、そのコンピュータ自身を示すIPアドレスのこと。 http://e-words.jp/w/%E3%83%AB%E3%83%BC%E3%83%97%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9.html

環境変数設定ファイルを設定

設定ファイルのサンプルが.env.production.sampleという名前で用意されています。そのファイルを.env.productionという名前でコピーします。

cp .env.production.sample .env.production

.env.productionはdocker-compose.ymlの中で読み込むように設定されています。

docker-compose.yml::

  web:
    build: .
    image: tootsuite/mastodon
    restart: always
    env_file: .env.production  # <- ここで環境変数として読み込むように設定している
    command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000 -b '0.0.0.0'"
    networks:
      - external_network
      - internal_network

この中にはデータベースへの接続情報やホスト名などアプリケーションが使うための設定が記述されています。

環境変数とは

> 環境変数(かんきょうへんすう、英語: environment variable)はオペレーティングシステム (OS) が提供するデータ共有機能の一つ。OS上で動作するタスク(プロセス)がデータを共有するための仕組みである。特にタスクに対して外部からデータを与え、タスクの挙動・設定を変更するために用いる。

https://ja.wikipedia.org/wiki/%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0

今設定されている環境変数はenvコマンドで確認できます。

アプリケーションシークレットを設定する

アプリケーションが使用する鍵を3つ作ります。

docker-compose run --rm web rake secret
0b2b4e6fcf520e9bb441733085bcca5cc47bade0ec5cc2bd620f579ca7dccfb6bd2bbe4b788d330aeb08835a4d24befc321c8f25aa2fb6336fb185d8b9875411
docker-compose run --rm web rake secret
4432a62896755b02c113e0ed354614362e908301d84ab76df1673d4ce63325fe650cf20f733cb084e6c4e5c8f5bfcbdd5b84c73b552995bdca93294657d0f788
docker-compose run --rm web rake secret
486a845559f825060dc45ca1786fe1b419f31567254e0cf82393635c6d7935607a4ed63e80ba0a7ca0ddec5cd8582e43742ef23d2494acb835c30cc3e6772891

生成した値は.env.productionに設定します。

.env.production::

PAPERCLIP_SECRET=0b2b4e6fcf520e9bb441733085bcca5cc47bade0ec5cc2bd620f579ca7dccfb6bd2bbe4b788d330aeb08835a4d24befc321c8f25aa2fb6336fb185d8b9875411
SECRET_KEY_BASE=4432a62896755b02c113e0ed354614362e908301d84ab76df1673d4ce63325fe650cf20f733cb084e6c4e5c8f5bfcbdd5b84c73b552995bdca93294657d0f788
OTP_SECRET=486a845559f825060dc45ca1786fe1b419f31567254e0cf82393635c6d7935607a4ed63e80ba0a7ca0ddec5cd8582e43742ef23d2494acb835c30cc3e6772891

データベースのマイグレーション

マイグレーションを実行します。

docker-compose run --rm web rake db:migrate

アセットのプリコンパイル

docker-compose run --rm web rake assets:precompile

起動

docker-compose up

起動したらブラウザで https://localhost にアクセスします。

Adminユーザーの作成

以下のコマンドでAdminユーザーを作成します。

docker-compose run --rm web bin/tootctl accounts create alice --email [email protected] --confirmed --role admin

次のようにパスワードが出力されます。

Starting mastodon_redis_1 ...
Starting mastodon_db_1    ...
OK
New password: e4cedc757ef111da639ce5c7ed8753ff