Applications Azure

Pleroma on Ubuntu 24.04 on Azure User Guide

| Product: Pleroma on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of Pleroma on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. Pleroma is an open source, self hosted social networking server for the Fediverse. It speaks the ActivityPub protocol, so your instance federates with Mastodon, Misskey and the wider fediverse: people on your server follow, reply to and boost posts with accounts anywhere else in the network. It is written in Elixir on PostgreSQL and is deliberately lightweight, so a single small VM comfortably runs a personal server or a small community.

Pleroma serves a familiar microblogging timeline through its built in web interface (pleroma-fe) and is compatible with the Mastodon client API, so most existing mobile and desktop apps work against it directly. You own and control the instance, the data and the moderation, on infrastructure in your own Azure subscription.

The cloudimg image ships the free and open source, AGPL-3.0 licensed Pleroma release, installed the officially supported way from the upstream Erlang/OTP release (pinned by SHA-256), paired with on box PostgreSQL 16. Pleroma binds to the loopback interface only, PostgreSQL never leaves loopback, and nginx terminates TLS as the single public listener. Pleroma ships no default administrator, so this image mints everything unique per VM on first boot: the Phoenix secret_key_base, the session signing salts, the web push (VAPID) keypair, the JWT signer, the PostgreSQL password, the administrator account and password, a self signed TLS certificate, and an outer web credential that gates anonymous access at the proxy. Backed by 24/7 cloudimg support.

Pleroma is a trademark of its respective owner. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by the Pleroma project. It ships the free and open source AGPL-3.0 licensed software, unmodified; the corresponding source is available at https://git.pleroma.social/pleroma/pleroma.

The postgresql, nginx and pleroma services active, with the pleroma-firstboot and pleroma-postboot one shot units having completed

What is included:

  • Pleroma 2.10.2 — the official upstream Erlang/OTP release, pinned by SHA-256, run unmodified under systemd
  • PostgreSQL 16 — the application database, bound to loopback with no host port published
  • nginx — the single public listener, terminating TLS, with the Pleroma server reachable only through it
  • First boot secret generationsecret_key_base, signing salts, web push keypair, JWT signer, database password, administrator account, TLS certificate and web credential, all unique to each VM
  • A bundled self test — logs in as the per instance administrator, posts a status and reads it back from the instance's own timeline, proving the server really works end to end

Prerequisites

  • An Azure subscription with permission to create virtual machines
  • An SSH key pair for administrative access
  • A network security group allowing inbound TCP 22 (SSH) and TCP 443 (HTTPS) from your own address ranges
  • Standard_B2s (2 vCPU, 4 GB RAM) or larger
  • For real federation with other fediverse servers: a public DNS name pointing at the VM and a CA issued TLS certificate (covered in Federation and a real domain below). Pleroma federates by hostname, so a bare IP with a self signed certificate is fine for evaluation but not for joining the wider network.

Step 1: Deploy from the Azure Portal

  1. Open the Azure Marketplace and search for Pleroma on Ubuntu 24.04 LTS by cloudimg.
  2. Select Create, then choose your subscription, resource group and region.
  3. Pick a VM size of Standard_B2s or larger.
  4. Under Administrator account, select SSH public key and supply your public key.
  5. Under Inbound port rules, allow SSH (22) and HTTPS (443).
  6. Select Review + create, then Create.

Step 2: Deploy from the Azure CLI

az group create --name pleroma-rg --location eastus
az vm create \
  --resource-group pleroma-rg \
  --name pleroma-vm \
  --image cloudimg:pleroma-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

az vm open-port --resource-group pleroma-rg --name pleroma-vm --port 443 --priority 1010

Step 3: Connect to your VM

ssh azureuser@<vm-ip>

Step 4: Confirm the services are running

Pleroma runs as a systemd service behind nginx, with PostgreSQL on box. Two one shot units run once on the first boot: pleroma-firstboot mints the per VM secrets and configuration before the server is allowed to start, and pleroma-postboot creates the per VM administrator once the server is up.

systemctl is-active postgresql nginx pleroma

Expected output:

active
active
active

The Pleroma server listens only on the loopback interface, and nginx is the single public listener on ports 80 (which redirects to HTTPS) and 443. Rather than grepping for the ports you expect, list every socket that is bound to something other than loopback, so anything unexpected has nowhere to hide:

sudo ss -ltn | awk 'NR>1{print $4}' | grep -vE '^(127\.|\[::1\])' | sort -u

The only sockets bound off loopback are SSH on 22 and nginx on 80 and 443, with Pleroma and PostgreSQL reachable only on 127.0.0.1

The only entries are 22 (SSH) and 80 and 443 (nginx), on both IPv4 and IPv6. Everything else the image runs, including Pleroma itself on 127.0.0.1:4000, PostgreSQL on 127.0.0.1:5432 and the Erlang port mapper on 127.0.0.1:4369, is bound to loopback and is not reachable from off the box. Because this lists the full set rather than a filtered subset, it is also the check to re run after you install anything else on the VM.

Step 5: Retrieve your per instance credentials

Every VM generates its own secrets and administrator on first boot. They are written to a root only file:

sudo cat /root/pleroma-credentials.txt

This file contains:

  • WEB_USER / WEB_PASSWORD — the outer HTTP Basic credential that gates anonymous access at the nginx proxy
  • ADMIN_USER / ADMIN_EMAIL / ADMIN_PASSWORD — the per instance Pleroma administrator account
  • PLEROMA_URL — the HTTPS URL of your instance

The per VM credentials file showing the web credential, the administrator account and the instance URL, all unique to this VM

Keep this file safe and change the passwords once you have logged in.

Step 6: Understand the security model

Pleroma has no published default administrator — accounts are only ever created explicitly. The security sensitive values that upstream would otherwise leave you to set are all generated uniquely on the first boot of every VM, before the server is reachable:

  • the Phoenix secret_key_base and the session signing salts (which sign and encrypt session cookies)
  • the web push VAPID keypair and the JWT signer
  • the PostgreSQL password
  • the per instance administrator account and password
  • a per instance self signed TLS certificate
  • a per instance web credential for the nginx gate

Because the two layers of authentication (the nginx Basic gate and Pleroma's own account login) both use the HTTP Authorization header, the image configures nginx to let authenticated API traffic (which carries a Bearer token) through to Pleroma's own auth, while challenging anonymous visitors for the web credential — so the web UI, the mobile apps and the API all work normally behind the gate. You can verify the model end to end with the bundled self test, which proves the front door refuses a missing or wrong credential, that a wrong administrator password is rejected, and that a status posted through the real login is read back from the timeline:

sudo /usr/local/sbin/pleroma-roundtrip.sh

The bundled self test posting a status and reading it back from the timeline, and proving the front door refuses missing and wrong credentials

Step 7: Log in to the web interface

Open your instance in a browser:

https://<vm-ip>/

Because the TLS certificate is self signed and per VM, your browser will warn once — accept it to continue (install a CA certificate for a real domain as described below to remove the warning). You then authenticate in two steps:

  1. The browser prompts for the web credential — enter WEB_USER / WEB_PASSWORD from your credentials file.
  2. On the Pleroma sign in page, log in as ADMIN_USER with ADMIN_PASSWORD.

The Pleroma web interface sign in page served over TLS

Once signed in you land on your timeline, ready to post.

The signed in Pleroma timeline showing the administrator account and a published post

Step 8: Post to your timeline

Write a post in the compose box and publish it. It appears immediately on your local timeline, and — once your instance federates (see below) — is delivered to your followers on other fediverse servers.

Composing and publishing a post from the Pleroma web interface

The same works from any Mastodon compatible app: point the app at https://<vm-ip>/ (or your domain), and log in with the administrator account.

The Pleroma about / instance information page showing the instance name and that registrations are closed

Step 9: Manage users from the command line

Self registration is closed by default on this image (it is a single administrator appliance). Create additional accounts, or grant moderator/admin rights, with pleroma_ctl:

# create a regular user (they can log in and post); -y skips the confirmation prompt
sudo -Hu pleroma bash -c 'cd /opt/pleroma && PLEROMA_CONFIG_PATH=/etc/pleroma/config.exs ./bin/pleroma_ctl user new alice alice@example.com --password "$(openssl rand -base64 18)" -y'

To open public registration instead, set registrations_open: true in /etc/pleroma/config.exs and restart Pleroma:

sudo sed -i 's/registrations_open: false/registrations_open: true/' /etc/pleroma/config.exs
sudo systemctl restart pleroma

Federation and a real domain

Pleroma federates by hostname, and every post and account carries the instance's configured URL, so real federation needs a stable public DNS name and a CA issued certificate rather than a bare IP with a self signed certificate.

  1. Point a DNS A record (for example social.example.com) at your VM's public IP.
  2. Set the instance host in /etc/pleroma/config.exs:

elixir config :pleroma, Pleroma.Web.Endpoint, url: [host: "social.example.com", scheme: "https", port: 443] 3. Issue a real certificate (for example with Certbot) and point nginx at it in /etc/nginx/sites-available/pleroma, then reload nginx. 4. Restart Pleroma: sudo systemctl restart pleroma.

Because federation identifiers are derived from the hostname, choose your domain before you start following accounts elsewhere — changing it afterwards breaks existing federation.

Backups

All state lives in PostgreSQL on box and in the uploads directory. To back up:

sudo -u postgres pg_dump pleroma | gzip > pleroma-$(date +%F).sql.gz
sudo tar czf pleroma-uploads-$(date +%F).tar.gz -C /var/lib/pleroma uploads

Store both off the VM.

Support

Every cloudimg image includes 24/7 support and is tested against the exact build you launch. If anything in this guide does not match what you see, contact cloudimg support.