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

Tutorials

Install mailcow on a VPS

Jul 9, 2026 · 6 min read

mailcow is a Docker Compose stack around Postfix, Dovecot, Rspamd, and SOGo, with the best admin interface of any self-hosted mail server. This guide covers a working install and how much memory it really needs.

1. Before you start

Port 25 must be open, reverse DNS must be set, and your DNS must be ready. Our guide on what running your own mail server actually takes covers all of it, and none of this works without it.

You also need Docker installed, version 24.0.0 or newer, which mailcow checks for and refuses to run without.

mailcow's stated minimum is 2.5 GB of RAM, and its setup script prompts you to disable ClamAV on anything at or below that. In practice it is comfortable at 4 to 6 GB. On 2 GB it will install and then swap itself to a standstill.

2. Install

ssh session
$ cd /opt
$ sudo git clone https://github.com/mailcow/mailcow-dockerized
$ cd mailcow-dockerized
$ sudo ./generate_config.sh

The script asks for your mail hostname, for example mail.example.com, and your timezone. That hostname must match your reverse DNS record. On a machine with 2.5 GB of RAM or less it also offers to set SKIP_CLAMD=y for you.

It writes mailcow.conf, which is where every later setting lives. Then pull and start:

ssh session
$ sudo docker compose pull
$ sudo docker compose up -d

The first pull is large and the first start takes a few minutes. Watch it with sudo docker compose logs -f.

3. Log in and add your domain

Open https://mail.example.com. The default login is admin with the password moohoo.

Change that password immediately. It is published in every mailcow guide including this one.

Then add your domain under Configuration, Mail Setup, Domains, and add your first mailbox. mailcow generates the DKIM key when you add the domain.

4. Publish the DNS records

Under Configuration, Mail Setup, Domains, the DNS button shows every record mailcow expects with a green or red status next to each. That page is the best DNS checklist any of these platforms provide, so work down it until everything is green.

It will include the DKIM record, which only exists after you added the domain.

5. Cut memory use if you need to

If you are on 4 GB rather than 8, disable ClamAV in mailcow.conf:

/opt/mailcow-dockerized/mailcow.conf
SKIP_CLAMD=y
ssh session
$ sudo docker compose down
$ sudo docker compose up -d

That frees roughly a gigabyte. Rspamd keeps doing the spam filtering, which is what most servers need.

Do not put mailcow behind your existing Nginx casually

mailcow ships its own web server and expects ports 80 and 443. Putting a proxy in front is supported but it is a documented procedure with specific headers and settings, not a quick proxy_pass. If this VPS also serves websites, read mailcow's reverse proxy documentation before you start, or give mail its own server.

6. Spam filtering

mailcow uses Rspamd for spam scoring, DKIM signing, and antivirus handling. Every message gets a score, and the score decides what happens to it.

The defaults are conservative on purpose:

ScoreAction
Below 4Delivered
4 and aboveGreylisted (sender asked to retry)
6 and aboveDelivered to Junk, header added
15 and aboveRejected at SMTP

Greylisting temporarily refuses a message from an unknown sender. Real mail servers retry a few minutes later; most spam software does not.

To change the thresholds server-wide, edit the actions file and restart Rspamd:

/opt/mailcow-dockerized/data/conf/rspamd/local.d/actions.conf
actions {
    reject = 15;
    add_header = 6;
    greylist = 4;
}
ssh session
$ cd /opt/mailcow-dockerized
$ sudo docker compose restart rspamd-mailcow

Existing per-user settings are not overwritten by this change.

Per-domain and per-user lists

Domain administrators set a blacklist and whitelist under Configuration, Mail Setup, Domains, Edit Domain, Spam Filter. Individual users get their own Spam filter tab in the mailcow interface, where they can set their own thresholds and lists.

Be aware that a user's own settings override the domain settings, so a user can whitelist a sender you blocked.

The Rspamd interface

Rspamd ships its own web interface with mailcow, showing live scores, the history of recent messages, and which rules fired on each. The password is random until you set one: log in to mailcow as administrator, go to System Configuration, then Access Rspamd UI.

When a message is junked and you do not know why, that history view names the rules that fired on it.

Training the filter

Rspamd learns from what your users do. Moving a message into Junk trains it as spam, moving it out trains it as ham. This feedback improves accuracy more than threshold tuning does, so tell your users to move mail into and out of Junk instead of deleting it.

7. Back it up

mailcow includes a backup script. Point it at a directory outside the install:

ssh session
$ sudo MAILCOW_BACKUP_LOCATION=/opt/mailcow-backup /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all

The script creates folders named mailcow_DATE inside that location. Do not rename them, because the restore process looks for that format. Copy the directory off the server, and test a restore once before you rely on it.

8. Updating

ssh session
$ cd /opt/mailcow-dockerized
$ sudo ./update.sh

The update script handles the compose changes between versions. Do not update by pulling images by hand; mailcow's versions are coordinated across containers.

Quick reference

TaskCommand
Installgit clone, ./generate_config.sh, docker compose up -d
First loginadmin / moooo, change it now
DNS checklistConfiguration, Mail Setup, Domains, DNS button
Save memorySKIP_CLAMD=y in mailcow.conf
BackupMAILCOW_BACKUP_LOCATION=/path helper-scripts/backup_and_restore.sh backup all
Update./update.sh

Where to go next

Work the DNS page until every row is green, then send a test message in each direction. If mail sends but lands in spam, look at DNS and reputation before you look at mailcow.

mail mailcow docker smtp imap webmail

Related articles