Technology

Multiple Mastodon Instances on a Single Server

| #linux | #mastodon | #nginx | #Tech |


I run a Mastodon instance, and for several reasons it didn’t really take off. I was going to shut it down but I sort of like having my own outpost in the fediverse. When I decided the domain name it was hogging was better used for a new project, I wanted to move the instance to a subdomain. Rather than nfg.zone, I wanted it on mstdn.nfg.zone, and for anything that isn’t Mastodon this is a simple thing to do.

Two Mastodons, One Server

I needed to run them both at the same time for a transition period, while any followers easily made the switch to the new domain.  I didn’t want my server to run two whole Mastodon installs, and so my goal was to re-use as much existing infrastructure as I could.

I knew the Postgres database server could be re-used, but what about redis? The Mastodon app directory? The Linux user? How much separation needed to exist between the instances?

I’ll save you the pain of working it out: the only thing you need to run two instances on one machine is:

  • a new database
  • a new .env config file
  • a new nginx config block for the new subdomain
  • two sets of the three Mastodon services (Streaming, Sidekiq and Web)

A New Database

If you run the Mastodon setup wizard it’ll create a new .env.production file, create an admin user, set up the database, etc. Do this, but make sure you’ve backed up your .env config file first. By default, it’s ~/live/.env.production. To run it, go to your Mastodon install directory ( ~/live/ ) and start the wizard:

RAILS_ENV=production bundle exec rake mastodon:setup 

Pretty much everything remains the same, but you need to specify a new database name (the default is Mastodon_Production).  All your ports and users remain the same.

You can edit this file manually later.  For whatever reason, my new file didn’t include a lot of stuff the old one did, so you can copy it from the working file to the new one.

Note!  The different DB name means an extra step when you perform an update that requires a database update.  The command is the same, with a new bit in the middle that specifies the new database name.  DB_NAME=<new database>

RAILS_ENV=production DB_NAME=database bundle exec rails db:migrate

A New .env file

Now that the wizard has created another .env.production file, sort it out.  The new file, .env.production, should be renamed to something new (like .env.new) and the one you backed up re-named to .env.production so your existing instance doesn’t fall over.

You’ll need to add three new lines to your new instance .env file.

PAPERCLIP_ROOT_PATH=/home/mastodon/live/public/system-new
PAPERCLIP_ROOT_URL=/system-new
REDIS_NAMESPACE=mstdn-new

By default, the new instance will store all its incoming media in the same directory as the existing instance ( live/public/system/ ) but I wanted mine separate so I could nuke the old stuff when the old instance went dark.  The Paperclip directives change the storage location to the directory you indicate.

Also, a new Redis namespace so the two instances don’t smash into each other.

While running the initial config of the new instance I had some content land in the old system directory before I put these directives in the .env file, and that resulted in content being in two places.  If this happens to you, the following nginx block will have nginx check both locations for the desired content until you can fix the problem files:

location ~ ^/system-new/(.*) {
try_files /system-new/$1 /system/$1;
}

Nginx Server Config

Load up your nginx config, which is normally /etc/nginx/nginx.conf.

First, Copy the existing server block and then change the server name to wherever your new instance will live (ie: mstdn.nfg.zone).

Next, find and change the two ports in the new server block.  By default they’re location @proxy and location /api/v1/streaming, ports 3000 and 4000 respectively.  They can be whatever you like, but I just changed them to 3001 and 4001.

Two sets of services

Copy and edit every service file (they’re in /etc/systemd/system/ and are normally called mastodon-something.service).  Change the names, obviously.

Environment="PORT=3001"
EnvironmentFile=/home/mastodon/live/.env.newfile
  1. Change any ports to the new ones in nginx.conf
  2. Indicate the location of the new .env config file

Once the new service files exist, register them and start them up, as detailed in the official install guide.

That’s it!

If you need to make changes to the service files, you’ll need to reload them:

sudo systemctl daemon-reload

then restart them:

sudo systemctl restart mastodon-*.service

Or, you know, whatever you named your new services.  To restart Mastodon if you’ve changed the .env file, just restart the services.

--NFG
[ Jul 10 2018 ]
Navigation

Comments

Dave Thomas

Mar 24 2023

This worked perfectly for me and both instances have been stable for 4 months. INSTANCE A (mast.thomasdmn.net) performs fine and tootctl media remove keeps it clean at 33.5GB paperclip storage reported in administration and confirmed 33.8GB with NCDU.

INSTANCE B (mas.greatlakes.club) is bloating massively. administration page shows 35.5GB NCDU shows 172.5 GB in /mnt/greatlakes/live/public

RAILS_ENV=production DB_NAME=mastodon_greatlakes bin/tootctl media remove
runs weekly and kills around 5GB regularly

tried to run media remove-orphans and it nuked INSTANCE A avatars before i quit it.
seems remove-orphans does not obey the DB_NAME= switch and I can’t see any other way to make it look for and obey the PAPERCLIP_ROOT_PATH in the second instance .env.production.greatlakes file.

As you document above, there is one Mastodon install (/home/mastodon/live/) and there are two separate paperclip folders. Mastodon works properly for both but instance B is bloating steadily every week.

How do you keep the newer instance clean?

    NFG

    Mar 28 2023

    Alas, I long ago gave up on running a Mastodon server. I can’t help you with this. =/

Takumiboo

Apr 13 2023

I tried it and successfull with “DB_NAME=” option.


Got something to add?

Your Comment
Name:
Email:
Website: