Ma
Applications Azure

Mail-Archiver on Ubuntu 24.04 on Azure User Guide

| Product: Mail-Archiver on Ubuntu 24.04 LTS on Azure

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 /healthz endpoint 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:5000 only and PostgreSQL bound to 127.0.0.1:5432 only, 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

The mailarchiver, nginx and postgresql services active, with Kestrel bound to loopback 127.0.0.1:5000, PostgreSQL bound to 127.0.0.1:5432, nginx listening on port 80, and the healthz endpoint returning 200

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

The per VM Mail-Archiver credentials file, showing the administrator username, the generated password and the site URL, owned root only with 0600 permissions

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.

The Mail-Archiver login page with the Username and Password fields, the Remember me option, and the Sign In button

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.

The Mail-Archiver dashboard showing the archived email, account and attachment counts, the database size, and the emails per month and top senders panels, with the top navigation for Dashboard, Archive, Mail Accounts, Users, Jobs and 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.

The Create New Email Account page showing the Account Name and Email Address fields, the Provider selector set to IMAP, and the IMAP Settings section for the mail server details

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.

The Mail-Archiver Email Archive search view showing the Search Term field, the From and To date filters, the Account and Direction selectors, the advanced search tips and the Search and Reset buttons

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

The admin user present in the Mail-Archiver Users table, and the round trip check confirming the per VM administrator authenticates while the build time literal and a wrong guess are rejected

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

The ASP.NET Core 10 runtime present and the built Mail-Archiver application, confirming the GPL-3.0 licensed Mail-Archiver 2607.5 appliance on .NET 10

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.txt protected, 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:5000 only and PostgreSQL on 127.0.0.1:5432 only; neither is reachable from the network. nginx is the only public listener.
  • The image ships with AllowedHosts set 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/tcp in 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.