Independent hosting operator since 2014 · New York · Dallas · Amsterdam Status Looking Glass Contact
D4 NetworksD4 Networks
Client area Deploy a server
Home / Resources / Install Mailu on a VPS

Tutorials

Install Mailu on a VPS

Jul 14, 2026 · 6 min read

Mailu is a Docker Compose stack of standard parts: Postfix, Dovecot, Rspamd, an admin interface, and webmail. You do not write the Compose file yourself, because a wizard on their site generates it from your answers.

1. Before you start

Port 25 must be open, reverse DNS must point at your mail hostname, and your DNS must be yours to edit. Our guide on what running your own mail server actually takes covers all of it.

You also need Docker installed, and 2 to 3 GB of RAM is a realistic floor.

Mailu wants ports 80, 443, 25, 465, 587, 110, 995, 143, 993, and 4190 on the host. If this server already runs a website, that conflicts on 80 and 443. Give mail its own server unless you are prepared to do the reverse proxy work.

2. Pick the right version

Mailu's version naming is unusual, and choosing the wrong one is a common way to end up running development code in production:

  • A dated branch such as 2024.06 is the stable release, and it keeps receiving patches. This is what new setups should use.
  • X.Y.Z pins to a specific commit, so containers never change under you when they are recreated. Use this if you want to control exactly when you update.
  • latest points at the master development branch. Their documentation says plainly you should never use it for a production server.

Check their setup site for the current stable version. Do not copy a number out of any guide, including this one.

3. Run the wizard

Go to setup.mailu.io and pick the current stable version. The wizard asks for your mail hostname, your domain, which optional features you want (webmail, antivirus, fetchmail, and so on), and the IP addresses the ports should bind to.

When you finish, it gives you a unique URL with two files behind it. Download both onto your server:

ssh session
$ sudo mkdir -p /mailu && cd /mailu
$ wget <the docker-compose.yml URL the wizard gave you>
$ wget <the mailu.env URL the wizard gave you>

Both files are generated for your answers, so do not copy them from someone else's guide.

4. Review the environment file

Open mailu.env and check three things before starting:

  • SECRET_KEY must be a random 16 character string. The wizard generates one, but confirm it is not left at a placeholder.
  • The bind addresses must be your server's real public addresses, not 127.0.0.1, or nothing outside the machine can reach your mail server.
  • The data path, /mailu by default, is where everything persistent lives.
  • TLS_FLAVOR decides how certificates work. letsencrypt obtains them automatically and is what most people want. cert means you supply them yourself, and notls is for testing only.

5. Start it and create the admin

ssh session
$ cd /mailu
$ docker compose up -d
$ docker compose logs -f

The first start pulls a lot of images. Once it settles, create the first administrator:

ssh session
$ docker compose exec admin flask mailu admin me example.com PASSWORD

That creates [email protected] with administration privileges. Then open https://mail.example.com/admin, sign in, and change the password to a strong one.

6. Add your domain and publish DNS

In the admin interface, add your domain, then open its details page. Mailu shows the DNS records it expects, including the DKIM key it generated. Publish them at your DNS provider.

Our DNS records guide explains what each one does.

Mailu ships its own DNS resolver

The stack includes an unbound container that the other services use for lookups. That matters for spam filtering, because DNS blocklists refuse queries from large public resolvers like Cloudflare and Google. Mailu solves that problem for you, which several other platforms leave to you.

7. Spam filtering

Rspamd does the filtering, and Mailu puts the parts most people need in the admin interface:

  • A default spam threshold for new users, set globally, with each user able to adjust their own.
  • Per-user and per-domain allow and deny lists.
  • Greylisting, which temporarily refuses mail from unknown senders.
  • Antivirus with ClamAV, which is optional in the wizard. Leaving it off is the single biggest memory saving available.

Rspamd learns from what users do with their Junk folder, so tell your users to move messages into and out of Junk instead of deleting them.

For anything deeper, Mailu supports an overrides directory where you can drop your own Rspamd configuration without editing the generated files.

8. Updating

ssh session
$ cd /mailu
$ docker compose pull
$ docker compose up -d

If you pinned an X.Y.Z version, edit that value first. Some releases need docker compose down --remove-orphans in between because of network changes, so read the release notes before each upgrade.

Quick reference

TaskCommand or place
Generate configsetup.mailu.io, pick the stable version
Data directory/mailu
Create admindocker compose exec admin flask mailu admin me example.com PASSWORD
Admin interfacehttps://mail.example.com/admin
Updatedocker compose pull && docker compose up -d
Never usethe latest tag in production

Where to go next

Publish the DNS records from the domain details page, then send a test message in each direction. If you want calendars and contacts, Mailu does not bundle them; our comparison guide covers the platforms that do.

mail mailu docker rspamd smtp imap

Related articles