My little GoToSocial installation tweaks

I started hosting my own GoToSocial instance this weekend and "bravely" moved from the old instance immediately. Configuration was straightforward operation, I mostly just followed upstream documentation and went with defaults. I do have some opinions how I like to maintain servers, so "obviously" I had to tweak things a little regarding how and where things are installed.

This post is mostly about those little tweaks. So basically thoughts about how I want to install software that is not packaged for distribution server is running and how I applied that to GoToSocial.

What upstream GoToSocial recommends

Steps from installation and configuration steps could be summarized to this:

  1. download and extract release tarball to /gotosocial
  2. copy /gotosocial/example/config.yaml to /gotosocial/config.yaml and edit according to the documentation
  3. copy /gotosocial/example/gotosocial.service to /etc/systemd/system/gotosocial.service and edit according to the documentation
  4. systemd service sets working directory to /gotosocial and all state is stored there
  5. when updating, extract new tarball on top of the /gotosocial

Now, these are wonderfully simple instructions for people who do not have that much experience about CLI or maintaining servers. I really like that! It is a really, really lovely that hosting this kind of nontrivial service is made to be approachable as possible.

I just have opinions how I want my servers to look like, which differs from that.

Why I want something different?

I want to be able to roll back to older release if there are problems. Obviously it probably is not going to be possible with GoToSocial which is often running big database migrations between updates and is pre-1.0. I still like to approach the installation like I could do rollbacks for consistency’s sake.

With software packaged for the distribution, downgrade is just simple pacman/apt/dnf incantation. With non-packaged software some work is needed to get there, I need to keep old versions around and make it relatively easy to switch between them. For the most recoverable solution I would do something like this:

With that setup both bundles and configurations can be rolled back, together or individually.

I don't bother going that complicated with my own server setup as these are rather simple and slow moving targets where I don't need to recover catastrophes fast. Those capabilities are really handy in work context though!

Other approach would be to package software by myself. I just find above approach be less painful than trying to get apt/rpm tooling happy. Or use containers. Containers are just are still in a phase where setup breaks after every distro upgrade. That is not something I want to deal with in server I maintain with my free time and where I don't benefit from the flexibility of containerization.

Ansiblefy everything

I might not be big fan of Ansible, but it is rather pragmatic and widely used tool. It is also a tool that I am somewhat familiar with, and it breaks in expected ways.

So my ansiblefied install/upgrade flow for GoToSocial this:

  1. download and extract release to /opt/gotosocial/<version>
  2. generate /etc/gotosocial/config.yaml from jinja template, required to parametrize following config options:
  3. generate /etc/systemd/system/gotosocial.service from jinja template, required to parametrize ExecStart to point to the correct /opt/gotosocial/<version>/gotosocial binary

Of course there is a bit more fluff around that to make sure required directories exist, have proper access rights, (re)starts happen, etc. But that is something I cannot avoid with the more manual approach either.

Now updates are just "read release notes for special steps", put new version number into playbook and few moments later a brand new service is running.