Recently the new #Mastodon v4.2.5 was announced and with it the urge of a security fix. In a previous article I explained a strategy to keep the code customised and up to date, and even working with #git is part of my daily work, I feel like explaining in detail the process so that I will remember it for future references and also may help anybody that has the instance somewhat customised.


Here I explain the steps how to get the code for the new v4.2.5 version that just got released, create a merging branch to ensure that the changes work for us and to finally merge them to our production branch.

I’ve divided the process into the following sections:

  1. What are we doing here?
  2. Get the new code into our fork
  3. Get that new code into our local
  4. Pre-merge the changes
  5. Test
  6. Merge the changes into our Production
  7. Leaving everything tidy and clean
  8. One last note: DB migrations
  9. Wrapping up

0. What are we doing here?

This article is a continuation of the previous Migrate a Mastodon instance from a Raspberry Pi 4 to a Raspberry Pi 5 under Docker, where I introduced a fork and customise strategy to keep the code updated, customised and registered in GitHub.

To refresh the concept a bit, let me just grab the graphic from the previous article: Fork%20Git%20branches%20strategy-5

In the previous article we focused on getting the last Mastodon code and apply on top the customisations. We've been good with it until now.

Here we're now in the point 6, where we realise that Mastodon brings a new version and we want to update our forked repository and merge these changes into our customised code base.

1. Get the new code into our fork

My fork lives in my GitHub account. For this step I only go there and click on the Sync fork button, and there click the green button Update branch. This will bring the last changes from the original Mastodon repository to my fork's main branch.


2. Get that new code into our local

The changes are now in my remote repository. Let’s SSH into the cloned repository in the Raspberry Pi. What we want is to bring the changes there so we can start the merging process.

  1. SSH into the Raspberry Pi and move into the instance directory

    ssh xavi@jakku
    cd ~/
  2. Checkout the main branch, it’s where the new code lives in the remote repository.

    git checkout main
  3. Pull the last changes

    git pull
  4. Fetch the code that is specifically tagged by the version v4.2.5 into a local branch called local-v4.2.5 that we can relate later on.

    git fetch origin v4.2.5:local-v4.2.5

Now we have the changes for the version v4.2.5 in a specific local branch.

3. Pre-merge the changes and test

What we do now is to create a new branch starting from our production, that contains already all customisations merged with what until now was the latest code. This means that we start from already finished code, where we only want to add the latest changes.

  1. Change to the production branch

    git checkout production/
  2. Create a new branch from it that will be used to merge all code there.

    git checkout -b merging/v4.2.5
  3. Finally, bring there the code from our local-v4.2.5 branch we did in the previous section

    git merge local-v4.2.5

This step is the one that may bring issues. I did not have any problems this time, but it could be when the new changes actually breaks our code, or we face conflicts that we have to solve. The good point is that whatever happens here, it does not affect the state of our production, so we can always abort and checkout a clean state, and perform that merge with calm.

4. Test

At this point our local repository is in a branch where we have our customisations AND the 4.2.5 code merged. I did not have any obvious issue, but I still won't merge into the production branch. I want to test that everything works, so I generate a new Docker image first:

docker build . -t mastodon:20240201  -f Dockerfile

Then I update the docker compose file to use this new local image

nano docker-compose.yml

Then I stop the instance

docker compose down

And I start it again. Now it will run with the new image with the v4.2.5 changes

docker compose up -d

Here I check that the instance works, customisations are still there, and that in the About page we have the new v4.2.5 version stated at the bottom.


It works!

5. Merge the changes into our Production

Everythng works, so I merge the current merging branch into production. But first, we need to undo the changes we just did on the docker-compose.yml, otherwise git will complain saying that we have uncommitted changes:

git checkout docker-compose.yml

And now yes, let’s move to the production branch and merge there the changes living in the merging branch.

git checkout production/
git merge merging/v4.2.5

Finally, send this changes to our upstream, so they are secure out of this host

git push upstream

We have now the production branch with all final code and customisations accumulated there, and the code safe somewhere else 🎉

6. Leaving everything tidy and clean

We could stop here, but we’re good engineers, so we want to leave the work finished and with a lace.

6.1. Upload the Docker image into Docker Hub.

We generated the image based on the code in the merging branch, that is the same we have now in production, so the image does not need to be generated again. Still, I like to have it submitted outside the host, so I just push the image into Docker Hub

  1. Login to Docker hub
    docker login
  2. Retag the image so it fits in the artifactory format
    docker tag mastodon:20240201 arnaus/mastodon:talamanca_rpi5_4.2.5
  3. Push the image
    docker push arnaus/mastodon:talamanca_rpi5_4.2.5

And edit again the docker-compose.yml file to specify this image in the web, streaming and sidekiq containers, and leave the instance ready for normal functioning.

6.2. Delete the branches that we don’t need anymore

Once all the process is completed, there is a bunch of branches that we don’t need, they were helpful and now not anymore. Let’s clean!

  1. List the branches that we have in our local

    $ git branch
    * production/
  2. Remove the 2 branches that relate to 4.2.5 code

    $ git branch --delete local-v4.2.5
    Deleted branch local-v4.2.5 (was a6641f828).
    $ git branch --delete merging/v4.2.5
    Deleted branch merging/v4.2.5 (was e3bf59b72).

7. One last note: DB migrations

I updated this article to add this section, as I realised in further updates that I can still follow this instructions point per point just keeping an eye on the version numbers, and a step that I did not mention was the migrations, because in the v4.2.5 was not needed.

Once updated, going into the Administration in the Preferences one can observe a yellow message requesting to apply the pending DB migrations if they exist. This is achieved by simply calling a command to be run inside the web container, so let's SSH into the host and move ourselves into the instance's directory. Then we run:

sudo docker compose run --rm web rails db:migrate

This command instantiates a web container, runs the rails db:migrate command and will destroy it once it finishes. Easy peasy.

8. Wrapping up

The process is not really complicated, but it’s true that it is relying on knowledge of git. Conceptually, we’re just bringing the changes from the original Mastodon repository to our forked one, and merge it in a controlled way so that we have always a way out in case of any catastrophe.

All in all, it did not take me more than 30 minutes including the build of the new Docker image, in a Raspberry Pi 5.

Happy tinkering!

Previous Post Next Post