Mail-Archiver on Ubuntu 24.04 on Azure User Guide
Overview
Mail-Archiver is a self hosted email archiving application. It connects to one or many IMAP or Microsoft 365 mailboxes, copies every message into a central searchable store, and gives you a web interface to search, read, browse by folder and export mail, along with a dashboard, per account storage figures, retention controls and attachment handling. The cloudimg image ships Mail-Archiver 2607.5, built from source and run as an ASP.NET Core application under Kestrel behind nginx on a hardened, fully patched Ubuntu 24.04 LTS base, with a bundled local PostgreSQL 16 database so the appliance is complete on its own. A unique administrator account and a unique database password are created on the first boot of every VM using per VM secrets, and no default login is shipped. Backed by 24/7 cloudimg support.
What is included:
- Mail-Archiver 2607.5 (GPL-3.0 licensed) on the .NET 10 runtime, run by Kestrel under systemd as
mailarchiver.service - A bundled local PostgreSQL 16 database, so the appliance is complete on its own with no external database server
- nginx serving the application on
:80, with an unauthenticated/healthzendpoint for Azure Load Balancer health probes - A per VM administrator account created on first boot and recorded in a root only credentials file
- No shipped default login: the upstream sample administrator is stripped from the image and a unique per VM password is minted on first boot, so no known or blank credential authenticates
- A forced password change on the first sign in, so the customer sets their own administrator password before using the appliance
- A per VM PostgreSQL password and a per VM ASP.NET Core DataProtection keyring, so no two VMs share database or session material
- Kestrel bound to
127.0.0.1:5000only and PostgreSQL bound to127.0.0.1:5432only, never exposed to the network; nginx is the only public listener - 24/7 cloudimg support
This image ships only the open source, GPL-3.0 licensed Mail-Archiver application. It is not affiliated with or endorsed by the Mail-Archiver project.
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting point; size up for larger archives or many mailboxes. NSG inbound: allow 22/tcp from your management network and 80/tcp for the web interface. The PostgreSQL database is never exposed on the network, and both Kestrel and PostgreSQL listen on 127.0.0.1 only.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Mail-Archiver 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). Then Review + create then Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name mail-archiver \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
Then open port 80:
az vm open-port --resource-group <your-rg> --name mail-archiver --port 80 --priority 900
Step 3 - Confirm the services are running
SSH in as azureuser and confirm the Mail-Archiver (Kestrel) service, nginx and PostgreSQL are all active. Kestrel listens only on 127.0.0.1:5000 and PostgreSQL only on 127.0.0.1:5432; nginx is the only public listener, serving :80. The unauthenticated /healthz endpoint answers 200 for load balancer probes.
systemctl is-active mailarchiver nginx postgresql
ss -ltnH | grep -E ':(80|5000|5432)' | awk '{print $4}' | sort -u
curl -s -o /dev/null -w '/healthz -> %{http_code}\n' http://127.0.0.1/healthz

First boot provisions the database and runs the application's schema migrations, then starts the app. Immediately after the first boot the .NET app performs a short just in time warm up, so allow around a minute for the first page request before it responds.
Step 4 - Retrieve the per VM administrator login
Every VM creates its own administrator on first boot and writes the username, the generated password and the site URL to a root only credentials file. Read it with sudo:
sudo cat /root/mail-archiver-credentials.txt

You sign in with MAILARCHIVER_ADMIN_USER (which is admin) and the MAILARCHIVER_ADMIN_PASSWORD from this file.
Step 5 - Sign in and set your own password
Browse to http://<vm-public-ip>/. You are taken to the login page. Sign in with the username admin and the password from Step 4.

On your first sign in the appliance prompts you to set your own administrator password (a built in security step, because the first login uses the generated per VM password). Enter the per VM password as the current password, choose a new password, and confirm it. After that, your chosen password is the only administrator login.
Step 6 - The dashboard
Once signed in you land on the dashboard: an overview of the archive with the number of archived emails, the number of connected accounts, attachment counts and the database size, along with the emails per month and top senders panels. The top navigation links to the Archive (search), Mail Accounts, Users, background Jobs and the access Log.

Step 7 - Connect your first mailbox
A fresh appliance has an empty archive until you connect a mailbox - no live mail server is needed to boot or run the appliance. Open Mail Accounts then New Account. Give the account a name, enter the email address, choose the provider (IMAP or Microsoft 365), and fill in the server details and credentials. Save the account and Mail-Archiver begins synchronising and archiving its messages on a schedule in the background.

Step 8 - Search the archive
Open Archive to search your stored mail. You can search by term, restrict by date range, account and direction, and use advanced field searches such as subject:invoice or from:john. Results can be opened, exported, or batch restored back to a mailbox. Folders from each account are listed on the left.

Step 9 - No known or default credentials
Mail-Archiver's upstream sample ships a default administrator, and the cloudimg image removes it entirely: the sample credential is stripped from the shipped configuration, the captured image contains no database and no DataProtection keyring, and the administrator is created with a unique per VM secret the first time the VM boots. You can prove that only the per VM secret works with the built in round trip check, which confirms the per VM administrator authenticates through the login form while the upstream default secure123! and a wrong guess are both rejected:
sudo -u postgres psql -d MailArchiver -tAc 'SELECT "Username" FROM mail_archiver."Users";'
sudo bash /usr/local/sbin/mail-archiver-cred-roundtrip.sh

Step 10 - Verify the stack and where your data lives
Confirm the ASP.NET Core runtime and the built Mail-Archiver application. The PostgreSQL database, the ASP.NET Core DataProtection keyring and your configuration all live on this VM's disk, so your archive persists across reboots and rides with the VM.
dotnet --list-runtimes | grep AspNetCore
ls /opt/mailarchiver/app/MailArchiver.dll

Adding your own domain and TLS
The image serves the application on the VM's public IP over plain HTTP out of the box, and is intended to be fronted by your own reverse proxy for production. Point your DNS at the VM (or at an Azure Load Balancer or Application Gateway in front of it), and terminate HTTPS at that load balancer, Application Gateway, or your own reverse proxy in front of nginx. Mail-Archiver reads the standard X-Forwarded-Proto and X-Forwarded-Host headers, so it works correctly behind a TLS terminating proxy with no extra configuration. For production, also set AllowedHosts to your own hostname (see the security notes) rather than the permissive default.
Security notes
- The administrator account is unique per VM and no known or blank credential authenticates. The upstream default
secure123!is removed from the image. Keep/root/mail-archiver-credentials.txtprotected, and complete the forced password change on first sign in. - The PostgreSQL password and the ASP.NET Core DataProtection keyring are generated per VM on first boot, so neither database access nor authentication cookies are shared between customer VMs.
- Kestrel listens on
127.0.0.1:5000only and PostgreSQL on127.0.0.1:5432only; neither is reachable from the network. nginx is the only public listener. - The image ships with
AllowedHostsset to*so you can reach it by IP immediately. For production, restrict it to your own hostname and front the application with your own TLS. - Restrict inbound
80/tcpin your NSG to the networks that need the web interface.
Support
This image is maintained by cloudimg with 24/7 support. If you need help deploying or operating Mail-Archiver on Azure, contact us at cloudimg.co.uk.