mastodon community
Jump toUpdate content

Installing a Mastodon Community on Ubuntu Focal Fossa

Reviewed on 07 February 2023Published on 05 March 2019
  • compute
  • communication
  • messaging
  • self-hosted
  • social-network
  • Prework
  • Mastodon
  • sni

Mastodon is an open-source, self-hosted, social media and social networking service. It allows you to host your own Instances which may have their own code of conduct, terms of service and moderation policies. There is no central server and Mastodon Instances are connected as a federated social network, allowing users from different Instances to interact with each other. The platform provides privacy features allowing users to adjust the privacy settings of each of their posts.

As there is no central server, you can choose whether to join or leave an instance according to its policy without actually leaving Mastodon Social Network. Mastodon is a part of Fediverse, allowing users to interact with users on other platforms that support the same protocol for example: PeerTube, Friendica and GNU Social.

Mastodon provides the possibility of using S3 compatible Object Storage to store media content uploaded to Instances, making it flexible and scalable.

Security & Identity (IAM):

You may need certain IAM permissions to carry out some actions described on this page. This means:

  • you are the Owner of the Scaleway Organization in which the actions will be carried out, or
  • you are an IAM user of the Organization, with a policy granting you the necessary permission sets

Installing Prework

  1. Connect to your instance via SSH.
  2. Update the APT packet cache and the software already installed on the instance.
    apt update && apt upgrade -y
  3. Install curl on the system and add an external repository for the required version of Node.js. Install it by running the following commands:
    apt install curl -y
    curl -sL https://deb.nodesource.com/setup_12.x | bash -
    Mastodon uses the Yarn package manager.
  4. Install the repository for the required version of Yarn by running the following commands:
    curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
    echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
  5. Update the system and install Yarn.
    apt-get update && apt-get install -y yarn
  6. Install the following packages, which Mastodon depends on:
    • Imagemagick for image related operations
    • FFmpeg for conversion of GIFs to MP4s
    • Protobuf with libprotobuf-dev and protobuf-compiler, used for language detection
    • Nginx as frontend web server
    • Redis for its in-memory data structure store
    • PostgreSQL is used as SQL database for Mastodon
    • Node.js is used for Mastodon’s streaming API
    • Yarn is a Node.js package manager
    • Certbot is a tool to manage TLS certificated issued by the Let’s Encrypt nonprofit “Certificate Authority” (CA)
    • other -dev packages and g++. These packages are required for the compilation of Ruby using ruby-build.
apt install -y imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev nginx redis-server redis-tools postgresql postgresql-contrib certbot python3-certbot-nginx yarn libidn11-dev libicu-dev libjemalloc-dev

We are going to use rbenv to manage Ruby versions. The application must be installed for a single Linux user, therefore, first we must create a user under which Mastodon will run. 7. Run the following command. The --disabled-login flag disables direct login to the user account for increased security.

adduser --disabled-login mastodon
  1. Log into the mastodon user account and change to the home directory.
    su mastodon
  2. Set up rbenv and ruby-build:
    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
    # Restart the users shell
    exec bash
    # Check if rbenv is correctly installed
    type rbenv
    # Install ruby-build as a rbenv plugin
    git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
  3. Install and enable the version of Ruby that is used by Mastodon.
    RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 2.6.6
    rbenv global 2.6.6

    This step may take up to several minutes to complete.

  4. Run the following command to install bundler:
    gem install bundler --no-document
  5. Switch back into the root account by typing exit.

Configuring PostgreSQL

Mastodon requires access to a postgreSQL database to store its configuration and user data.

  1. Change into the postgres user account, run psql and create a database:
    sudo -u postgres psql
  2. Create the database user for Mastodon and exit:

Downloading Mastodon

  1. Switch into the mastodon user account:
    su - mastodon
  2. Enter the user’s home directory and clone the Mastodon Git repository into the live directory:
    git clone https://github.com/tootsuite/mastodon.git live && cd live
  3. Check out to the latest stable branch.
    git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)
  4. Install the remaining Ruby dependencies:
    bundle config deployment 'true'
    bundle config without 'development test'
    bundle install -j$(getconf _NPROCESSORS_ONLN)
  5. Use yarn to install the node.js dependencies:
    yarn install --pure-lockfile
  6. Type and enter exit to return to the root account.

Requesting a Let’s Encrypt Certificate

  1. Stop Nginx before requesting the certificate:

    systemctl stop nginx.service
  2. Use certbot to request a certficate with TLS SNI validation in standalone mode. Replace example.com with your domain name:

    certbot certonly --standalone -d example.com

    As Let’s Encrypt certficates have a validity of 90 days, a cron-job can be used to renew them and to restart nginx automatically.

  3. Create a new file and open it in a text editor like nano:

    nano /etc/cron.daily/letsencrypt-renew
  4. Copy the following content into the file, save it and exit nano:

    #!/usr/bin/env bash
    certbot renew
    systemctl reload nginx.service
  5. Allow execution of the script and restart the cron daemon. It will run the script daily:

    chmod +x /etc/cron.daily/letsencrypt-renew
    systemctl restart cron.service

Configuring Nginx

  1. Copy the example configuration file shipped with Mastodon in your Nginx sites-available directory and create a symlink to it in the sites-enabled directory:
    cp /home/mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon
    ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon
  2. Open the configuration file in a text editor, such as nano:
    nano /etc/nginx/sites-available/mastodon
  3. Replace example.com in the configuration file with your domain or subdomain. Replace with your domain in all following occurrences as well.
    map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
    upstream backend {
    server fail_timeout=0;
    upstream streaming {
    server fail_timeout=0;
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;
    server {
    listen 80;
    listen [::]:80;
    server_name example.com; <- /!\ Replace example.com with your domain name /!\
    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 example.com;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    # Uncomment these lines once you acquire a certificate:
    # ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; <- /!\ Replace example.com with your domain name and uncomment this line /!\
    # ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; <- /!\ Replace example.com with your domain name and uncomment this line /!\
    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://backend;
    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_valid 410 24h;
    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://streaming;
    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;
  4. Save and exit.

Configuring the Mastodon Application

  1. Enter the mastodon user account:

    su - mastodon
  2. Change into the /home/mastodon/live directory and run the Mastodon installer:

    cd /home/mastodon/live
    RAILS_ENV=production bundle exec rake mastodon:setup

    The interactive installer guides you through the setup process.

  3. Enter the domain name or subdomain of the instance.

  4. Select No when asked if you want to use Docker.

    Most of the other values are already pre-filled with the correct settings. Edit them if required for your setup.

  5. Select Amazon S3 as a service provider to set up Mastodon with Object Storage. Valid API keys are required in this step.

    Enter the details as following:

    Provider Amazon S3
    S3 bucket name: [scaleway_bucket_name]
    S3 region: fr-par
    S3 hostname: s3.fr-par.scw.cloud
    S3 access key: [scaleway_access_key]
    S3 secret key: [scaleway_secret_key]

    If your bucket is located in Amsterdam, use nl-ams as region and s3.nl-ams.scw.cloud as S3 hostname If it is located in Warsaw, use pl-waw and s3.pl-waw.scw.cloud.

    Once the configuration is complete, the installer will start to compile the application. This may take some time and consume a lot of RAM.

    Once the application is installed, you will be asked if you want to create an Administrator account for your Mastodon instance.

  6. Type Y to create the account. Enter the username for the admin user, followed by your email address. A random password will be generated. Take a note of it, as you will need it to connect to your Instance.

    All done! You can now power on the Mastodon server 🐘
    Do you want to create an admin user straight away? Yes
    Username: admin <-- Enter the username for your Mastodon admin account
    E-mail: me@myemail.com <-- Enter your email address
    You can login with the password: 9dc4d92d93a26e9b6c021bb75b4a3ce2
  7. Type exit to switch back into the root account.

Setting-up systemd Services

Systemd scripts are used to manage services on Ubuntu systems. Three different scripts are required for Mastodon. These scripts come with the Mastodon package, you need to copy them to their final destination, then activate the services.

  1. Copy the Mastodon systemd scripts into their final destination:
    cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/
  2. Reload the systemd daemon:
    systemctl daemon-reload
  3. Start the services and enable them, so they will start automatically upon the next system reboot:
    systemctl start mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service
    systemctl enable mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service
  4. Verify if all services are running:
    systemctl status mastodon-*.service

If everything is running, open a web browser and go to your domain name. You will see the home page of your Mastodon instance:

You can log in with the admin account that you have created during the installation to configure additional parameters of your instance, link the instance with another one to join a federated network, create another user account and start sharing posts and photos on your timeline. If configured with Object Storage, all files uploaded to the instance are automatically stored in the Object Storage bucket and embedded in the users timeline:

For more information and advanced configuration of Mastodon, refer to the official documentation.