24. Mastodonサーバ構築 [さくらのVPS/CentOS7]

・Mastodon のインストール

Mastodon は サブディレクトリ環境では動作しないため、VirtualHostで対応する

#-- 変数に必要な値を代入
VHOST=mstdn.masdon.life
DOMAIN=masdon.life
#-- admin@masdon.life のパスワード
PASSWORD=********
IPV4=$(ip addr show eth0 | awk '/inet /{print $2}' | awk -F\/ '{print $1}' | head -1)
IPV6=$(ip addr show eth0 | awk '/inet6 /&&/global/{print $2}' | awk -F\/ '{print $1}')

#-- 正引きを追加
cat <<_EOL_>> /etc/nsd/zone/${DOMAIN}.zone
mstdn                   IN      A       ${IPV4}
mstdn                   IN      AAAA    ${IPV6}
_EOL_

#-- シリアル更新
vi /etc/nsd/zone/${ZONE}.zone

systemctl restart nsd

#-- 既存の TLS証明書に mstdn.masdon.life を追加
certbot -n certonly --webroot -w /var/www/html/http_root -d ${DOMAIN} -d ${VHOST} -m admin@${DOMAIN} --agree-tos --expand

systemctl reload postfix nginx

#-- Mastodon インストール
curl -sL https://rpm.nodesource.com/setup_10.x | bash -
yum install -y http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
yum install -y ImageMagick ffmpeg rubygem-redis authd nodejs {openssl,readline,zlib,libxml2,libxslt,protobuf,ffmpeg,libidn,libicu}-devel protobuf-compiler
npm install -g yarn

su - postgres -c "createuser --createdb mastodon"

useradd mastodon
SETUP=/home/mastodon/setup.sh

cat <<_EOL_> ${SETUP}
REPO=https://github.com/sstephenson
git clone \${REPO}/rbenv.git ~/.rbenv
echo 'export PATH="~/.rbenv/bin:/usr/pgsql-11/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
rbenv init - >> ~/.bash_profile
source ~/.bash_profile
git clone \${REPO}/ruby-build.git ~/.rbenv/plugins/ruby-build
git clone https://github.com/tootsuite/mastodon.git live
cd live
git checkout \$(git tag|grep -v rc|tail -1)
cd ..
RV=\$(cat live/.ruby-version)
rbenv install \${RV}
rbenv global \${RV}
rbenv rehash
cd live
#-- エラーとなったのでバージョンを指定
# gem install bundler
gem install bundler 1.17.3
bundle install --deployment --without development test

yarn install --pure-lockfile
cp .env.production{.sample,}
export RAILS_ENV=production SAFETY_ASSURED=1
SKB=\$(bundle exec rake secret)
PS=\$(bundle exec rake secret)
OS=\$(bundle exec rake secret)
sed -i -e "s/_HOST=[rd].*/_HOST=localhost/" \
-e "s/=postgres$/=mastodon/" \
-e "s/^LOCAL_DOMAIN.*/LOCAL_DOMAIN=${VHOST}/" \
-e "s/^LOCAL_HTTPS.*/LOCAL_HTTPS=true/" \
-e "s/^SMTP_SERVER.*/SMTP_SERVER=${DOMAIN}/" \
-e "s/^SMTP_PORT=587/SMTP_PORT=465/" \
-e "s/^SMTP_LOGIN/SMTP_LOGIN=admin@${DOMAIN}/" \
-e "s/^SMTP_PASSWORD/SMTP_PASSWORD=${PASSWORD}/" \
-e "s/^#SMTP_AUTH_METHOD.*/SMTP_AUTH_METHOD=plain/" \
-e "s/^#SMTP_TLS=true/SMTP_TLS=true/" \
-e "s/^SMTP_FROM_ADDRESS.*/SMTP_FROM_ADDRESS=admin@${DOMAIN}/" \
-e "s/^SECRET_KEY_BASE=/SECRET_KEY_BASE=\${SKB}/" \
-e "s/^OTP_SECRET=/OTP_SECRET=\${OS}/" .env.production

export \$(bundle exec rake mastodon:webpush:generate_vapid_key)
sed -i -e "s/^VAPID_PRIVATE_KEY=/VAPID_PRIVATE_KEY=\${VAPID_PRIVATE_KEY}/" \
-e "s/^VAPID_PUBLIC_KEY=/VAPID_PUBLIC_KEY=\${VAPID_PUBLIC_KEY}/" .env.production

bundle exec rails db:setup
bundle exec rails assets:precompile
_EOL_

chmod 755 ${SETUP}
chown mastodon. ${SETUP}
su - mastodon -c "/bin/bash ${SETUP}"

chmod 770 /home/mastodon
usermod -aG mastodon nginx

cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/
systemctl enable mastodon-{web,sidekiq,streaming}
systemctl start mastodon-{web,sidekiq,streaming}

cat <<'_EOL_'>/etc/nginx/conf.d/${VHOST}.conf
map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

proxy_cache_path /var/cache/nginx_mastodon levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;

server {
  listen 80;
  listen [::]:80;
  server_name _VHOST_;
  root /home/mastodon/live/public;
  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 _VHOST_;

  include /etc/nginx/default.d/_DOMAIN__ssl.conf;
  access_log /var/log/nginx/_VHOST__access.log main;
  error_log  /var/log/nginx/_VHOST__error.log  error;
  server_tokens off;
  charset     utf-8;

  ssl_session_cache shared:WEB:10m;
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
  ssl_stapling on ;
  ssl_stapling_verify on ;

  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";
    add_header Strict-Transport-Security "max-age=31536000";
    try_files $uri @proxy;
  }

  location /sw.js {
    add_header Cache-Control "public, max-age=0";
    add_header Strict-Transport-Security "max-age=31536000";
    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 on;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    proxy_cache CACHE;
    proxy_cache_valid 200 7d;
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    add_header X-Cached $upstream_cache_status;
    add_header Strict-Transport-Security "max-age=31536000";

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

sed -i -e "s/_DOMAIN_/${DOMAIN}/" \
       -e "s/_VHOST_/${VHOST}/" /etc/nginx/conf.d/${VHOST}.conf

systemctl start nginx