Simple Mastodon Node Deployment on Azure

Itay Podhajcer
Microsoft Azure
Published in
3 min readMar 15, 2023

Mastodon is a decentralized social media network that lets users create and join various communities of their choice. Mastodon also supports several types of content, such as audio, video, picture, polls, and more, to help users express themselves online. Mastodon values users’ privacy and freedom of expression by allowing them to choose who can see their posts and who can interact with them. Mastodon allows anyone to run their own server instance and join the network of millions of users, which is exactly what we will be doing in this article.

Prerequisites

Will be using Terraform and its azurerm provider to deploy the Mastodon instance, so we will be needing the following installed on our workstation:

  • Terraform: installation guide is here.
  • Azure CLI: installation guide is here.

Example Repository

A complete Terraform script that creates a resource group and deploys the Mastodon instance using an Azure Container Instances container group, is available in the following GitHub repository:

Deployment Script

This script deploys a simple Mastodon instance that can be used for testing purposes, so we will be keeping it as simple as possible, and that’s why will be using Azure Container Instances to do that.

Also, we will be using Bitnami’s Mastodon image and not the tootsuite/mastodon image, as it is more automated deployment friendly (the tootsuite image requires running a manual wizard as part of the deployment process).

We’ll start by creating a few locals (deployment name, database user, mastodon user and Mastodon email), a resource group and passwords (for the database, Elasticsearch and Mastodon admin user):

Next will create the Azure Container Instances resource and expose the ports 3000 and 4000 for Mastodon web container and the Mastodon streaming container (we will be defining the actual containers inside next):

Now we can add the required containers, which are:

  • A PostgreSQL database instance
  • An Elasticsearch instance
  • A Redis instance
  • A Mastodon web instance — processes short-lived HTTP requests,
  • A Mastodon streaming instance — handles long-lived WebSocket connections for real-time udpates.
  • A Mastodon sidekiq instance — handles background processing such as emails, media files and delivering posts to other servers.

The database container:

The Elasticsearch container:

The Redis container:

The Mastodon web container:

The Mastodon streaming container:

And lastly, the Mastodon sidekiq container:

A few notes:

  • The PostgreSQL, Elasticsearch and Redis container all have a dedicated Empty Dir volume.
  • The Mastodon web and sidekiq containers have a shred Empty Dir volume.
  • Containers inside an Azure Container Instances group communicate with each other using localhost.

Testing The Deployment

Execute terraform apply, wait for the script to complete, and then let the Mastodon web container run all the initial migrations (this can take a few minutes, you can track the logs from Azure’s portal). Once the migrations are complete, the server will be available through the Azure Container Instances resource FQDN on port 3000.

Conclusion

The tradeoff of this deployment, being this simple, is that it’s not recommended for a production deployment, as the volumes won’t persist if the containers are stopped. Also, because the Bitnami images use a non-root user, we cannot use Azure Files as volume mounts (they can only be accessed by container running with root), meaning, different services will be required to run the containers (such as Azure Kubernetes Service or Azure Container Apps, which are more complex) and maybe even use Azure managed services for PostgreSQL and Redis.

--

--

Itay Podhajcer
Microsoft Azure

Former Microsoft MVP | Highly experienced software development & technology professional; consultant, architect & project manager