Mastodon on Ubuntu 24.04 on Azure User Guide
Overview
Mastodon is the reference open-source server for the fediverse: 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 cloudimg 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), keeps the database and uploaded media on a dedicated Azure data disk, and generates every cryptographic secret plus the initial Owner account uniquely on the first boot of each VM. Backed by 24/7 cloudimg support.
What is included:
- 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
mastodonuser, loopback only:mastodon-web(Puma),mastodon-streaming@4000(Node streaming API) andmastodon-sidekiq(workers) - PostgreSQL 16 and Redis bound to loopback; nginx fronting the app with an unauthenticated
:80/healthzand 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-dataholding the PostgreSQL cluster andpublic/systemmedia, captured into the image and re-provisioned with every VM - 24/7 cloudimg 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) is the recommended size - Mastodon runs five services plus PostgreSQL and Redis, so do not go below 8 GiB of RAM. NSG inbound: allow 22/tcp from your management network, and 80/tcp + 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 you 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 cloudimg, and select Create. On Basics 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 Review + create -> Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name mastodon \
--image <marketplace-image-urn> \
--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
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
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
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 password. The PostgreSQL cluster and media live on the dedicated data disk:
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 will warn about the self-signed certificate on first visit - that 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 as an evaluation placeholder. Before you create real accounts or content, and before you federate, set your own domain:
- Point a DNS record (for example
social.example.com) at the VM public IP. - Edit
/home/mastodon/live/.env.productionand setLOCAL_DOMAINandWEB_DOMAINto your domain. - Install a real TLS certificate (for example with
certbot) and 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
As the Owner, open Preferences -> Administration to reach the server dashboard: 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 object storage (S3-compatible) via the
S3_*variables in.env.production. tootctl: thetootctlcommand (run as themastodonuser from/home/mastodon/live) manages 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.txtprotected and rotate the Owner password after first sign-in.
Mastodon is free software licensed under the AGPL-3.0. This image is produced by cloudimg and is not affiliated with, sponsored by, or endorsed by Mastodon gGmbH. "Mastodon" is a trademark of Mastodon gGmbH.