Mastodon サーバ引っ越しメモ

さくらのクラウドから VPS に引っ越した時のメモです。

環境

  • 現行
    • さくらのクラウド
      • Mastodon サーバ (CPU 1Core/RAM 4GB/HDD 40GB)
      • ネームサーバ (レジストラはお名前ドットコム)
    • AWS RDS (t2.micro)
    • AWS S3
  • 移行後
    • カゴヤ VPS
      • Mastodon サーバ (CPU 4Core/RAM 4GB/SSD 50GB)
      • PostgreSQL サーバ (CPU 2Core/RAM 2GB/SSD 50GB)
    • お名前ドットコムネームサーバ
    • AWS S3
    • Mailgun

手順

  • 移行後サーバ起動、設定
  • 現行停止
  • DNS 設定変更
  • Mailgun 設定
  • DB 移行
  • Redis 移行
  • アプリ設定
  • アプリ起動

セキュリティグループ、ネットワーク作成

  • セキュリティグループ作成
    • Mastodon サーバ用
      • ポート 80, 443 を許可
      • ポート 22 を自分の IP アドレスのみ許可
    • DB サーバ用
      • ポート 22 を自分の IP アドレスのみ許可
  • ネットワーク作成

Mastodon サーバの起動

Ubuntu 16.04 で起動します。ユーザデータを使って以下を行います。

  • ホストネーム設定
  • Docker, docker-compose のインストール
  • ユーザ mastodon の追加
  • ローカルネットワーク設定
  • 再起動

ユーザデータ:

#!/bin/bash

# hostname
hostname 'theboss.tech'
echo $(hostname) > /etc/hostname
echo "127.0.0.1 $(hostname)" >> /etc/hosts

apt update -y
apt upgrade -y

apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
apt update -y
apt install docker-ce -y
systemctl enable docker
systemctl start docker
curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
curl -L https://raw.githubusercontent.com/docker/compose/1.19.0/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose

useradd -m -p $(perl -e 'print crypt("mastodon", "\$6\$salt");') -s /bin/bash mastodon
gpasswd -a mastodon sudo
mkdir /home/mastodon/.ssh

usermod -aG docker mastodon

mv /root/.ssh/authorized_keys /home/mastodon/.ssh/

chown -R mastodon:mastodon /home/mastodon/.ssh
chmod 700 /home/mastodon/.ssh
chmod 600 /home/mastodon/.ssh/authorized_keys

cp /etc/ssh/sshd_config{,.bk}
sed -i 's/PermitEmptyPasswords yes/PermitEmptyPasswords no/' /etc/ssh/sshd_config
sed -i 's/PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#AuthorizedKeysFile/AuthorizedKeysFile' /etc/ssh/sshd_config

# Network
cp /etc/network/interfaces{,.bk}
cat <<EOF >> /etc/network/interfaces
auto eth1
iface eth1 inet static
    address 172.16.1.1
    netmask 255.255.255.0
EOF

reboot

ローカルマシンで ~/.ssh/config に接続先を設定します。

Host kagoya
  HostName xxx.xxx.xxx.xxx
  User mastodon
  IdentityFile ~/.ssh/kagoya.pem
  ForwardAgent yes

ログイン後に以下を実行します。

# パスワード変更
passwd

sudo apt install tmux

# リポジトリ取得
git clone git@github.com:theboss/dotfiles.git ~/projects/dotfiles
projects/dotfiles/linktohome.sh

git clone git@github.com:theboss/mastodon.git

git config --global user.name 'theboss'
git config --global user.email 'luckybeastakatheboss@gmail.com'

PostgreSQL サーバの起動

OS は同じで、 Docker は使用せず PostgreSQL をインストールします。

DB を別サーバとしたのは性能の懸念から分けておこうという意図です。複数サーバを使う場合、本来なら Docker Swarm とか Kubernetes を使ったほうがよさそうですが、今回は学習が間に合わず断念しました。

ユーザデータ:

#!/bin/bash

# hostname
hostname 'db.theboss.tech'
echo $(hostname) > /etc/hostname
echo "127.0.0.1 $(hostname)" >> /etc/hosts

apt update -y
apt upgrade -y

echo 'deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main' > /etc/apt/sources.list.d/pgdg.list
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
apt update -y
apt install -y postgresql-9.6 postgresql-contrib-9.6

useradd -m -p $(perl -e 'print crypt("mastodon", "\$6\$salt");') -s /bin/bash mastodon
gpasswd -a mastodon sudo
mkdir /home/mastodon/.ssh

usermod -aG docker mastodon

mv /root/.ssh/authorized_keys /home/mastodon/.ssh/

chown -R mastodon:mastodon /home/mastodon/.ssh
chmod 700 /home/mastodon/.ssh
chmod 600 /home/mastodon/.ssh/authorized_keys

cp /etc/ssh/sshd_config{,.bk}
sed -i 's/PermitEmptyPasswords yes/PermitEmptyPasswords no/' /etc/ssh/sshd_config
sed -i 's/PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#AuthorizedKeysFile/AuthorizedKeysFile' /etc/ssh/sshd_config

# Network
cp /etc/network/interfaces{,.bk}
cat <<EOF >> /etc/network/interfaces
auto eth1
iface eth1 inet static
    address 172.16.1.2
    netmask 255.255.255.0
EOF

# postgresql
cp /etc/postgresql/9.6/main/postgresql.conf{,.bk}
sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '172.16.1.2'/" /etc/postgresql/9.6/main/postgresql.conf

cp /etc/postgresql/9.6/main/pg_hba.conf{,.bk}
echo 'host mastodon mastodon 172.16.1.1/24 password' >> /etc/postgresql/9.6/main/pg_hba.conf

reboot

同様に ~/.ssh/config に追記します。

Host kagoya-db
  HostName xxx.xxx.xxx.xxx
  User mastodon
  IdentityFile ~/.ssh/kagoya.pem
  ForwardAgent yes

ログイン後以下を実行します。

# パスワード変更
passwd

現行停止

さくらのクラウドのサーバの Mastodon サービスを停止します。

# Sakura server
sudo systemctl stop mastodon-{web,sidekiq-default,sidekiq-mailers,sidekiq-pull,sidekiq-push,streaming}

DNS 設定変更

さくらのクラウドからお名前ドットコムのネームサーバに変更し、新サーバの DNS レコードを登録します。

Mailgun 設定

Mailgun にドメイン登録を行い、指示に従って DNS レコード登録を行います。

Mailgun のドキュメントによると、ドメイン確認には 24~48 時間かかり、 48 時間以上経過しても変わらない場合 Check DNS Records Now ボタンを押せとありますが、レコード登録して数分後に押すとすぐ確認済みになりました。

DB 移行

PostgreSQL サーバから AWS RDS に接続し、ダンプを取得します。

  • PostgreSQL サーバから RDS に接続できるよう、 AWS のセキュリティグループ設定にて、インバウンド接続に IP アドレスを追加
  • RDS よりダンプファイルエクスポート
  • RDS の IP アドレス許可を削除
  • PostgreSQL サーバにダンプインポート
# PostgreSQL server

# 接続確認
psql -h mastodon.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U mastodon mastodon
# パスワードを入力
# 問題なければ \q で抜ける

# ダンプ取得
pg_dump -h mastodon.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -U mastodon mastodon -f /tmp/mastodon.dump

# DB 作成
sudo -u postgres psql

CREATE USER mastodon PASSWORD 'PASSWORD' CREATEDB;
CREATE DATABASE mastodon OWNER mastodon;
\q

# インポート
psql -f /tmp/mastodon.dump -U mastodon --dbname=mastodon

Mastodon サーバでコマンドを実行し、 PostgreSQL サーバに接続できることを確認します。 (こちらは postgres をインストールしていないため、 Docker で実行する。実行後、不要であれば docker rmi postgres:9.6-alpine で削除すること)

# Mastodon server
docker run -it --rm postgres:9.6-alpine psql -h 172.16.1.2 -U mastodon
# パスワードを入力
# 問題なければ \q で抜ける

Redis 移行

さくらのクラウドのサーバより、 redis のデータを取得します。

# Sakura server
redis-cli dbsize
redis-cli save
redis-cli lastsave
ls -l /var/lib/redis/dump.rdb

ローカルにダウンロードします。

# local
scp sakura:/var/lib/redis/dump.rdb .
scp dump.rdb dump.rdb kagoya:~/

新 Mastodon サーバは Docker 環境のため、 redis/ ディレクトリを作成し、そこに配置します。

# Mastodon server
mkdir ~/mastodon/redis
cp dump.rdb ~/mastodon/redis/dump.rdb

アプリ設定

docker-compose.ymlpostgres サービスをコメントアウトし、 https-portal サービスを追加しました。

https-portal は Let’s Encrypt の登録や自動更新が設定された nginx イメージです。 nginx 向けのコンフィグファイルを別途作成し nginx-conf/ に格納します。 (詳細は リポジトリ をご覧ください。)

# Mastodon server
cd ~/mastodon

# .env.production 作成
# (DB 接続先/ドメイン名/後述のシークレット/Mailgun/S3 など設定する)
cp .env.production.sample .env.production

# build
docker-compose build

# generate paperclip secrets
for i in {0..2}; do docker-compose run --rm web rake secret; done

# generate Web Push private/public key
docker-compose run --rm web rake mastodon:webpush:generate_vapid_key

アプリ起動

# Mastodon server
cd ~/mastodon

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

docker-compose up -d

# ログ確認
docker-compose logs -f

トラブルシュート

.env.production 変更後は restart ではなく up を実行すること

docker-compose restart は作成済みのコンテナを再起動するのみで、設定変更は反映されません。

設定変更後は、 docker-compose up -d を実行することで、コンテナ再作成が行われ、変更が反映されます。

コンテナの環境変数は docker-compose exec SERVICE env で確認できます (SERVICEweb などのサービス名) 。

参考: docker-compose up | Docker Documentation

DNS が反映されない

dig コマンドや curl コマンドでは接続できるものの、 Web ブラウザだと古い方にアクセスしてしまう状態になりました (chrome://net-internals/#dns からキャッシュをクリアしてみたが変化なし) が、しばらく待ったら正しく接続できるようになりました (TTL=3600 を超過したため?) 。

起動に時間がかかる

Mastodon 起動時の Updating permissions... という処理に数分かかっていましたが、 Docker のストレージドライバを overlay2 から aufs に変更すると解消するとのこと。

Qiita に解説記事があり、これに従い aufs に変更しました。

無料鯖(Ubuntu)でDocker使用のMastodonを1.4.1に上げようとしたら死んだ話 - Qiita

Mastodon リポジトリに Issue が上がっており、 2017 年 5 月時点の議論ですが内容をかいつまむと:

  • docker_entrypoint.sh で、単に chown -r するのではなく、 find ... | xargs chown としており、これが遅い。
  • chown の対象から /public/system を除外するために find コマンドを使う必要があり、こうしている。
  • 遅いのは Docker のストレージドライバである overlay2 の問題。 aufs を使っていると早い (数秒で終わる) 。
  • overlay2 は上記コマンドに限らず、性能全般に問題があるという意見も出ている。 overlay2 は aufs の後継のようだが、本番環境で使うべきではない、 Docker の公式ドキュメントにも「まだ歴史が浅いから注意して使え」と書かれている、とのこと。
  • OverlayFS は将来的に aufs より性能が向上する見通しではある。
  • Docker の edge version は overlay2 がデフォルトだが、 stable は aufs である。

実施したコマンドは以下の通りです。

# 存在しないことを確認
cat /proc/filesystems | grep aufs

sudo apt update
sudo apt install -y linux-image-extra-$(uname -r) linux-image-extra-virtual
sudo modprobe aufs

# 存在することを確認
cat /proc/filesystems | grep aufs

sudo vim /etc/docker/daemon.json
# 以下を記述
# {
#   "storage-driver": "aufs"
# }

# 再起動
sudo systemctl restart docker
sudo reboot

# 再起動後に docker-compose up (再度ビルドするため時間がかかることに注意)

IPv6 対応

まだできていません。そのうちやりたい…


See also