Mastodon

Updated 30 September 2019

Installing and configuring Mastodon

Mastodon is a free distributed microblogging platform running on a federated network.

Preparing a LXC container

We suggest that you install Mastodon in a separate container and configure it according to the manual.

Installing and configuring PostgreSQL

Install and configure PostgreSQL according to the manual.

Enable peer authentication for local connections only:

/etc/postgresql-11/pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
#host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
#host    all             all             ::1/128                 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local   replication     all                                     trust
#host    replication     all             127.0.0.1/32            trust
#host    replication     all             ::1/128                 trust

Create a user named mastodon and enable them to create databases:

su postgres -c psql
psql (11.2)
Type "help" for help.

postgres=# CREATE USER mastodon CREATEDB;
CREATE ROLE
postgres=# \q

Install Mastodon

Installing system packages

Install the necessary accessories:

emerge -a dev-db/redis dev-libs/icu dev-libs/protobuf dev-python/nodeenv dev-util/pkgconfig media-gfx/imagemagick media-video/ffmpeg net-dns/libidn

Starting Redis

Start Redis and add it to autostart:

/etc/init.d/redis start

rc-update add redis

Creating a system user

Create a system user called mastodon:

mkdir -p /var/calculate/www

useradd -d /var/calculate/www/mastodon mastodon

Installing and configuring rbenv and rbenv-build

Install rbenv and rbenv-build to the user's home directory and configure them:

su mastodon

cd

git clone https://github.com/rbenv/rbenv.git ~/.rbenv

cd ~/.rbenv && src/configure && make -C src

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

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

exec bash

git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

Installing Ruby

Install the relevant version of Ruby (2.6.1 in our case):

RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 2.6.1

rbenv global 2.6.1

The default version of gem refers to ruby_2.6.1 and is incompatible with the latest version of bundler. Therefore, update gem:

gem update --system

And install bundler:

gem install bundler -f --no-document

Installing Node.js and Yarn

Install Node.js and Yarn to the user's home directory:

nodeenv --node=8.16.0 .node-8

source .node-8/bin/activate

npm install -g yarn

echo 'source ~/.node-8/bin/activate' >> ~/.bashrc

Fetching Mastodon sources from Git

Install the source code:

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

cd live

git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)

Installing Ruby and Node.js dependencies

Install Ruby dependencies:

bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test

Install Node.js dependencies:

yarn install --pure-lockfile

Installing and configuring Mastodon

Create a configuration for ~mastodon.example.org~~ with the following command:

RAILS_ENV=production bundle exec rake mastodon:setup
Your instance is identified by its domain name. Changing it afterward will break things.
Domain name: mastodon.example.org

Single user mode disables registrations and redirects the landing page to your public profile.
Do you want to enable single user mode? No

Are you using Docker to run Mastodon? no

PostgreSQL host: /var/run/postgresql
PostgreSQL port: 5432
Name of PostgreSQL database: mastodon_production
Name of PostgreSQL user: mastodon
Password of PostgreSQL user:
Database configuration works! 🎆

Redis host: localhost
Redis port: 6379
Redis password:
Redis configuration works! 🎆

Do you want to store uploaded files on the cloud? No

Do you want to send e-mails from localhost? No
SMTP server: mail.example.org
SMTP port: 465
SMTP username:
SMTP password:
SMTP authentication: starttls
SMTP OpenSSL verify mode: none
E-mail address to send e-mails "from": Mastodon <notifications@mastodon.example.org>
Send a test e-mail with this configuration right now? Yes
Send test e-mail to: admin@example.org

This configuration will be written to .env.production
Save configuration? Yes

Now that configuration is saved, the database schema must be loaded.
If the database already exists, this will erase its contents.
Prepare the database now? Yes
Running `RAILS_ENV=production rails db:setup` ...

Created database 'mastodon_production'
...
Done!

The final step is compiling CSS/JS assets.
This may take a while and consume a lot of RAM.
Compile the assets now? Yes
Running `RAILS_ENV=production rails assets:precompile` ...

yarn install v1.15.2
...
Done!

All done! You can now power on the Mastodon server 🐘

Do you want to create an admin user straight away? Yes
Username: admin
E-mail: admin@example.org
You can login with the password: e3b316f78cbc2ec0bde5118c68414d73
You can change your password once you login.

Exit the user session:

exit

Getting Let's Encrypt certificate

Get the ~~mastodon.example.org~ domain certificate ~ for Nginx, according to the manual.

Installing and configuring Nginx

Install and configure a Nginx Web server as a reverse proxy according to the manual.

Copy the example of Nginx configuration for Mastodon:

cp /var/calculate/www/mastodon/live/dist/nginx.conf /etc/nginx/sites-enabled/mastodon.conf

Specify the paths and the server name, mastodon.example.org:

/etc/nginx/sites-enabled/mastodon.conf
server {
  listen 80;
  listen [::]:80;
  server_name mastodon.example.org;
  root /var/calculate/www/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 mastodon.example.org;

  # Uncomment these lines once you acquire a certificate:
  ssl_certificate /etc/letsencrypt/live/mastodon.example.org/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/mastodon.example.org/privkey.pem;
  ...
  root /var/calculate/www/mastodon/live/public;
  ...
}

Starting Mastadon

Create OpenRC scripts for managing the services:

Here is an init script for Mastodon Web:

/etc/init.d/mastodon-web
#!/sbin/openrc-run

name="Mastodon Web daemon"
description=""
pidfile=/run/mastodon-web.pid
extra_commands="reload"
command_user=mastodon
output_log=/var/log/mastodon-web.log
error_log=/var/log/mastodon-web.log
directory=/var/calculate/www/mastodon/live
start_stop_daemon_args="-e RAILS_ENV=production -e PORT=3000"
command=/var/calculate/www/mastodon/.rbenv/shims/bundle
command_args="exec puma -C config/puma.rb"
command_background=true

depend() {
    use postgresql net redis
}

start_pre() {
    checkpath -f -o mastodon -m 0600 /var/log/mastodon-web.log
}

reload() {
    einfo "Reload $name"
    kill -USR1 $(cat $pidfile)
}

Here is an init script for Mastodon Streaming:

/etc/init.d/mastodon-streaming
#!/sbin/openrc-run
name="Mastodon streaming daemon"
description=""
pidfile=/run/mastodon-streaming.pid
command_user=mastodon
output_log=/var/log/mastodon-streaming.log
error_log=/var/log/mastodon-streaming.log
directory=/var/calculate/www/mastodon/live
start_stop_daemon_args="-e NODE_ENV=production -e PORT=4000 -e STREAMING_CLUSTER_NUM=1"
command=/var/calculate/www/mastodon/.node-8/bin/node
command_args="./streaming"
command_background=true

depend() {
    use postgresql net redis
}

start_pre() {
        checkpath -f -o mastodon -m 0600 /var/log/mastodon-streaming.log
}

and the one for Mastodon Sidekiq:

/etc/init.d/mastodon-sidekiq
#!/sbin/openrc-run

name="Mastodon Sidekiq daemon"
description=""
pidfile=/run/mastodon-sidekiq.pid
command_user=mastodon
output_log=/var/log/mastodon-sidekiq.log
error_log=/var/log/mastodon-sidekiq.log
directory=/var/calculate/www/mastodon/live
start_stop_daemon_args="-e RAILS_ENV=production -e DB_POOL=25 -e MALLOC_ARENA_MAX=2"
command=/var/calculate/www/mastodon/.rbenv/shims/bundle
command_args="exec sidekiq -c 25"
command_background=true

depend() {
    use postgresql net redis
}

start_pre() {
    checkpath -f -o mastodon -m 0600 /var/log/mastodon-sidekiq.log
}

Set up privileges for Mastodon services:

chmod 0755 /etc/init.d/mastodon-*

Launch the Mastodon services:

/etc/init.d/mastodon-web start

/etc/init.d/mastodon-streaming start

/etc/init.d/mastodon-sidekiq start

Add them to autostart:

rc-update add mastodon-web

rc-update add mastodon-streaming

rc-update add mastodon-sidekiq

Updating Mastodon

Git update

Update the Git repository containing Mastodon source code:

su - mastodon

cd ~/live

git fetch --tags

git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)

Make sure that the version of the source code has changed:

git status
HEAD detached at v2.8.0
nothing to commit, no changes detected

Update Ruby and Node.js dependencies

You may need to update Ruby and Node.js after upgrading to a new version of Mastodon. The above-mentioned release notes will tell you if you need to do the rest of this section.

To update Ruby dependencies, run:

bundle install --deployment --without development test

To update Node.js dependencies, run:

yarn install --pure-lockfile

Database schema update

Update the database schema at every update time, up to the new version of Mastodon. This operation is safe, since the update will be skipped anyway if there is no new schema.

For database migration, run:

RAILS_ENV=production bundle exec rails db:migrate

Pre-compilation of updated resources

You may need to pre-compile updated resources after upgrading to a new version of Mastodon. The above-mentioned release notes will tell you if you need to do the rest of this section.

For pre-compilation, run:

RAILS_ENV=production bundle exec rails assets:precompile

Warning

The (Webpacker) precompiler may take a significant load, especially of RAM load. If you realize that your server does not have enough RAM when precompiling, you can stop Mastodon services before starting the precompilation process.

Cache clearing

Clear the cache:

RAILS_ENV=production bin/tootctl cache clear

Additional update time actions

Release notes may contain relevant instructions marked Non-Docker that you may need when you want to update to a new Mastodon version.

Exit the user session:

exit

Restore Ruby environment after updating system packages

Log in to the user session:

su - mastodon

cd ~/live

Reinstall the packages belonging to the Ruby environment:

bundle pristine

bundle install --deployment --without development test

Exit the user session:

exit

Restarting Mastodon

Mastodon operates in RAM only, so you will need to restart it for any of the previously described updates to take effect. To restart, run:

/etc/init.d/mastodon-web restart

/etc/init.d/mastodon-streaming restart

/etc/init.d/mastodon-sidekiq restart