Mailpit on Ubuntu 24.04 on Azure User Guide
Overview
Mailpit is a small, fast, self-hosted email and SMTP testing tool for developers. It runs a fake SMTP server that catches every message your application sends, stores each one, and shows it in a modern web interface where you can read the HTML, plain text and raw source, inspect headers and attachments, run HTML and link checks, and release messages onward when you choose. Because Mailpit never delivers mail externally, it is completely safe to point your development and staging applications at it: nothing ever reaches a real inbox. The cloudimg image installs the pinned Mailpit 1.30.3 static binary, runs it as a dedicated mailpit system user under systemd, and fronts its web UI on port 80 with an nginx reverse proxy configured for the WebSocket the live message list uses. The SMTP listener is exposed on port 25 for your applications, the SQLite message store lives on a dedicated Azure data disk, and a unique web UI password is generated on the first boot of every VM. Backed by 24/7 cloudimg support.
What is included:
- Mailpit 1.30.3 (single static Go binary) running as the
mailpitsystemd service - A fake SMTP server on
:25that captures every message your apps send and never delivers externally - The Mailpit web UI on
:80, fronted by nginx with the WebSocket upgrade proxied - HTTP Basic Auth protecting the web UI and REST API, with a unique password generated on first boot
- A dedicated Azure data disk at
/var/lib/mailpitholding the SQLite message store mailpit.service+nginx.serviceas systemd units, enabled and active- An unauthenticated
/healthzendpoint for Azure Load Balancer health probes - 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting point; Mailpit is very light on resources. NSG inbound: allow 22/tcp from your management network, 80/tcp for the web UI, 443/tcp if you add TLS, and 25/tcp from the networks that run the applications under test so they can deliver mail to Mailpit. Mailpit serves plain HTTP on port 80; for production-adjacent use, terminate TLS in front of it with your own domain (see Maintenance).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Mailpit by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). After creation, add an inbound NSG rule for SMTP (25) from your application networks. 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 mailpit \
--image <marketplace-image-urn> \
--size Standard_B2s \
--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 mailpit --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name mailpit --port 25 --priority 1020
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm the services are running
systemctl is-active mailpit.service nginx.service
Both report active. Mailpit listens for SMTP on 0.0.0.0:25 and serves its web UI and REST API on the loopback connector 127.0.0.1:8025; nginx fronts the UI on port 80 with the WebSocket upgrade the live message list requires. Mailpit's SQLite message store lives on the dedicated Azure data disk mounted at /var/lib/mailpit.

Step 5 - Retrieve your web UI password
Mailpit protects its web UI and REST API with HTTP Basic Auth. The username is admin and a unique password is generated on the first boot of your VM and written to a root-only file:
sudo cat /root/mailpit-credentials.txt
This file contains MAILPIT_USERNAME, MAILPIT_PASSWORD, the MAILPIT_URL to open in a browser and the MAILPIT_SMTP host:port your applications should send to. The password is stored on disk only as a bcrypt hash in /etc/mailpit/ui-auth, so no plaintext password ships in the image. Store the password somewhere safe.

Step 6 - Confirm the health endpoint
nginx serves an unauthenticated health endpoint for load balancers and probes:
curl -s http://localhost/healthz
It returns ok. This endpoint never requires authentication, so it is safe for an Azure Load Balancer health probe.
Step 7 - Confirm authentication and SMTP capture
Because a password is set on first boot, an unauthenticated request to the web UI returns HTTP 401, so nobody reaches your captured mail without the password. The following reads the per-VM password from the credentials file and proves the round-trip - unauthenticated is rejected, and the correct password authenticates:
PW=$(sudo grep '^MAILPIT_PASSWORD=' /root/mailpit-credentials.txt | cut -d= -f2-)
echo "unauth: $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/)"
echo "authed: $(curl -s -o /dev/null -w '%{http_code}' -u admin:$PW http://127.0.0.1/)"
It prints unauth: 401 then authed: 200. Every message your applications send to port 25 is captured and readable through the authenticated REST API at /api/v1/messages.

Step 8 - Sign in to the web UI
Browse to http://<vm-public-ip>/. Your browser prompts for a username and password: enter admin and the password from Step 5. Mailpit opens on the inbox - the message list of everything your applications have sent, newest first, each row showing the sender, recipient, subject, size and time.

Step 9 - Read a captured message
Click any message to open it. Mailpit renders the email exactly as a mail client would, with the From, To, Subject and Date headers at the top and tabs to switch between the HTML view, plain text, HTML source, full headers, raw MIME, and automated HTML and link checks.

Step 10 - Inspect the message source and headers
Switch to the HTML Source tab (or Headers / Raw) to see the exact markup and MIME your application produced - invaluable when you are debugging templating, encoding or deliverability issues.

Step 11 - Search the mailbox
Use the search box at the top to filter the mailbox by sender, recipient, subject or body text - handy when an automated test suite has generated a large number of messages.

Step 12 - Point your application's SMTP at Mailpit
Configure your application's outbound SMTP settings to use this VM on port 25 - no username, no password and no TLS are required by default, which matches how most frameworks send to a local development mail catcher:
- Host: the VM's private or public IP (the
MAILPIT_SMTPvalue from Step 5) - Port:
25 - Encryption / auth: none
Every email the application then sends is captured by Mailpit and appears instantly in the web UI. Nothing is ever delivered to a real recipient, so it is safe to exercise password resets, order confirmations, notification digests and any other mail flow against production-like data.
Step 13 - Confirm data lives on the dedicated disk
Mailpit's SQLite message store is kept under /var/lib/mailpit on the dedicated Azure data disk, so your captured messages survive OS changes and the disk can be resized independently:
findmnt /var/lib/mailpit
The mount is backed by a separate Azure data disk captured into the image and re-provisioned on every VM.
Maintenance
- Password: the web UI password is set on first boot and stored as a bcrypt entry in
/etc/mailpit/ui-auth. To change it, runsudo htpasswd -B /etc/mailpit/ui-auth adminand thensudo systemctl restart mailpit. - Retention: Mailpit keeps the most recent messages and prunes automatically; adjust retention with the
--maxoption in themailpit.serviceunit if you need a larger or smaller mailbox. - Releasing mail: to actually forward a captured message to a real recipient, configure a release SMTP relay in the message view's Release action.
- Upgrades: Mailpit is a single static binary at
/usr/local/bin/mailpit; to upgrade, download a newer pinned release, verify its checksum, replace the binary and runsudo systemctl restart mailpit. Your message store under/var/lib/mailpitis preserved. - Storage: all Mailpit state lives under
/var/lib/mailpiton the data disk; back up that volume to protect your captured messages. - TLS: Mailpit serves plain HTTP on port 80; front it with TLS (for example certbot with your own domain) before exposing it beyond a trusted network.
- Security patches: unattended-upgrades remains enabled so the OS continues to receive security updates automatically.
Support
cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.