2017年5月5日金曜日

Mastodonのアップデート

マストドンは頻繁に更新されています。
せっかく自分専用インスタンスを立てたのだから、最新版を
追いかけたくなるのが人情ってもんですw
ということで、アップデートの手順です。
su - mastodon

cd live

git fetch

git checkout $(git tag | sed -e "/rc/d" | tail -n 1)

bundle install

yarn install

RAILS_ENV=production bundle exec rails db:migrate

RAILS_ENV=production bundle exec rails assets:precompile

sudo pm2 restart mastodon-*.service
あとは正常に動作しているか確認すれば終了です!

Mastodonに管理アカウントを設定する。

マストドンのインスタンスを立ち上げてみてはものの、
このままの状態では誰も管理アカウントが居ない状態になっています。
なので自分のアカウントを追加した状態で、
su - mastodon

cd live

RAILS_ENV=production bundle exec rails mastodon:make_admin USERNAME=#自分#
を実行。
めでたく管理者アカウントに昇格できました!

Mastodonのサーバ通信切れを予防する

無事に自分用マストドンインスタンスを開設できたわけですが、
一つ重要な設定を忘れていることに気がつきました。
つーかちゃんと公式マニュアル見ろって話ですw

で、参考にしたサイトはこちら。
Qiita:Mastodonのサーバ間通信が切れた場合のリカバリ

crontab -eで編集します。
crontab -e
通常であれば、
cd /home/mastodon/live && RAILS_ENV=production bundle exec rake mastodon:daily
をcronに追加すればいいようなのですが、
実はこれ、リソースの少ないサーバでは落ちるという事例があるようで、
今の契約はVPSの最安プラン(512MBプラン)という貧弱なものなので、
安全策でこのような設定にしてみました。
MAILTO=root
10 4,16 * * * /bin/bash -l -c 'cd /home/mastodon/live && RAILS_ENV=production bundle exec rake mastodon:feeds:clear'
15 4,16 * * * /bin/bash -l -c 'cd /home/mastodon/live && RAILS_ENV=production bundle exec rake mastodon:media:clear'
20 4,16 * * * /bin/bash -l -c 'cd /home/mastodon/live && RAILS_ENV=production bundle exec rake mastodon:users:clear'
25 4,16 * * * /bin/bash -l -c 'cd /home/mastodon/live && RAILS_ENV=production bundle exec rake mastodon:push:refresh'
とりあえずコレで一安心ですw

Mastodonインスタンスを立ててみる

今流行のマストドンインスタンスを立ててみました。
Dockerを使えば簡単に導入できるようですが、今回はあえて手動でやってみました。

下記手順の前提条件:
・さくらのVPS(標準OS:Ubuntu16.04)
・ドメイン取得済み[mstdn.imoimo.xyz](今回はお名前.comを利用させて頂きました。)
・諦めない心


参考サイト:
公式マニュアル
Qiita:さくらのVPSで自分の Mastodon サーバを最速でつくる方法
稲葉サーバーデザイン:Let’s EncryptによるSSLサーバー証明書の自動更新設定

443ポート、動作確認用ポートを開放するために、iptablesの設定を編集
sudo vi /etc/iptables/iptables.rules
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT

#さくらのVPS標準OSはデフォルトで22番ポート(ssh)だけが開放されている。
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

#httpsポートを追加。
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

#Mastodon動作確認用でこちらも。後で削除する。
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3000 -j ACCEPT

-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

iptablesの設定内容を反映
sudo iptables-restore < /etc/iptables/iptables.rules

mastodonユーザを作成し、mastodonユーザでログイン
sudo adduser -ingroup sudo mastodon

su - mastodon

依存関係のあるパッケージなどをインストール
sudo apt-get install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev nodejs file git curl

curl -sL https://deb.nodesource.com/setup_4.x | sudo bash -

sudo apt-get install nodejs

sudo npm install -g yarn

Redisのインストール
sudo apt-get install redis-server redis-tools

Postgresのインストール
sudo apt-get install postgresql postgresql-contrib

sudo postgresql-setup initdb

sudo systemctl start postgresql

sudo systemctl enable postgresql

Postgresにmastodonユーザを作成
sudo su - postgres

psql

CREATE USER mastodon CREATEDB;

\q

Postgresのおまじない(ローカルユーザからはパスワード要求しない設定っぽい)
sudo sed -i '/^local.*postgres.*peer$/a host    all     all     127.0.0.1/32    ident' /etc/postgresql/9.?/main/pg_hba.conf

identのインストール
sudo apt-get install pidentd

sudo systemctl enable pidentd

sudo systemctl start pidentd

sudo systemctl restart postgresql

Rbenvのインストール
git clone https://github.com/rbenv/rbenv.git ~/.rbenv

echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile

echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

~/.rbenv/bin/rbenv init

source ~/.bash_profile

rbenvが無事インストールされているか確認
exit

su - mastodon

type rbenv

rbenv-build のインストール
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

rubyのインストール
rbenv install 2.4.1

rbenv rehash

rbenv global 2.4.1

rubyが正常にインストールされたか確認
ruby -v

Mastodon本体を取得
mastodonユーザのHomeにliveディレクトリを作成し、そこに格納。
cd ~

git clone https://github.com/tootsuite/mastodon.git live

cd live

git checkout $(git tag | tail -n 1)

依存パッケージ(RubyGems)のインストール
gem install bundler

bundle install --deployment --without development test

yarn install

rakeのシークレットキーを生成(3回実行し、3個生成しておく)
rake secret

.env.productionの編集
cp .env.production.sample .env.production

vi .env.production
#RdisとPostgresは同一サーバに構築したので、そのように設定。
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
DB_HOST=127.0.0.1
DB_USER=mastodon
DB_NAME=mastodon
DB_PASS=
DB_PORT=5432

#Mastodonで使うドメイン名を設定
LOCAL_DOMAIN=mstdn.imoimo.xyz
#動作確認のため、falseに設定しておく(あとでtrueに戻す)
LOCAL_HTTPS=false

#それぞれrake secretで作成したシークレットキーを設定する。
PAPERCLIP_SECRET=#シークレットキー#
SECRET_KEY_BASE=#シークレットキー#
OTP_SECRET=#シークレットキー#

#とりあえずGmailアカウントを作ってそれを使うことにした。
SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
SMTP_LOGIN=mstdn.imoimo@gmail.com
SMTP_PASSWORD=#GMailのログインパスワード#
SMTP_FROM_ADDRESS=mstdn.imoimo@gmail.com
SMTP_OPENSSL_VERIFY_MODE=none
SMTP_DOMAIN=gmail.com

Mastodonのビルド
RAILS_ENV=production bundle exec rails db:setup

RAILS_ENV=production bundle exec rails assets:precompile

systemdの設定(自動起動)
sudo vi /etc/systemd/system/mastodon-web.service
[Unit]
Description=mastodon-web
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="PORT=3000"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target
sudo vi /etc/systemd/system/mastodon-sidekiq.service
[Unit]
Description=mastodon-sidekiq
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="DB_POOL=5"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target
sudo vi /etc/systemd/system/mastodon-streaming.service
[Unit]
Description=mastodon-streaming
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="NODE_ENV=production"
Environment="PORT=4000"
ExecStart=/usr/bin/npm run start
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target

Mastodonサービスを起動
sudo systemctl enable /etc/systemd/system/mastodon-*.service

sudo systemctl start mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service

とりあえず動作確認
これでマストドンのAboutページが出れば成功!
http://<サーバのIPアドレス>:3000

Let's Encrypt(certbot)のインストール
cd /usr/local

sudo git clone https://github.com/certbot/certbot

certbotが正常にインストールされたことを確認
certbotのヘルプが表示されればOK。
cd /user/local/certbot

sudo ./certbot-auto --help

証明書を取得する
certbot-auto certonly --standalone -d mstdn.imoimo.xyz -m mstdn.imoimo@gmail.com --agree-tos -n

証明書を自動更新するためのスクリプトを作成する
sudo vi /usr/local/certbot/certbot.sh
#!/bin/sh
#
LOGFILE=/var/log/update_sslcert.log
COMMAND=/usr/local/certbot/certbot-auto
WEBSERVER_STOP_COMMAND="systemctl stop nginx"
WEBSERVER_START_COMMAND="systemctl start nginx"

MAILTO=root

echo "===== Update SSL Cert =====" >> ${LOGFILE}
echo "`date` Update SSL Cert start" >> ${LOGFILE}

${COMMAND} renew \
  --pre-hook "$WEBSERVER_STOP_COMMAND" \
  --post-hook "$WEBSERVER_START_COMMAND" \
  --non-interactive >> ${LOGFILE}
STATUS=$?

if [ "$STATUS" != 0 ]; then
    echo "Update SSL Cert failed" >> ${LOGFILE}
    echo "Update SSL Cert failed" |\
    mail -s "Update SSL Cert in `hostname`" ${MAILTO}
fi

echo "`date` Update SSL Cert end" >> ${LOGFILE}

# EOF

先ほど作成したスクリプトをcronに追加する
sudo crontab -e
50 4 * * 4 /usr/local/certbot/certbot.sh > /dev/null

Nginx(httpsプロキシとして使用)のインストール
sudo apt-get install nginx

Nginxの設定
公式ドキュメントのサンプルをそのまま流用。
sudo vi /etc/nginx/conf.d/mastodon_proxy.conf
map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

server {
  listen 80;
  listen [::]:80;
  server_name mstdn.imoimo.xyz;
  # Useful for Let's Encrypt
  location /.well-known/acme-challenge/ { allow all; }
  location / { return 301 https://$host$request_uri; }
}

server {
  listen 443 ssl;
  listen [::]:443 ssl;
  server_name mstdn.imoimo.xyz;

  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/mstdn.imoimo.xyz/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/mstdn.imoimo.xyz/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 /assets {
    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://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;
}

.env.productionのLOCAL_HTTPSをtrueに変更する
vi ~/live/.env.production

iptablesで開けていた3000番ポートを閉じて、設定を反映
sudo vi /etc/iptables/iptables.rules

sudo iptables-restore < /etc/iptables/iptables.rules

MastodonとNginxの再起動
sudo systemctl restart mastodon-sidekiq.service

sudo systemctl restart mastodon-web

sudo systemctl restart nginx

最終動作確認
https://mstdn.imoimo.xyz
コレで無事マストドンが表示されれば成功!
ハマり所はLet's Encryptとポート開放の辺りでしょうか・・・
ぶっちゃけ結構大変でした・・・w