Streaming & Messaging Azure

BillionMail on Ubuntu 24.04 on Azure User Guide

| Product: BillionMail on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of BillionMail on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. BillionMail is a complete, open source, self hosted mail server and email marketing platform from the aaPanel team. It bundles a Postfix mail transfer agent for sending and receiving, Dovecot for IMAP and POP3 mailbox access, Rspamd for spam scoring and DKIM signing, PostgreSQL and Redis for storage and rate limiting, a bundled Roundcube webmail client, and a single web console for managing domains, mailboxes, templates and marketing campaigns. It gives a team full control of both its mailboxes and its outbound email campaigns on infrastructure it owns, with no per message fees and no third party seeing the mailing list.

The cloudimg image ships the free and open source, AGPL-3.0 licensed BillionMail release, run the officially supported way as the upstream container stack. All seven images are captured into the VM, so your instance starts in seconds. Because the upstream project ships with documented default credentials, nothing here ships with a known secret: a unique admin password, an unguessable console entrance path, fresh database and Redis passwords, a per instance DKIM key and a per instance TLS certificate carrying the instance's own hostname are all generated for each VM on first boot, before the console is reachable. A demo domain and mailbox are seeded so the console is usable from the first login. Backed by 24/7 cloudimg support.

BillionMail is a trademark of its respective owner. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by BillionMail or aaPanel. It ships the free and open source AGPL-3.0 licensed self hosted software, unmodified.

The seven BillionMail compose services listed by docker compose ps, each showing its pinned upstream image (billionmail/core 4.9.0, billionmail/dovecot 1.6, billionmail/postfix 1.6, billionmail/rspamd 1.2, postgres 17.4-alpine, redis 7.4.2-alpine and roundcube 1.6.11) and its Up status, with Postgres and Redis bound to loopback only

What is included:

  • BillionMail v4.9 admin and marketing console (the billionmail/core:4.9.0 container) served on ports 80 and 443 behind a per instance security entrance path.
  • Postfix (SMTP on 25, submission on 587, SMTPS on 465), Dovecot (IMAP on 143/993, POP3 on 110/995), Rspamd spam filtering and DKIM signing, PostgreSQL and Redis, and the Roundcube webmail client, all as the official upstream images pinned by the v4.9 release.
  • A billionmail-firstboot.service that generates every per instance secret on first boot, and a billionmail.service that runs the stack, gated so it never starts before firstboot has written the per instance configuration.
  • A bundled proof script, /usr/local/sbin/billionmail-roundtrip.sh, that verifies the console and a real local mail round trip end to end.

Prerequisites

  • An Azure subscription and the Azure CLI (az) installed and logged in (az login), or access to the Azure Portal.
  • An SSH key pair for administrative access to the VM.
  • A recommended size of Standard_B2ms (2 vCPU / 8 GB) or larger. The stack runs seven containers, so the 4 GB of a Standard_B2s leaves no headroom for mail volume and campaigns.
  • Inbound access on the mail and console ports you intend to use: 25, 465, 587 (SMTP), 143, 993 (IMAP), 110, 995 (POP3) and 80, 443 (console and webmail).
  • For production sending and receiving: a domain name you control and the ability to edit its DNS records.

Step 1: Deploy from the Azure Portal

  1. In the Azure Portal, open the cloudimg BillionMail on Ubuntu 24.04 LTS offer and select Create.
  2. Choose your subscription, resource group and region, and set the VM size to Standard_B2ms or larger.
  3. Under Administrator account, provide your SSH public key with username azureuser.
  4. Under Inbound port rules, allow SSH (22), plus the mail and console ports you need (25, 465, 587, 143, 993, 110, 995, 80, 443).
  5. Review and create. When the VM is running, note its public IP address.

Step 2: Deploy from the Azure CLI

Create a resource group, open the required ports and launch the VM. Replace the image reference with the plan your subscription is entitled to.

az group create --name billionmail-rg --location eastus

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

az vm open-port --resource-group billionmail-rg --name billionmail \
  --port 25,465,587,143,993,110,995,80,443 --priority 900

Step 3: Connect to your VM

Connect over SSH as azureuser using the private key that matches the public key you supplied.

ssh azureuser@<vm-ip>

Step 4: Confirm the stack is running

The whole appliance runs as a Docker Compose stack under /opt/billionmail. List the containers and confirm each is up.

sudo docker compose -f /opt/billionmail/docker-compose.yml ps

All seven services (core, postfix, dovecot, rspamd, pgsql, redis, webmail) should report Up. Confirm the managing services are active too.

sudo systemctl is-active docker billionmail-firstboot.service billionmail.service

The published SMTP, IMAP, POP3 and console ports listening on the VM, and the docker, billionmail-firstboot and billionmail services all reported active

Step 5: Read the per instance credentials

On the first boot of each VM, BillionMail generates a unique admin password, an unguessable console entrance path, fresh database, Redis and DKIM keys and a per instance TLS certificate. The human readable values are written to a root only file.

sudo cat /root/billionmail-credentials.txt

The billionmail-credentials.txt file at mode 0600 root, showing the per instance console URL with its unguessable safe entrance path, the admin username, the admin and demo mailbox passwords redacted, the seeded demo domain and mailbox, and the per instance DKIM public record

The file contains the console URL (with its per instance entrance path), the admin username and password, the seeded demo domain and mailbox, and the DKIM public record to publish once you set your own domain. Nothing in this file is baked into the image; it is generated uniquely on each VM.

Step 6: Verify the appliance end to end

A bundled script proves the appliance is correctly configured without relying on external mail delivery: it checks the console answers on the per instance entrance path (and that the upstream default path is dead), that the per instance admin credentials authenticate (and the upstream default is rejected), that an authenticated message submitted on port 587 is delivered and retrieved over IMAPS 993, and that an open relay attempt and a wrong password are both refused.

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

It prints ROUNDTRIP_OK when every check passes.

Step 7: Open the console and sign in

Open the console URL from the credentials file in your browser. It has the form https://<vm-ip>/<entrance-path>/, where <entrance-path> is the unguessable value generated for this VM. The certificate is a per instance self signed certificate, so your browser will warn once; accept it to continue. Sign in with the admin username and password from the credentials file.

The BillionMail console sign in page, showing the BillionMail wordmark and the username and password fields behind the per instance security entrance path

Step 8: The Overview dashboard

After signing in you land on the Overview dashboard. It summarises delivery, open, click and bounce rates, the mail providers in use and a send statistics chart. On a fresh instance it already reflects the local delivery performed by the verification round trip.

The BillionMail Overview dashboard after login, showing 100 percent delivered, the mail providers table, a send statistics panel reporting one successful send and zero failures, and the left navigation for Email Marketing, Templates, Send API, Contacts, Domain, Mailboxes, SMTP, Logs and Settings

Step 9: Manage mailboxes

Open Mailboxes from the left navigation to see the mailboxes on your domains. The image ships with a seeded demo domain and mailboxes so the console is usable immediately; add your own with Add Mailbox, or import many at once with Batch Add and Import.

The BillionMail Mailboxes page listing the seeded mailboxes on the demo domain, each with its quota, General User type, enabled status and edit and delete actions, plus the Add Mailbox, Batch Add, Import and Export All controls

Step 10: Manage domains and DNS

Open Domain to manage the domains this server handles. Each domain shows its mailbox quota and capacity, spam list status and a DNS Records action that lists the exact MX, SPF, DKIM and DMARC records to publish for that domain.

The BillionMail Domain page listing the configured demo domain with its 5 GB quota, 500 mailbox capacity and current usage, and the DNS Records, Edit, Set Default and Delete actions

Step 11: Sending mail on Azure (important)

Azure blocks outbound TCP port 25 from virtual machines on every subscription type except Enterprise Agreement and Microsoft Customer Agreement for enterprise, and the block cannot be lifted on pay as you go, CSP, MSDN, Education or Free Trial subscriptions. This means a mail server on Azure generally cannot deliver directly to recipient mail servers on port 25.

What this does and does not affect:

  • Receiving mail is unaffected. Inbound SMTP on 25, submission on 587, IMAP on 143/993 and POP3 on 110/995 all work, so this is a fully functional receiving and mailbox server as shipped.
  • Sending to the internet should go through an authenticated relay (smarthost) on port 587, which Azure never blocks. Configure a relay provider in the console under Settings, then send through it.

This is a property of the Azure platform, not of BillionMail, and it is the single most important thing to plan for before going live.

Step 12: Use your own domain and DNS (production)

To run production mail for your own domain, point that domain at this VM and publish its DNS records:

  1. Set the server's mail hostname to a name under your domain and restart the stack:
sudo /usr/local/sbin/billionmail-set-domain.sh mail.<your-domain>
  1. In the console, add your domain under Domain, then open its DNS Records and publish the listed records at your DNS provider:
A      mail.<your-domain>     ->  <vm-ip>
MX     @                      ->  mail.<your-domain>   (priority 10)
TXT    @                      ->  v=spf1 mx ~all
TXT    default._domainkey     ->  (the DKIM public record shown in the console / credentials file)
TXT    _dmarc                 ->  v=DMARC1; p=quarantine; rua=mailto:admin@<your-domain>
  1. Create your mailboxes under Mailboxes, and issue a real TLS certificate for the console and mail from the console Settings once your DNS resolves.

Step 13: Webmail

The bundled Roundcube webmail client is served on the same VM so mailbox users can read and send mail in a browser:

https://<vm-ip>/roundcube/

Users sign in with their full email address and mailbox password.

Step 14: The pinned component stack

The image ships the official upstream images pinned by the BillionMail v4.9 release, captured into the VM so first boot needs no pull.

sudo docker images --format '{{.Repository}}:{{.Tag}}' | grep -E 'billionmail|postgres|redis|roundcube' | sort

docker images listing the seven pinned upstream images that make up the appliance: billionmail/core 4.9.0, billionmail/dovecot 1.6, billionmail/postfix 1.6, billionmail/rspamd 1.2, postgres 17.4-alpine, redis 7.4.2-alpine and roundcube 1.6.11-fpm-alpine

Step 15: Managing the service

The stack starts automatically on boot. To manage it manually:

sudo systemctl restart billionmail.service     # restart the whole stack
sudo systemctl stop billionmail.service        # stop it
sudo docker compose -f /opt/billionmail/docker-compose.yml logs -f core-billionmail

To change the admin password or the console entrance path, use the bundled BillionMail helper:

sudo bash /opt/billionmail/bm.sh change-password
sudo bash /opt/billionmail/bm.sh change-safe-path

Step 16: Security recommendations

  • Restrict the console. Ports 80 and 443 serve the admin console behind the per instance entrance path. Limit them to your management network with an Azure NSG rule, and issue a real TLS certificate before production.
  • Keep the entrance path secret. The console only responds behind the unguessable path generated for this VM; treat it as a credential.
  • Publish SPF, DKIM and DMARC for every sending domain so your mail is trusted, and monitor the DMARC reports.
  • Rotate the admin password you were issued after first login if you wish, using the helper in Step 15.
  • Keep the OS updated. Unattended security upgrades are enabled by default.

Step 17: Support and Licensing

BillionMail is free and open source software licensed under the GNU AGPL-3.0, shipped unmodified as the upstream v4.9 container stack. The bundled components (Postfix, Dovecot, Rspamd, PostgreSQL, Redis and Roundcube) are the official upstream images under their own respective open source licences. This cloudimg image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by BillionMail or aaPanel.

cloudimg provides 24/7 support for the deployment and operation of this image. For product questions about BillionMail itself, see the upstream project at github.com/aaPanel/BillionMail.

Deploy on Azure

Launch BillionMail on Ubuntu 24.04 LTS by cloudimg from the Azure Marketplace, or with the Azure CLI as shown in Step 2.