さくらVPSでmastodonのインスタンスを立てた(CentOS7)


はじめに

mastodonブーム?がきて1週間ほど経った。
いい機会なので、借りていたさくらVPSの8Gプランでインスタンスを立ててみました。dockerを使うので比較的作業は簡単で公開するためのメールサーバーは外部のものを使いました。
また立て終わったあとにまとめたものなので、間違っている部分があったらご指摘お願いします。

一応Apacheでも動かしてみました→ここ

環境(自分の環境例です)

  • さくらVPS 8G (CentOS7)
  • SSHやfirewallは設定済み
  • sudo権限持ちユーザー
  • メールサーバー(SparkPost)

必要なもの

  • docker
  • nginx
  • git
  • mastodon本体
  • let's encrypt(SSLの証明書)
  • ドメイン(お名前.comで取得)
  • SparkPost(外部のメールサーバー)

nginxとDocker関連のインストール

nginxとdockerのインストールと起動設定
自分のnginxのバージョンはnginx 1.12.0 dockerはDocker version 17.04.0-ceでした。

$ sudo yum install -y nginx docker
$ sudo systemctl enable docker

ユーザーをdockerグループに追加。

$ sudo usermod -aG docker ユーザー名

docker起動。

$ sudo systemctl start docker

次はdocker-composeのセットアップです。

$ sudo curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /bin/docker-compose
$ sudo chmod +x /bin/docker-compose

バージョン確認

$ docker version

Client:
 Version:      17.04.0-ce
 API version:  1.28
 Go version:   go1.7.5
 Git commit:   4845c56
 Built:        Mon Apr  3 18:01:50 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.04.0-ce
 API version:  1.28 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   4845c56
 Built:        Mon Apr  3 18:01:50 2017
 OS/Arch:      linux/amd64
 Experimental: false

mastodonの構築

まずは本体をcloneし .env.productionをコピーします。
任意の場所で

$ git clone https://github.com/tootsuite/mastodon.git
$ cd mastodon
$ cp .env.production.sample .env.production

以降、mastodonの中での作業になります。

docker-compose.yml

Docker Compose は mastodon にある docker-compose.yml を読み込み、一括してイメージの構築・ダウンロード・実行などを行います。

mastodonの中にある初期のdocker-compose.ymlのまま実行してしますとdbやredisのデータが吹っ飛んでします為 ボリューム機能を使ってホストにデータを保存するように編集します。

volumes の部分の # を削除します。

services:

  db:
    restart: always
    image: postgres:alpine
### Uncomment to enable DB persistance
    volumes:
      - ./postgres:/var/lib/postgresql/data

  redis:
    restart: always
    image: redis:alpine
### Uncomment to enable REDIS persistance
    volumes:
      - ./redis:/data

そして必要なイメージを引っ張ってきてbuildします。

$ docker-compose pull
$ docker-compose build

.env.production

設定ファイルの.env.productionを編集していきます。

$ vim .env.production

DB関連・ドメインの設定

# Service dependencies

REDIS_HOST=redis
REDIS_PORT=6379
DB_HOST=db
DB_USER=任意のユーザー名
DB_NAME=データベース名
DB_PASS=*********
DB_PORT=5432

# Federation

LOCAL_DOMAIN=取得したドメイン
LOCAL_HTTPS=true

DB関連の設定は下記に。任意のユーザー名、DB名、パスワードを設定しますが、後で実際に DB に設定しないといけないので参照できたほうがいい。

secret key の設定

secret keyを3つ取得します。以下のコマンドを3回実行します。

$ docker-compose run --rm web rake secret

ここで取得した3つのキーを.env.productionに記載します。

# Application secrets
# Generate each with the `rake secret` task (`docker-compose run --rm web rake secret` if you use     docker compose)

PAPERCLIP_SECRET=
SECRET_KEY_BASE=
OTP_SECRET=

メールサーバーの設定(SparkPost)

今回は外部サービスの「SparkPost」 を利用をしました。

まずアカウントを作成します。作成が完了しログインするとドメインを登録しろと言われるので登録します。
そうすると、API Key が発行されるので、これを間違いなく手元にメモしておきましょう。確実にメモして!!。忘れるとめんどいです。

Dashboard の ACCOUNT → SENDING DOMEINS にいくと settingtestボタンがあるのでsettingを選択すると DKIM Recordを指定されるので DNS レコードを登録します。

DNSの設定方法は調べてください。TypeはTXTです。

DNSの設定が終わったらtestを押し問題ないことを確認してください。
以下の画像のようになれば完了です。

問題なければ .env.productionのメールサーバー部分を編集します。

# 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.sparkpostmail.com
SMTP_PORT=587
SMTP_LOGIN=SMTP_Injection
SMTP_PASSWORD=[取得したAPI Key]
SMTP_FROM_ADDRESS=任意の名前@ドメイン.com
#SMTP_DOMAIN= # defaults to LOCAL_DOMAIN
#SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail
SMTP_AUTH_METHOD=plain
#SMTP_OPENSSL_VERIFY_MODE=peer
SMTP_ENABLE_STARTTLS_AUTO=true

SMTP_SERVERやSMTP_PORT、SMTP_LOGINなどの情報はSparkPostのこちらを参照

データベースの初期化とプリコンパイル

まずDBの設定をするために立ち上げます。

$ docker-compose up -d

コンテナが立ち上がったら、コンテナに入り DBの設定をします。

$ docker exec -it mastodon_db_1 bash

先程 .env.productionに記載したDB部分の情報を参考に、ユーザー、パスワード、データベース名を決めていきます。

# su - postgres
$ createuser -P ユーザー名
 Enter password for new role:パスワード入力
 Enter it again:再入力
$ createdb データベース名 -O ユーザー名
$ exit
# exit

コンテナから出たら初期化とプリコンパイルをします。まぁまぁ時間かかったかも?

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

そしてコンテナを再起動します。

$ docker stop $(docker ps -a -q) && docker-compose up -d

動作状況を確認します。

% docker-compose ps 

        Name                      Command               State                Ports
------------------------------------------------------------------------------------------------
mastodon_db_1          docker-entrypoint.sh postgres    Up      5432/tcp
mastodon_redis_1       docker-entrypoint.sh redis ...   Up      6379/tcp
mastodon_sidekiq_1     bundle exec sidekiq -q def ...   Up      3000/tcp, 4000/tcp
mastodon_streaming_1   npm run start                    Up      3000/tcp, 0.0.0.0:4000->4000/tcp
mastodon_web_1         bundle exec rails s -p 300 ...   Up      0.0.0.0:3000->3000/tcp, 4000/tcp

あとはnginxでmastodonを動かします。

nginxとSSL証明書の発行の設定

let's encrypt

let's encryptではOpenSSLが必要なのでインストールしておきましょう。

$ sudo yum install -y openssl mod_ssl

まず let's encrypt をcloneしてきて証明書を発行します。
cloneする場所は任意ですが自分は /opt にしてます。

$ cd /opt
$ sudo git clone https://github.com/letsencrypt/letsencrypt.git
$ cd letsencrypt

証明書の発行します。

$ ./letsencrypt-auto certonly --standalone -d ドメイン名

色々説明がでるのでそれ通りに進めてください。自分はすでに登録済みなのでどんな説明だったか覚えてません・・・。

こちらを参考にするといいと思います。

また証明書の期限は90日のため cronなどで自動更新を設定しておくと便利です。

証明書は/etc/letsencrypt/live/ドメイン名に作成されます。

nginxの設定

nginxのconfファイルは公式通りに設定しました。

参考 https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md

コピペです。

$ sudo vim /etc/nginx/conf.d/mastodon.conf
map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

server {
  listen 80;
  listen [::]:80;
  server_name ドメイン名;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl;
  listen [::]:443 ssl;
  server_name ドメイン名;

  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/letsencrypt/live/ドメイン名/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem;
  ssl_dhparam         /etc/ssl/certs/dhparam.pem;

  keepalive_timeout    70;
  sendfile             on;
  client_max_body_size 0;

  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 @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://127.0.0.1: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://localhost: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;
}

Mastodonインスタンスのルートディレクトリは、/home/mastodon/live/public です。

起動&確認

コンテナとnginxを再起動。

$ docker stop $(docker ps -a -q) && docker-compose up -d
$ sudo systemctl restart nginx

アクセスして、以下が出れば成功です。

念のため登録してちゃんとメールが届くか確認しておきましょう。

管理者権限の付与

管理者にしたいアカウントに権限を付与します。

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

以下の画像のように管理が追加されてれば完了です。

その他

  • インスタンスを立ち上げて身内で使う程度なら問題ないが色んな人に公開して運用するには大変だと思う。セキュリティやお金など。
  • 今後はセキュリティ対策やチューニングなどをしていく予定。
  • また、別のサーバーでdockerを使わずにインスタンスを立ち上げて遊んでみたい。
  • 1ヶ月位は遊んでみたいと思う。

参考

ありがとうございました。