Running multiple instances on a single server

In this tutorial, I am going to show you how to install more then one mastodon instances on a single server.

Switch to the mastodon user:

Code:
su - mastodon


Clone the Mastodon Git repository into the new directory:

Code:
git clone https://github.com/tootsuite/mastodon.git new && cd new


Check out the latest stable branch.

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


Install the remaining Ruby dependencies:

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


Use yarn to install the node.js dependencies:

yarn install --pure-lockfile


Type and enter exit to return to the root account.

Requesting a Let’s Encrypt Certificate​

Stop Nginx before requesting the certificate:

systemctl stop nginx


Use certbot to request a certificate with TLS SNI validation in standalone mode. Replace example.com with your domain name

certbot certonly --standalone -d example.com


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

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

nano /etc/cron.daily/letsencrypt-renew


Copy the following content into the file, save it and exit nano:

#!/usr/bin/env bash
certbot renew
systemctl reload nginx



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

 

Configuring Nginx​

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/new/dist/nginx.conf /etc/nginx/sites-available/mastodon-new
ln -s /etc/nginx/sites-available/mastodon-new /etc/nginx/sites-enabled/mastodon-new


Open the configuration file in a text editor, such as nano:

nano /etc/nginx/sites-available/mastodon-new


Replace example.com in the configuration file with your domain or subdomain. Replace with your domain in all following occurrences as well. Change streaming port number, backend port number, change upstram and backend to new-backend, new-streaming, and all other paths to your new mastodon files. You can just copy/paste the code bellow.

Code:
upstream new-backend {
   server 127.0.0.1:3030 fail_timeout=0;
}

upstream new-streaming {
   server 127.0.0.1:4030 fail_timeout=0;
}

server {
 listen 80;
 listen [::]:80;
 server_name example.com;  <- /!\ Replace example.com with your domain name /!\
 root /home/mastodon/new/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/new/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://new-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://new-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;
}


Save and exit.

Enter the mastodon user account:

su - mastodon


Change into the /home/mastodon/new directory and run the Mastodon installer:

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


The interactive installer guides you through the setup process.

  1. Enter the domain name or subdomain of the instance.
  2. 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.

  1. Optional - 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 follows:
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]

Note:

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.

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

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.

Copy the current Mastodon systemd scripts and rename it:

cp /etc/systemd/system/mastodon-sidekiq.service /etc/systemd/system/new-sidekiq.service
cp /etc/systemd/system/mastodon-streaming.service /etc/systemd/system/new-streaming.service
cp /etc/systemd/system/mastodon-web.service /etc/systemd/system/new-web.service


Edit files

Code:
nano /etc/systemd/system/new-web.service


See changes, new

Code:
[Unit]
Description=new-web
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/new
Environment="RAILS_ENV=production"
Environment="PORT=3030"
EnvironmentFile=/home/mastodon/new/.env.production #add this
Environment="LD_PRELOAD=libjemalloc.so"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb
ExecReload=/bin/kill -SIGUSR1 $MAINPID
TimeoutSec=15
Restart=always
# Proc filesystem
ProcSubset=pid
ProtectProc=invisible
# Capabilities
CapabilityBoundingSet=
# Security
NoNewPrivileges=true
# Sandboxing
ProtectSystem=strict
PrivateTmp=true
PrivateDevices=true
PrivateUsers=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictAddressFamilies=AF_INET
RestrictAddressFamilies=AF_INET6
RestrictAddressFamilies=AF_NETLINK
RestrictAddressFamilies=AF_UNIX
RestrictNamespaces=true
LockPersonality=true
RestrictRealtime=true
RestrictSUIDSGID=true
RemoveIPC=true
PrivateMounts=true
ProtectClock=true
# System Call Filtering
SystemCallArchitectures=native
SystemCallFilter=~@cpu-emulation @debug @keyring @ipc @mount @obsolete @privileged @setuid
SystemCallFilter=@chown
SystemCallFilter=pipe
SystemCallFilter=pipe2
ReadWritePaths=/home/mastodon/new

[Install]
WantedBy=multi-user.target

 

Code:
nano /etc/systemd/system/new-streaming.service

 

Code:
[Unit]
Description=new-streaming
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/new
Environment="NODE_ENV=production"
Environment="PORT=4030" #change the port
EnvironmentFile=/home/mastodon/new/.env.production #add this

Environment="STREAMING_CLUSTER_NUM=1"
ExecStart=/usr/bin/node ./streaming
TimeoutSec=15
Restart=always
# Proc filesystem
ProcSubset=pid
ProtectProc=invisible
# Capabilities
CapabilityBoundingSet=
# Security
NoNewPrivileges=true
# Sandboxing
ProtectSystem=strict
PrivateTmp=true
PrivateDevices=true
PrivateUsers=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictAddressFamilies=AF_INET
RestrictAddressFamilies=AF_INET6
RestrictAddressFamilies=AF_NETLINK
RestrictAddressFamilies=AF_UNIX
RestrictNamespaces=true
LockPersonality=true
RestrictRealtime=true
RestrictSUIDSGID=true
RemoveIPC=true
PrivateMounts=true
ProtectClock=true
# System Call Filtering
SystemCallArchitectures=native
SystemCallFilter=~@cpu-emulation @debug @keyring @ipc @memlock @mount @obsolete @privileged @resources @setuid
SystemCallFilter=pipe
SystemCallFilter=pipe2
ReadWritePaths=/home/mastodon/new

[Install]
WantedBy=multi-user.target

 

Code:
nano /etc/systemd/system/new-sidekiq.service

 

Code:
[Unit]
Description=new-sidekiq
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/new
Environment="RAILS_ENV=production"
Environment="DB_POOL=25"
Environment="MALLOC_ARENA_MAX=2"
Environment="LD_PRELOAD=libjemalloc.so"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 25
TimeoutSec=15
Restart=always
# Proc filesystem
ProcSubset=pid
ProtectProc=invisible
# Capabilities
CapabilityBoundingSet=
# Security
NoNewPrivileges=true
# Sandboxing
ProtectSystem=strict
PrivateTmp=true
PrivateDevices=true
PrivateUsers=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictAddressFamilies=AF_INET
RestrictAddressFamilies=AF_INET6
RestrictAddressFamilies=AF_NETLINK
RestrictAddressFamilies=AF_UNIX
RestrictNamespaces=true
LockPersonality=true
RestrictRealtime=true
RestrictSUIDSGID=true
RemoveIPC=true
PrivateMounts=true
ProtectClock=true
# System Call Filtering
SystemCallArchitectures=native
SystemCallFilter=~@cpu-emulation @debug @keyring @ipc @mount @obsolete @privileged @setuid
SystemCallFilter=@chown
SystemCallFilter=pipe
SystemCallFilter=pipe2
ReadWritePaths=/home/mastodon/new

[Install]
WantedBy=multi-user.target


Reload the systemd daemon:

systemctl daemon-reload


We are not done yet dude

Code:
su - mastodon

 

Code:
cd new
nano .env.production


add this line

Code:
REDIS_NAMESPACE=mstdn-new


Save and exit to root.

Start the services and enable them, so they will start automatically upon the next system reboot:

systemctl start new-web new-sidekiq new-streaming
systemctl enable new-web new-sidekiq new-streaming


If you need to restart the service use:

Code:
systemctl restart new-*.service


Verify if all services are running:

systemctl status new-*.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.

  • mastodon
  • 0 Users Found This Useful
Was this answer helpful?

Related Articles

Installing a Mastodon on Ubuntu Focal Fossa

Update system packages​ apt update && apt upgrade -y   Install fail2ban so it...

Setting up email in Mastodon using an external SMTP server

This is how I got Mastodon to use an external SMTP server to deliver outgoing mail.I received...

How to install glitch-soc version

In this tutorial I will show you how to install mastodon glitch version. Glitch-soc is based on...

Moving or leaving accounts

Exporting your information​   The data export page in settingsAt any time you want, you can...

Mobile & Desktop Apps

Thanks to Mastodon's open API, you can use it from any of these apps developed by third-party...

Powered by WHMCompleteSolution