Streaming & Messaging Azure

smtp4dev on Ubuntu 24.04 on Azure User Guide

| Product: smtp4dev on Ubuntu 24.04 LTS on Azure

Overview

smtp4dev is a fake, developer focused SMTP server with a modern web interface. It runs a fake SMTP server that catches every message your application sends, stores each one, and shows it in a web UI where you can read the HTML, plain text and raw source, inspect headers and attachments, and run HTML validation and compatibility checks. Because smtp4dev never delivers mail externally, it is completely safe to point your development and staging applications at it: nothing ever reaches a real inbox. A built in IMAP server also lets a standard mail client browse the captured messages.

The cloudimg image installs the pinned smtp4dev 3.15.0 release on the ASP.NET Core 10 runtime, runs it as a dedicated smtp4dev 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 and the IMAP server on port 143, 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:

  • smtp4dev 3.15.0 running as the smtp4dev systemd service on the ASP.NET Core 10 runtime
  • A fake SMTP server on :25 that captures every message your apps send and never delivers externally
  • An IMAP server on :143 so a standard mail client can browse the captured mail
  • The smtp4dev 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/smtp4dev holding the SQLite message store
  • smtp4dev.service + nginx.service as systemd units, enabled and active
  • An unauthenticated /healthz endpoint 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; smtp4dev is light on resources. NSG inbound: allow 22/tcp from your management network, 80/tcp for the web UI, 25/tcp from the networks that run the applications under test so they can deliver mail to smtp4dev, and 143/tcp if you want to browse captured mail from an IMAP client. smtp4dev 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 smtp4dev 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 inbound NSG rules for SMTP (25) from your application networks and, if you want IMAP access, IMAP (143). 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 smtp4dev \
  --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 smtp4dev --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name smtp4dev --port 25 --priority 1020
az vm open-port --resource-group <your-rg> --name smtp4dev --port 143 --priority 1030

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

systemctl is-active smtp4dev.service nginx.service

Both report active. smtp4dev serves its web UI and REST API on the loopback connector 127.0.0.1:5000, listens for SMTP on 0.0.0.0:25 and IMAP on 0.0.0.0:143; nginx fronts the UI on port 80 with the WebSocket upgrade the live message list requires. smtp4dev's SQLite message store lives on the dedicated Azure data disk mounted at /var/lib/smtp4dev.

The smtp4dev, nginx and firstboot services active, the listeners on port 80 (nginx), loopback 5000 (web UI), 25 (SMTP) and 143 (IMAP), and the dedicated data disk mounted at /var/lib/smtp4dev

Step 5 - Retrieve your web UI password

smtp4dev 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/smtp4dev-credentials.txt

This file contains SMTP4DEV_USERNAME, SMTP4DEV_PASSWORD, the SMTP4DEV_URL to open in a browser and the SMTP4DEV_SMTP / SMTP4DEV_IMAP host:port values your applications and mail clients should use. The password is stored only in the per-VM override at /var/lib/smtp4dev/appsettings.json (mode 0600), so no shared password ships in the image. Store the password somewhere safe.

The smtp4dev version reported by the REST API and the per-VM credentials file with the generated admin password masked, the web UI URL, and the SMTP and IMAP host:port values

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 '^SMTP4DEV_PASSWORD=' /root/smtp4dev-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/Messages.

The HTTP Basic Auth round-trip returning 401 unauthenticated and 200 with the per-VM password, then a test email delivered to SMTP port 25 raising the captured message count, never delivered to a real recipient

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. smtp4dev opens on the inbox - the message list of everything your applications have sent, each row showing the received time, sender and recipient.

The smtp4dev inbox message list showing captured test emails with the received time, sender and recipient columns

Step 9 - Read a captured message

Click any message to open it. smtp4dev renders the email exactly as a mail client would, with the From, To and Subject headers at the top and tabs to switch between the rendered View, Analysis, raw Source, full Headers and MIME Parts.

A rendered HTML order confirmation email in smtp4dev showing the message headers and the HTML body with its call to action button, plus the View, Analysis, Source, Headers and Parts tabs

Step 10 - Inspect the message source and headers

Switch to the Source tab (or Headers / Parts) to see the exact MIME your application produced - invaluable when you are debugging templating, encoding or deliverability issues.

The smtp4dev Source tab showing the exact raw MIME source of the captured message with syntax highlighting and line numbers

Step 11 - Review the server settings

Open Settings (the gear icon, top right) to review the server configuration. The SMTP Server, IMAP Server and POP3 Server tabs show the ports and options for each protocol, Users manages the web and mailbox accounts, and Mailboxes defines how incoming mail is routed. On the cloudimg image, Require Authentication (web, API) is enabled by default so your captured mail is never exposed without the per-VM password.

The smtp4dev Settings dialog with the General, SMTP Server, IMAP Server, POP3 Server, Users and Mailboxes tabs, showing Require Authentication for the web and API enabled by default

Step 12 - Point your application's SMTP at smtp4dev

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 SMTP4DEV_SMTP value from Step 5)
  • Port: 25
  • Encryption / auth: none

Every email the application then sends is captured by smtp4dev 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 - Browse captured mail over IMAP

smtp4dev also runs an IMAP server on port 143, so you can point a standard mail client (Thunderbird, Outlook, mutt) at the box and browse the captured messages as an ordinary mailbox:

  • Host: the VM's IP (the SMTP4DEV_IMAP value from Step 5)
  • Port: 143
  • Connection security: none

The default mailbox holds every captured message. This is handy when you want to test how your own mail client renders the messages your application produced.

Step 14 - Confirm data lives on the dedicated disk

smtp4dev's SQLite message store is kept under /var/lib/smtp4dev on the dedicated Azure data disk, so your captured messages survive OS changes and the disk can be resized independently:

findmnt /var/lib/smtp4dev

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 in the per-VM override /var/lib/smtp4dev/appsettings.json under ServerOptions:Users. To change it, edit that file (as root) and run sudo systemctl restart smtp4dev.
  • Retention: smtp4dev keeps the most recent messages and prunes automatically; adjust # of Messages to Keep in the Settings dialog, or ServerOptions:NumberOfMessagesToKeep in the override file.
  • Relaying mail: to forward a captured message to a real recipient, configure a relay SMTP server under Settings -> Message Relay, then use the Relay action on a message.
  • Upgrades: smtp4dev is published under /opt/smtp4dev and runs on the apt managed ASP.NET Core 10 runtime; to upgrade, download a newer pinned release, verify its checksum, replace the contents of /opt/smtp4dev and run sudo systemctl restart smtp4dev. Your message store under /var/lib/smtp4dev is preserved.
  • Storage: all smtp4dev state lives under /var/lib/smtp4dev on the data disk; back up that volume to protect your captured messages.
  • TLS: smtp4dev 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 and the ASP.NET Core runtime continue to receive security updates automatically.

Support

cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.