CentOS 7: Mastodonインスタンスを立ち上げる

DockerやVagrantを使わずにCentOS 7上に直接Mastodonインスタンスを立ち上げる手順を記載します。

1 制限事項

  • 本記事はMastodon documentationProduction-guide.mdAlternatives.mdを参考にしています。
  • 本記事のMastodonインスタンスはMastodonの使い方やAPIを確かめることを目的にしたもので、実運用に耐えうるものではありません。
  • Mastodon、Redis、PostgreSQL、Apache、Postfixは全て同じマシンにインストールします。
  • 登録可能なメールアドレスは<user>@localhostのみです(Postfixでlocalhostのみへ送信できるようにしています)。複数のアカウントを登録するには、適時ローカルユーザを追加してメールアドレスを増やす必要があります。
  • アカウント登録後の確認メールは、SSH等でホストマシンのユーザにログインしてmutt等で確認する必要があります。
  • Apacheの設定は簡易なものにとどまっており、他のウェブサービスと混在できません。混在する必要があればサブドメインで分割したり、RewriteRule等を設定する必要があります。

2 Mastodonインスタンスを立ち上げる前に

Mastodonインスタンスを立ち上げる前にFFmpegとRuby 2.3をインストールする必要があります。

2.1 FFmpegをインストールする

こちらのスクリプトでFFmpegをインストールしてください。

2.2 Ruby 2.3をインストールする

こちらのスクリプトでRuby 2.3をインストールしてください。

3 Mastodonインスタンスを立ち上げる

以下のスクリプトを実行することでMastodonインスタンスが立ち上がります。LOCAL_DOMAINはIPアドレスでもFQDNでも可能です。ブラウザでアクセスできるものにしてください。

$ LOCAL_DOMAIN=192.168.11.86 ./run-this-script.sh
#!/bin/sh

set -e

[ -z "${LOCAL_DOMAIN}" ] && \
  LOCAL_DOMAIN=centos-7-mastodon.hiroom2.com
[ -z "${MASTODON_DIR}" ] && \
  MASTODON_DIR=/var/lib/mastodon
MASTODON_TAG=v1.3.3

mastodon_install_depend()
{
  sudo yum install -y epel-release
  sudo yum install -y ImageMagick postgresql-devel libxml2-devel \
       libxslt-devel file git curl nodejs npm
  sudo gem install bundler rake
  sudo npm install -g yarn
}

mastodon_install_redis()
{
  sudo yum install -y redis
  sudo systemctl enable redis
  sudo systemctl start redis
}

mastodon_install_postgres()
{
  sudo yum install -y postgresql-server
  sudo postgresql-setup initdb
  sudo sed -e 's/^host\(.*\)ident/host\1trust/g' \
       -i /var/lib/pgsql/data/pg_hba.conf
  sudo systemctl enable postgresql
  sudo systemctl start postgresql
  cat <<EOF | sudo -u postgres psql
CREATE USER mastodon CREATEDB;
\q
EOF
}

mastodon_install_mastodon()
{
  # Not use -m for disable creating skel like .bashrc.
  sudo useradd mastodon -M -d ${MASTODON_DIR}
  git clone https://github.com/tootsuite/mastodon.git
  cd mastodon
  git checkout ${MASTODON_TAG} -b ${MASTODON_TAG}
  cd ..
  sudo mkdir -p "$(dirname ${MASTODON_DIR})"
  sudo mv mastodon ${MASTODON_DIR}
  sudo chown -R mastodon:mastodon ${MASTODON_DIR}

  sudo su - mastodon -c "
set -e
cd ${MASTODON_DIR}
# The ruby version checker may not work correctly.
sed -e \"s/^ruby/#ruby/g\" -i Gemfile
bundle install --deployment --without development test
yarn install --pure-lockfile

PAPERCLIP_SECRET=\$(rake secret)
SECRET_KEY_BASE=\$(rake secret)
OTP_SECRET=\$(rake secret)

sed -e \"s/^REDIS_HOST=.*/REDIS_HOST=localhost/g\" \
    -e \"s/^DB_HOST=.*/DB_HOST=localhost/g\" \
    -e \"s/^DB_USER=.*/DB_USER=mastodon/g\" \
    -e \"s/^DB_NAME=.*/DB_NAME=mastodon/g\" \
    -e \"s/^LOCAL_DOMAIN=.*/LOCAL_DOMAIN=${LOCAL_DOMAIN}/g\" \
    -e \"s/^LOCAL_HTTPS=.*/LOCAL_HTTPS=true/g\" \
    -e \"s/^PAPERCLIP_SECRET=.*/PAPERCLIP_SECRET=\${PAPERCLIP_SECRET}/g\" \
    -e \"s/^SECRET_KEY_BASE=.*/SECRET_KEY_BASE=\${SECRET_KEY_BASE}/g\" \
    -e \"s/^OTP_SECRET=.*/OTP_SECRET=\${OTP_SECRET}/g\" \
    -e \"s/^SMTP_SERVER=.*/SMTP_SERVER=localhost/g\" \
    -e \"s/^SMTP_PORT=.*/SMTP_PORT=25/g\" \
    -e \"s/^SMTP_LOGIN=/#SMTP_LOGIN=/g\" \
    -e \"s/^SMTP_PASSWORD=/#SMTP_PASSWORD=/g\" \
    -e \"s/^SMTP_FROM_ADDRESS=.*/SMTP_FROM_ADDRESS=noreply@localhost/g\" \
    -e \"s/^#SMTP_AUTH_METHOD=.*/SMTP_AUTH_METHOD=none/g\" \
    -e \"s/^# DEFAULT_LOCALE=.*/DEFAULT_LOCALE=en/g\" \
    .env.production.sample > .env.production

RAILS_ENV=production bundle exec rails db:setup
RAILS_ENV=production bundle exec rails assets:precompile
"

  cat <<EOF | sudo tee /lib/systemd/system/mastodon-web.service
[Unit]
Description=mastodon-web
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=${MASTODON_DIR}
Environment="RAILS_ENV=production"
Environment="PORT=3000"
ExecStart=/usr/local/bin/bundle exec puma -C config/puma.rb
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target
EOF

  cat <<EOF | sudo tee /lib/systemd/system/mastodon-sidekiq.service
[Unit]
Description=mastodon-sidekiq
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=${MASTODON_DIR}
Environment="RAILS_ENV=production"
Environment="DB_POOL=5"
ExecStart=/usr/local/bin/bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target
EOF

  cat <<EOF | sudo tee /lib/systemd/system/mastodon-streaming.service
[Unit]
Description=mastodon-streaming
After=network.target

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

[Install]
WantedBy=multi-user.target
EOF

  sudo systemctl enable mastodon-web mastodon-sidekiq mastodon-streaming
  sudo systemctl start mastodon-web mastodon-sidekiq mastodon-streaming
}

mastodon_install_apache()
{
  sudo yum install -y httpd mod_ssl
  cat <<EOF | sudo tee /etc/httpd/conf.d/mastodon.conf
<VirtualHost _default_:443>
  SSLEngine on
  SSLCertificateFile /etc/pki/tls/certs/localhost.crt
  SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

  <Location /assets>
    Header always set Cache-Control "public, max-age=31536000, immutable"
  </Location>

  ProxyPreserveHost On
  RequestHeader set X-Forwarded-Proto "https"
  ProxyPass /500.html !
  ProxyPass /oops.png !
  ProxyPass /api/v1/streaming/ ws://localhost:4000/
  ProxyPassReverse /api/v1/streaming/ ws://localhost:4000/
  ProxyPass / http://localhost:3000/
  ProxyPassReverse / http://localhost:3000/
</VirtualHost>
EOF

  sudo setsebool -P httpd_can_network_connect 1
  sudo setsebool -P httpd_can_sendmail 1
  sudo systemctl enable httpd
  sudo systemctl restart httpd
  sudo firewall-cmd --add-service=https --permanent
  sudo firewall-cmd --reload
}

mastodon_install_postfix()
{
  sudo yum install -y postfix
  cat <<EOF | sudo tee /etc/postfix/main.cf
myhostname = localhost
mydomain = localdomain
myorigin = \$myhostname.\$mydomain
mydestination = localhost, localhost.\$mydomain, \$myhostname, \$mydomain, \$myorigin
compatibility_level = 2
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
inet_interfaces = all
local_recipient_maps = unix:passwd.byname \$alias_maps
unknown_local_recipient_reject_code = 550
mynetworks_style = subnet
mynetworks = 127.0.0.0/8
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
smtpd_banner = \$myhostname ESMTP  (\$mail_version)
debug_peer_level = 2
debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         ddd \$daemon_directory/\$process_name \$process_id & sleep 5
sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
inet_protocols = ipv4
EOF

  sudo newaliases
  sudo systemctl restart postfix
  sudo firewall-cmd --add-service=smtp --permanent
  sudo firewall-cmd --reload
  sudo yum install -y mutt
}

mastodon_main()
{
  mastodon_install_depend
  mastodon_install_redis
  mastodon_install_postgres
  mastodon_install_mastodon
  mastodon_install_apache
  mastodon_install_postfix
}

mastodon_main "$@"

4 Mastodonインスタンスへアクセスする

これ以降はUbuntu 16.04と同様です。