I’ve not always wanted to bring up a Mastodon instance for it was not that intriguing to me, until recently Musk has worked on Twitter in an amateur way.

On the other hand, to host an instance of my own is a way of paying tribute to the past ‘90s self-host Email compaign which I was too young and poor to have the chance to experience. At least for now, we are seeing a blooming new way of social networking, whether or not a long-term fight against spam and junk information in the future awaits.

https://twitter.com/mogita/status/1605188553423536134

I’ll open source my setup. You can skip to the Code section to see the project.

You can also check out my instance @[email protected]. I’m always ready for a little chat.

How To Run Link to heading

I’m going to serve my Mastodon instance through Docker with docker-compose for an easier and consistent management workflow.

What To Include Link to heading

Inside the docker-compose.yml file I’ll put these components:

  • Mastodon web: tootsuite/mastodon:latest + ES analyzer tweak (for indexing non-English languages)
  • Database: postgres:14-alpine
  • Redis: redis:7-alpine
  • ElasticSearch: elasticsearch:7.17.8 + ik + stconvert
  • Streaming: tootsuite/mastodon:latest
  • Sidekiq: tootsuite/mastodon:latest
  • Nginx: nginx:latest

ES Analyzer Tweak Link to heading

A vanilla Mastodon instance is fairly easy to setup from the basic versions of the said docker images. However, adding optimization for other languages in its search functionality requires code modification which would impair the simplicity of just following the minimum workflow. Hope this necessity can be replaced with a more proper way, like configurable through .env.

At the time of writing, there are 3 steps according to the official documentation:

  1. Install ES plugin https://github.com/medcl/elasticsearch-analysis-ik
  2. Install ES plugin https://github.com/medcl/elasticsearch-analysis-stconvert
  3. Modify Mastodon’s source code on index definition

Previous 2 steps can be achieved relatively easier. Just create a Dockerfile for a custom ES build and make the installation on the official ES image. Pay attention to the version consistency though.

As of step 3, I’ll patch the diff code provided by the documentation. Nonetheless a custom image is necessary too.

To sum up, I’ll need to build 2 images:

  • A custom Mastodon image for: Mastodon web, Streaming and Sidekiq
  • A custom ElasticSearch image for: ElasticSearch with non-English languages support

Miscellaneous Link to heading

HTTPS Support Link to heading

My Mastodon setup will enjoy the benefits from nginx-proxy and acme-companion for automatic SSL certificates challenging and renewal. This is why I have an Nginx component on the list. It’s the reverse proxy to handle SSL traffic.

Object Storage Support Link to heading

Using a cheap S3 compatible object storage service is my go-to plan on a minimum user base. Having it gone through a Cloudflare CDN might help with lowering the bandwidth cost too.

Email Relay Link to heading

Google Workplace SMTP relay service is my first choice since I’m on a business plan. For free alternatives, any relay service shall do and many offer a free amount for around 100 or more Emails per day.

Backups Link to heading

Since the object storage will be used, the only critical thing to backup is the database. A script that sends a daily pg_dump archive to one of my storage service provider shall do. If things go crazy in the future, like I’ll need to host the instance for hundreds of users, then master-slave replica might be useful as an additional measurement.

Scaling Link to heading

No need to consider right now. Cost effectivity, on the contrary, shall be my first priority given the instance being invitation only.

Code Link to heading

I named my Mastodon setup project the monsts, it stands for “Mastodon Of Not So Typical Setup”.

You can browse the source code here: https://gitlab.com/mogita/monsts