Not so long since I decided to try out installing my own Mastodon instance, a new version was rolled out. For what I could see in other instances where they were already playing with the RC, it brings some new features and security fixes, and well... why not?

I need to mention that for this process I followed this blog post that I found fitting to my current setup. It's always comfortable to know that someone did the same successfully, isn't it?

Steps overview

We're starting from a working Mastodon instance 3.5.3 on a Debian 11 hosted in a Droplet in DigitalOcean. The steps we'll do here are toe following:

  1. Update the Ruby version to 3.0.4
  2. Get the Mastodon 4.0.2
  3. Update dependencies, apply DB migrations and compile assets
  4. Bring back the server!


I am removing any info about IPs and users, more than the needed by the normal mastodon setup, but never actually referring to my infrastructure. Assume user@talamanca as the user and the machine IP where I have my instance.

0. Take a snapshot

You never know... And DigitalOcean makes some things so uncomplicated... So why not just snapshot the current setup in case we need to roll back? To do so, it is important to first shut down the machine to care about data consistency, so:

  1. SSH to the droplet and power it off
    $ ssh user@talamanca
    $ poweroff
  2. Log in into the DigitalOcean account in the browser
  3. Go to the Droplet > Snapshots
  4. Set a name for the snapshot and press "Take live snapshot". It will take some minutes.
  5. Once it's finished, go to Power and press "Turn on"

At this point I'd normally ssh into my droplet and restart the services with the following commands, but I won't do so as my droplet has only 2GB of RAM and I will need every single one for the upgrade process. So if the first meaningful step is actually to stop the service, I just call it done and jump to the next one 😉

$ RAILS_ENV=production systemctl start mastodon-web
$ RAILS_ENV=production systemctl start mastodon-streaming
$ RAILS_ENV=production systemctl start mastodon-sidekiq

1. SSH into the droplet

$ ssh user@talamanca

2. Shutdown the Mastodon services

$ systemctl stop mastodon-*.service

3. Change to the mastodon user

$ su - mastodon

4. Change to the live directory

$ cd live

5. Update Ruby to version 3.0.4

This is actually a pity, first because I installed my mastodon instance using the ruby version 3.0.3 and second because I don't like to have multitude of language versions coexisting in the same environment... But anyways:

$ rbenv install --verbose 3.0.4

This process downloads and compiles the ruby version in our system. It will take a while, and will throw several warning messages, but we wanted it verbose, right? When it finishes, we just set this version as the global one for the system:

$ rbenv global 3.0.4

6. Quickly backup your personalizations!

oops! I was about to go for the next steps and luckily I checked what is the git status, yeah, kinda automatic as I am a developer... and luckily I caught some images I use to personalize my instance, that I quickly backup!

To see what do you have not actually covered by the code:

$ git status

You should not get anything in red. I copied out some files:

$ cp public/favicon.ico ../.

and cleaned the cloned repo, just in case:

$ git checkout public/favicon.ico

Now I check again and appears a calmy message:

$ git status
nothing to commit, working tree clean

7. Get the Mastodon 4.0.2 from the git repository

Now it's time to checkout the tag of the new version

$ git fetch && git checkout v4.0.2

8. Install the dependencies

Now we need to get the dependencies for this new version. These 2 commands one after the other.

$ bundle install
$ yarn install

It will also take a while, getting and installing all new packages.

9. Run the DB migrations

So new version means usually changes in the DB, here we apply them. Just make sure we skip the migrations belonging to de deployment.

$ SKIP_POST_DEPLOYMENT_MIGRATIONS=true RAILS_ENV=production bundle exec rails db:migrate

10. Precompile the assets

Next step is to prepare the assets to be used in frontend:

$ RAILS_ENV=production bundle exec rails assets:precompile

11. Restart the Mastodon services

So, let's back to business. Exit the mastodon user and start the services:

$ systemctl start mastodon-web
$ systemctl start mastodon-streaming
$ systemctl start mastodon-sidekiq

Here the blog post I was following mentioned to run the migrations again, which didn't make too much sense to me and I skipped it. But I discovered that I was wrong: this last migration step is the one that moves the accounts to the new Roles system. I spent a good hour trying to know why my account was not Admin anymore, browsing through reported (and merged!) bugs, until I entered into the DB and listed the User Roles table... which was empty, and anyhow it linked my brain to the migration step I just skipped.

So after all the steps, enter again into the mastodon user and move to the live directory:

$ su - mastodon
$ cd live

and execute the migration:

$ RAILS_ENV=production bundle exec rails db:migrate

et voilà! Our user now has the Admin rights and everything seems to be back to normal. I would then request the next guy to try the step 9 without the SKIP_POST_DEPLOYMENT_MIGRATIONS=true option and see if then you need to repeat the migration at the end of the process or not.


To be honest, the process went very smooth, with no issues at all. I was expecting any crash due to the low amount of RAM that my Droplet has, or anything popping up once I start the services again, but nope, all smooth.

All in all, the process took me not more than 30 minutes, including the waiting time during the snapshot creation. Then I had that fail regarding the skipped migration, but I put it more into my fault.

Now all I want is to spend some time discovering all that comes with the new version!

Previous Post Next Post