Deployment guide

Mastodon

Overview

Mastodon is the reference open-source server for the fediverse. It is a self-hosted, federated social network that speaks ActivityPub, so your instance can interoperate with thousands of others. It is a Ruby on Rails application served by Puma, with a Node.js streaming API for real-time timelines, Sidekiq background workers, PostgreSQL for storage and Redis for caching and queues.

The SecureAnyCloud image installs Mastodon 4.6.3 the official "install from source" way (Ruby 4.0.5 via rbenv, Node.js 24, PostgreSQL 16, Redis and nginx). It keeps the database and uploaded media on a dedicated Azure data disk. It generates every cryptographic secret, plus the initial Owner account, uniquely on the first boot of each VM.

What you get:

  • Mastodon 4.6.3 installed from source (AGPL-3.0), built on Ruby 4.0.5, Node.js 24 and yarn 4.16
  • Three systemd services running as the unprivileged mastodon user, loopback only: mastodon-web (Puma), mastodon-streaming@4000 (Node streaming API) and mastodon-sidekiq (workers)
  • PostgreSQL 16 and Redis bound to loopback, with nginx fronting the app. nginx serves an unauthenticated :80/healthz and the full web UI on :443
  • All per-VM secrets generated on first boot: SECRET_KEY_BASE, OTP_SECRET, the VAPID keypair, the ActiveRecord-encryption keys and the PostgreSQL password. None are baked into the image
  • A per-VM Owner account created on first boot (via tootctl) and recorded in a root-only credentials file, plus a per-VM self-signed TLS certificate
  • A dedicated 20 GiB Azure data disk at /var/lib/mastodon-data holding the PostgreSQL cluster and public/system media, captured into the image and re-provisioned with every VM
  • 24/7 SecureAnyCloud support

Prerequisites

  • An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region
  • Standard_D4s_v5 (4 vCPU / 16 GiB RAM) as the recommended size. Mastodon runs five services plus PostgreSQL and Redis, so do not go below 8 GiB of RAM
  • NSG inbound rules that allow 22/tcp from your management network, and 80/tcp and 443/tcp for the web interface

The appliance serves HTTPS on port 443 with a per-VM self-signed certificate, so the UI works immediately. For production, install your own certificate and domain (see "Set your own domain").

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Mastodon by SecureAnyCloud, and select Create.

On the Basics tab, pick your subscription, resource group, region and size (Standard_D4s_v5). Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22), HTTP (80) and HTTPS (443).

Review the dedicated data disk on the Disks tab. Then choose Review + create, followed by Create.

Step 2 - Deploy from the Azure CLI

Accept the Marketplace terms once per subscription, create the VM, then open ports 80 and 443.

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:mastodon-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name mastodon \
  --image sac1647283583153:mastodon-ubuntu-24-04:default:latest \
  --size Standard_D4s_v5 \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name mastodon --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name mastodon --port 443 --priority 1011

Step 3 - Connect to your VM

Connect over SSH as azureuser.

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

On first boot, the image generates the per-VM secrets, sets LOCAL_DOMAIN to the VM public IP, creates the Owner account and starts the stack. Confirm all six services are active and bound to loopback.

systemctl is-active postgresql redis-server nginx mastodon-web mastodon-sidekiq mastodon-streaming@4000
sudo ss -tlnp | grep -E ':80 |:443 |:3000 |:4000 |:5432 |:6379 '

Step 5 - Check the health endpoints

Check the three health endpoints. The unauthenticated :80/healthz returns 200 for load-balancer probes. The app exposes /health, and the streaming API has its own health endpoint.

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/healthz
curl -s http://127.0.0.1:3000/health
curl -sk https://127.0.0.1/api/v1/streaming/health

Step 6 - Retrieve the per-VM Owner credentials

Read the credentials file. The Owner account and a strong password are generated on first boot and written to a root-only file. The .env.production secrets are unique to this VM and never leave it.

sudo cat /root/mastodon-credentials.txt

The file records the web URL, the Owner e-mail and the password. The PostgreSQL cluster and media live on the dedicated data disk. Check the mount.

findmnt -no SOURCE,TARGET,FSTYPE /var/lib/mastodon-data

Step 7 - Sign in to the web interface

Browse to https://<vm-public-ip>/ and sign in with the Owner e-mail and password from the credentials file. Your browser warns about the self-signed certificate on first visit. This is expected until you install your own certificate.

The home timeline, the compose box and your profile are the standard Mastodon web UI.

Step 8 - Set your own domain (do this BEFORE creating content)

This is the most important step. Mastodon bakes LOCAL_DOMAIN into accounts, posts and federation identifiers at setup, and cannot cleanly change it later. The appliance boots with LOCAL_DOMAIN set to the VM IP purely so you can evaluate the software. Set your own domain before you create real accounts or content, and before you federate.

  • Point a DNS record (for example social.example.com) at the VM public IP.
  • Edit /home/mastodon/live/.env.production and set LOCAL_DOMAIN and WEB_DOMAIN to your domain.
  • Install a real TLS certificate (for example with certbot), reference it in /etc/nginx/sites-available/mastodon, then reload nginx.
  • Add your SMTP server settings (SMTP_SERVER, SMTP_PORT, SMTP_LOGIN, SMTP_PASSWORD, SMTP_FROM_ADDRESS) so users receive confirmation and notification e-mails.
  • Restart the services so the new configuration takes effect.
sudo systemctl restart mastodon-web mastodon-sidekiq mastodon-streaming@4000 nginx

Federation with the fediverse requires a real domain and a valid TLS certificate. A bare IP is only suitable for evaluating the software.

Step 9 - Administration dashboard

Sign in as the Owner and open Preferences, then Administration, to reach the server dashboard. The dashboard covers user and content moderation, server rules, custom emoji, federation controls and instance settings.

Maintenance and production notes

  • Object storage and disk size: A real instance accumulates a large volume of federated media. The 20 GiB data disk is sized for evaluation. For production, attach a larger disk and configure S3-compatible object storage with the S3_* variables in .env.production.
  • tootctl: Run the tootctl command as the mastodon user from /home/mastodon/live to manage accounts, media, search indexing and maintenance tasks.
  • Backups: Back up the PostgreSQL database and /home/mastodon/live/public/system (or your object storage bucket) regularly.
  • Updates: Apply OS security updates with sudo apt update && sudo apt upgrade. Mastodon version upgrades follow the upstream release notes.
  • Security: The appliance ships no default credentials. Every secret and the Owner account are generated uniquely per VM on first boot. Keep /root/mastodon-credentials.txt protected, and rotate the Owner password after first sign-in.

Mastodon is free software licensed under the AGPL-3.0. This image is produced by SecureAnyCloud and is not affiliated with, sponsored by, or endorsed by Mastodon gGmbH. "Mastodon" is a trademark of Mastodon gGmbH.

Deploy on Azure

Launch Mastodon on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure