Start here
There are four things to do, and the first is the only one that can go wrong in a way that costs you an afternoon.
1. Pick a host that can send mail
Section titled “1. Pick a host that can send mail”This is the step people skip, and it is the one that decides whether any of the rest works.
- Outbound port 25 must be open. Most providers block it by default and will open it if you ask — DigitalOcean, Hetzner, Vultr and Oracle all do. AWS and Google Cloud make it hard on purpose.
- You must be able to set reverse DNS on the IP address, to the same hostname you will use. A mismatched or missing PTR is the single most common reason self-hosted mail is filtered.
- A fresh Debian 12 or Ubuntu 22.04+ host with a public IPv4, at least 2 GiB of RAM and 10 GiB of disk. Fresh matters: the stack publishes eleven ports — 25, 80, 110, 143, 443, 465, 587, 993, 995, 4190 and 8081 — and they must be free. From 0.11.0 the preflight checks all eleven; 0.10.0 and earlier check only seven (25, 80, 443, 465, 587, 993, 995), so on those a taken 110, 143, 4190 or 8081 passes its checks and then fails.
Point an A record at the host — mail.example.com — before you go any further, and set the PTR at
your provider to the same name.
Add two more names, also at the host: postmaster.example.com for the admin console and
webmail.example.com for the mail client — A records to the same address, or CNAMEs to
mail.example.com. They are built from your hostname with its first label dropped, so a hostname of
mx.example.co.uk means postmaster.example.co.uk and webmail.example.co.uk. There is one pair
for the whole server, whichever domains it hosts. Their certificates are issued the first time each
name is visited, so the records have to resolve by then. The wizard does not list these two, so add
them now.
2. One command
Section titled “2. One command”curl -fsSL https://get.maildock.app/install.sh | sh -s -- --hostname mail.example.comIt installs Docker and mailctl if they are missing and checks the preconditions above. It refuses to
go on without Docker and Compose, with less than 2 GiB of RAM, or with one of the ports it
checks already taken. The public IP, the A and PTR records, outbound port 25 and free disk are only
warnings — it prints them and carries on, so read them. Then it brings the stack up
and prints the address of the Setup Wizard. Roughly five minutes on a small VPS, most of it pulling images.
Doing this without a browser — for a provisioning script — is
the answers file, which produces byte-for-byte the same result. The full reference, including every error the preflight can print, is the install run-book.
3. The wizard, then the DNS records
Section titled “3. The wizard, then the DNS records”Open the address it printed. The Setup Wizard takes seven steps — hostname, TLS, your first domain, the owner account, AI (skippable), apply, and then the DNS records to publish.
Publish the records before you send anything. The wizard lists SPF, DKIM, DMARC and MTA-STS ready to paste; once you sign in, Verify now on the domain page checks them live. Mail sent from a domain whose records are not yet published is mail that teaches a receiver to distrust you.
4. Your first mailbox, and a client
Section titled “4. Your first mailbox, and a client”Add a mailbox in the admin console — from now on at https://postmaster.example.com — then open
https://webmail.example.com and sign in as it. https://<your hostname>/mail still works, as a
redirect to the webmail name, so it fails if that record is missing.
Desktop and mobile clients configure themselves — MailDock serves
autoconfig and autodiscover, so Thunderbird, Apple Mail and Outlook need the address and the password and nothing else.
Then what
Section titled “Then what”- Moving mail in from somewhere else — migration has a connector for cPanel, Plesk, Google Workspace, Microsoft 365 and plain IMAP, and syncs the delta after you change the MX record so nothing is lost in the cutover.
- Check your own deliverability before you rely on it. Send to a few addresses at the providers your recipients actually use, and read mail going to spam if any of it lands wrong — it is written in order of likelihood.
- Set up a backup.
mailctl backupis one command and the product does not ship it anywhere for you: backup and restore. - Run
mailctl doctoronce now, so you know what healthy looks like on this machine.
If something is wrong
Section titled “If something is wrong”mailctl doctor first — it checks the host, the containers, the database, the daemons and the DNS,
and its output is the thing to have in hand. What each check means.