Ubuntu 16.04: Mastodonインスタンスを立ち上げる

DockerやVagrantを使わずにUbuntu 16.04上に直接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インスタンスが立ち上がります。LOCAL_DOMAINはIPアドレスでもFQDNでも可能です。ブラウザでアクセスできるものにしてください。

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

set -e

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

mastodon_install_depend()
{
  sudo apt install -y imagemagick ffmpeg libpq-dev libxml2-dev \
       libxslt1-dev file git curl ruby-bundler ruby-dev
  sudo gem install bundler
  curl -sL https://deb.nodesource.com/setup_6.x | sudo bash -
  sudo apt install -y nodejs
  sudo npm install -g yarn
}

mastodon_install_redis()
{
  sudo apt install -y redis-server redis-tools
  sudo systemctl enable redis-server
  sudo systemctl start redis-server
}

mastodon_install_postgres()
{
  sudo apt install -y postgresql postgresql-contrib
  cat <<EOF | sudo -u postgres psql
CREATE USER mastodon CREATEDB;
\q
EOF
  sudo sed \
       -e 's;^local.*postgres.*peer$;host all all 127.0.0.1/32 ident;g' \
       -i /etc/postgresql/9.?/main/pg_hba.conf

  sudo apt install -y pidentd
  sudo systemctl enable pidentd
  sudo systemctl start pidentd
  sudo systemctl restart postgresql
}

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 "
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 apt install -y apache2
  cat <<EOF | sudo tee /etc/apache2/sites-available/mastodon.conf
<VirtualHost _default_:443>
  SSLEngine on
  SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem
  SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.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

  for mod in ssl proxy proxy_http headers; do
    sudo a2enmod ${mod}
  done
  sudo a2ensite mastodon

  sudo systemctl enable apache2
  sudo systemctl restart apache2
}

mastodon_install_postfix()
{
  cat <<EOF | sudo debconf-set-selections
postfix postfix/main_mailer_type select No configuration
EOF
  sudo apt install -y postfix

  cat <<EOF | sudo tee /etc/postfix/main.cf
compatibility_level = 2
command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix/sbin
data_directory = /var/lib/postfix
mail_owner = postfix
myhostname = localhost
inet_interfaces = all
mydestination = localhost
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_name (Ubuntu)
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/postfix
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
inet_protocols = ipv4
EOF

  sudo newaliases
  sudo systemctl enable postfix
  sudo systemctl restart postfix
}

mastodon_main()
{
  mastodon_install_depend
  mastodon_install_redis
  mastodon_install_postgres
  mastodon_install_mastodon
  mastodon_install_apache
  mastodon_install_postfix
}

mastodon_main "$@"

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

インストールしたマシンへアクセスします。

https://<server>

マシンの証明書を組み込んでいないので、Chromeの場合は以下の警告が出てアクセスできません。"ADVANCED"を表示させて"Proceed to <server> (unsafe)"をクリックすることで、このウェブサイトに例外的にアクセスするようにします。

Firefox等でも同様にこのウェブサイトを例外的にアクセスできるようにしてください。

0001_YourConnectionIsNotPrivate.png

Mastodonのトップページが表示されます。ユーザを追加します。メールアドレスは<user>@localhostです。

0002_MastodonTopPage.png

送信した確認メールに記載されたページリンクを使ってアカウントを有効化しろと表示されます。

0003_NeedConfirmation.png

マシンのユーザにログインして、muttを立ち上げると確認メールが届いています。ページリンクをクリックします。

$ sudo apt install -y mutt
$ mutt

0004_ConfirmationMail.png

メールアドレスを確認できたと表示されます。メールアドレスとパスワードを入力してログインします。

0005_ConfirmationDone.png

Mastodonにログインできました。

0006_WelcomeToMastodon.png

TOOTもできます。

0007_MyFirstTOOT.png