Self-hosting email with Postfix and Dovecot on Ubuntu

Self-hosting email with Postfix and Dovecot on Ubuntu
This image: CC BY 3.0 by cybrkyd

On the surface of it, getting a self-hosted email server running sounds like a 10-minute job with Postfix and Dovecot. Except it is not quite so easy! I kept running into an issue where sending email was fine but not receiving or vice-versa.

After much investigation and numerous re-installs, I stumbled onto the issue by accident: when setting up Postfix with Dovecot, the postfix service needs to be in a ‘stopped’ state for this particular configuration change.


The following assumes that DNS records are in place for the mail server and the mail domain is configured for TLS encryption. I use Let’s Encrypt. This guide was used to install Postfix and Dovecot on Ubuntu 20.04 LTS. Further, this guide assumes that:

  • The apex domain is =
  • The mail subdomain is =
  • Therefore, the SMTP server address =

No additional system users will need to be configured; instead, users are maintained in /etc/aliases. If the user-name is not present in the aliases file, the mail will not be delivered. An example of /etc/aliases is below and shows the explicitly-named users will be diverted to root. In turn, emails addressed to root will be diverted to admin. We therefore end up with being a type of catch-all for, and so on.

mailer-daemon: postmaster
postmaster: root
nobody: root
hostmaster: root
usenet: root
news: root
webmaster: root
www: root
ftp: root
abuse: root
root: admin

Install Postfix

To install Postfix, run the command:

sudo apt update

sudo apt install postfix -y
  1. During install, Postfix will ask about the type of configuration required, so select Internet Site.
  2. Postfix will then request the apex domain name. Enter the name, e.g.

Installation will complete and Postfix can be used immediately from the command line. Ensure that port 25 is open on your firewall. Using UFW, this can be done with:

sudo ufw allow 25/tcp

Send a test email:

echo "hello" | sendmail

The email should be delivered to the recipient without issue at this point.

Install Dovecot

Because we are not in 1975 and we would like to access email from a client, we will install Dovecot. The remainder of this guide will assume we are only using IMAP (not POP3).

IMPORTANT: before proceeding, Postfix must be stopped

Check if Postfix is running:

postfix status

postfix: Postfix is running with backwards-compatible default settings
postfix: See for details
postfix: To disable backwards compatibility use "postconf compatibility_level=2" and "postfix reload"
postfix/postfix-script: the Postfix mail system is running: PID: 697

Stop Postfix:

sudo postfix stop

Install Dovecot:

sudo apt install dovecot-core dovecot-imapd

Configure Dovecot

We will empty the dovecot.conf file so let’s backup the original:

sudo cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig

Configure Dovecot:

sudo nano /etc/dovecot/dovecot.conf

Empty the file and add the following:

disable_plaintext_auth = no
mail_privileged_group = mail
mail_location = mbox:~/mail:INBOX=/var/mail/%u
userdb {
  driver = passwd
passdb {
  args = %s
  driver = pam
protocols = " imap"

namespace inbox {
  inbox = yes

  mailbox Trash {
    auto = subscribe
    special_use = \Trash
  mailbox Sent {
    auto = subscribe
    special_use = \Sent

service auth {
  unix_listener /var/spool/postfix/private/auth {
    group = postfix
    mode = 0660
    user = postfix

ssl_cert = </etc/letsencrypt/live/
ssl_key = </etc/letsencrypt/live/

Save and close the file. Two key points to note here: This configuration will use the default mbox format instead of Maildir. SSL is required (not optional) so point Dovecot to the certificates.

Configure Postfix

We will empty the main and the master config files so let’s backup the originals:

sudo cp /etc/postfix/ /etc/postfix/
sudo cp /etc/postfix/ /etc/postfix/

Configure Postfix

sudo nano /etc/postfix/

Empty the file and add the following:

myhostname =
myorigin = /etc/mailname
mydestination =,, localhost, localhost.localdomain
relayhost =
mynetworks = [::ffff:]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_protocols = !SSLv2, !SSLv3

local_recipient_maps = proxy:unix:passwd.byname $alias_maps

Note that myhostname is the mail subdomain aka the SMTP server address. Note also that mydestination includes both the apex domain name as well as the mail subdomain. The TLS/SSL certificates will point to the same Let’s Encrypt certificates as per the Dovecot configuration.

Save and close the file.

Finally, we will configure Postfix

sudo nano /etc/postfix/

Empty the file and add the following:

submission inet n       -       -       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_wrappermode=no
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth

Save and close the file.

Start Postfix:

sudo postfix start

Restart Dovecot:

sudo systemctl restart dovecot

Ensure that ports 25, 993 and 587 are open:

sudo ufw allow 25/tcp
sudo ufw allow 993/tcp
sudo ufw allow 587/tcp

That was easy, wasn’t it?

See also