February 5, 2021

Mastodon Installation

Mastodon Installation

1. Intro

Mastodon is free and open-source software for running self-hosted social networking services. It has microblogging features similar to the Twitter service, which are offered by a large number of independently run Mastodon nodes (known as "instances"), each with its own code of conduct, terms of service, privacy options, and moderation policies.
Each user is a member of a specific Mastodon instance, which can interoperate as a federated social network, allowing users on different nodes to interact with each other. This is intended to give users the flexibility to select a server whose policies they prefer, but keep access to a larger social network. Mastodon is also part of the Fediverse ensemble of server platforms, which use shared protocols allowing users to also interact with users on other compatible platforms, such as PeerTube and Friendica
Official Website: https://joinmastodon.org/

2. Background

Docker is not recommended by Mastodon Official.(dunno why) So this is a tutorial of manual deployment.
Environment: Ubuntu 20.04 LTS

3. Deployment

3.1 Dependencies

Install the required packages

apt -y update
apt -y install curl git nginx python3-certbot-nginx

Install Docker

curl -sSL https://get.docker.com/ | sh
systemctl enable --now nginx docker

Install docker-compose (check latest version yourself)

curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

3.2 Download Mastodon and edit docker-compose file

Pull files

cd /opt
git clone https://github.com/tootsuite/mastodon.git
cd mastodon/

Copy a configuration file

cp .env.production.sample .env.production

Actually you can rename or delete the default docker-compose.yml that comes with the project. If you use this yml configuration directly, it will definitely not run. There are too many problems beyond explanation, so I won't go into details here.

mv docker-compose.yml docker-compose.yml.bak

Create docker-compose file

nano docker-compose.yml

Here I put up an example configuration I am currently using, for your reference

version: '3.5'

services:
  mastodon-db:
    image: postgres:9.6-alpine
    shm_size: 256mb
    environment:
      POSTGRES_DB: mastodon
      POSTGRES_USER: user # your database username
      POSTGRES_PASSWORD: password # your database password
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "postgres"]
    volumes:
      - ./postgres:/var/lib/postgresql/data
    restart: unless-stopped

  mastodon-redis:
    image: redis:6.0-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
    volumes:
      - ./redis:/data
    restart: unless-stopped

  mastodon-web:
    image: tootsuite/mastodon
    env_file: .env.production
    command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
    depends_on:
      - mastodon-db
      - mastodon-redis
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:3000/health || exit 1"]
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - ./public/system:/mastodon/public/system
    restart: unless-stopped

  mastodon-streaming:
    image: tootsuite/mastodon
    env_file: .env.production
    command: node ./streaming
    depends_on:
      - mastodon-db
      - mastodon-redis
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1"]
    ports:
      - "127.0.0.1:4000:4000"
    restart: unless-stopped

  mastodon-sidekiq:
    image: tootsuite/mastodon
    env_file: .env.production
    command: bundle exec sidekiq
    depends_on:
      - mastodon-db
      - mastodon-redis
    volumes:
      - ./public/system:/mastodon/public/system
    restart: unless-stopped

3.3 Run configuration wizard

Next, run this command to enter the configuration wizard

docker-compose run --rm mastodon-web bundle exec rake mastodon:setup

Simply follow the instructions below:

Domain name: # fill in your domain
Do you want to enable single user mode? # Yes
Are you using Docker to run Mastodon? # Yes
PostgreSQL host: # mastodon-db
PostgreSQL port: # 5432
Name of PostgreSQL database: # mastodon
Name of PostgreSQL user: # user, match the database username in docker-compose.yml
Password of PostgreSQL user: # password, match the database username in docker-compose.yml
Redis host: # mastodon-redis
Redis port: # 6379
Redis password: # leave blank, press enter directly
Do you want to store uploaded files on the cloud? # No
Do you want to send e-mails from localhost? # Yes
Send a test e-mail with this configuration right now? # No
Save configuration? Yes

Note: This configuration is in single-user mode. that is, registration is not open by default. Secondly, SMTP is not configured because I’m the only user.

Next, it will print out the configuration you filled in, and now you need to copy the configuration you filled in before.

This is a very tricky place. You will see the following prompt:

Prepare the database now? (Y/n)

Important: Don't choose Y or N, just press the keyboard combination Ctrl^C to exit. Then clear the default configuration in the following configuration file:

echo > .env.production

Edit it

nano .env.production

Paste the configuration you copied through the wizard output earlier and save. Then run the wizard again:

docker-compose run --rm mastodon-web bundle exec rake mastodon:setup

The configuration this time must be the same as the last time. When you come to the following prompt again, you can choose Yes:

Prepare the database now? (Y/n) # Yes
Compile the assets now? (Y/n) # Yes

The next step is to create an administrator account. Continue to follow this guide and it will be OK.

3.4 Build up the container

Up docker-compose

docker-compose up -d

Now you need to change the owner of the public directory to the one in the container, otherwise you cannot upload avatar later.

chown -R 991:991 public

3.5 Config Nginx

Now make a copy of the Nginx configuration file

cp /opt/mastodon/dist/nginx.conf /etc/nginx/conf.d/mastodon.conf

Edit mastodon.conf

nano /etc/nginx/conf.d/mastodon.conf

In this configuration file, the official template has been all set. You only need to edit in the following two server blocks:

server {
  listen 80;
  listen [::]:80;
  server_name example.com; # your domain
  root /opt/mastodon/public; # absolute path of public directory
...
server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name example.com; # your domain
  root /opt/mastodon/public; # absolute path of public directory
...
}

Use certbot to issue SSL certificates

certbot --nginx

Restart Nginx

systemctl restart nginx

4. Post-Installation

If you want to move your site in the future, just pack the /opt/mastodon directory directly, and upload it to another machine after decompression.

It is the same to change the configuration in .env.production. After changes, you can run docker-compose up -d.