Running your own email server is one of the most challenging—and rewarding—self-hosting projects you can tackle. Unlike other services, email requires proper DNS configuration, security hardening, and reputation management to ensure your messages actually reach their destination. But once you’ve got it working, you’ll have complete control over your communications, better privacy, and the satisfaction of truly owning your digital identity.

💡 This article contains affiliate links. If you buy through them, we earn a small commission at no extra cost to you. Learn more.

In this guide, I’ll walk you through setting up a complete email server stack using Postfix (SMTP), Dovecot (IMAP), and Roundcube (webmail). This is a production-ready configuration that includes spam filtering, SSL/TLS encryption, and modern authentication. By the end, you’ll have a fully functional email server capable of sending and receiving mail for your domain.

Why Self-Host Email?

Before we dive in, let’s address the elephant in the room: self-hosted email is hard. Major providers like Gmail and Outlook have made it increasingly difficult for independent mail servers to compete. Spam filters are aggressive, IP reputation matters more than ever, and one misconfiguration can land all your emails in the spam folder.

So why bother?

Privacy and ownership. Your emails aren’t scanned for advertising, mined for data, or subject to third-party terms of service. You control the encryption, the storage, and the access logs.

Learning experience. Email is fundamental internet infrastructure. Understanding how SMTP, IMAP, DNS records, and spam filtering work together gives you deep insight into how the internet actually functions.

Custom domains and unlimited aliases. Create as many email addresses as you want for your domain. Want hello@, contact@, noreply@, and secret-project@? Go for it.

No vendor lock-in. Your email data lives on your server, in open formats, backed up however you want.

That said, if you just want “Gmail but self-hosted,” consider using a service like Fastmail or Migadu with your custom domain. Self-hosting email makes sense if you value control and are willing to invest time in maintenance.

Prerequisites

Before starting, make sure you have:

  • A server with at least 2 GB RAM and 20 GB storage (a small VPS or homelab server will work)
  • Ubuntu 22.04 or 24.04 (this guide uses Ubuntu; adapt for other distros)
  • A domain name with access to DNS settings
  • A static IP address (most VPS providers include this; residential IPs often get blocked)
  • Port 25 unblocked by your provider (critical for receiving email; some VPS providers block it by default)
  • Root or sudo access to your server

You’ll also need basic familiarity with the Linux command line and text editors like nano or vim.

Architecture Overview

Here’s what we’re building:

  • Postfix: The Mail Transfer Agent (MTA) that handles sending and receiving emails via SMTP
  • Dovecot: The IMAP/POP3 server that stores and retrieves emails for your mail client
  • Roundcube: A modern webmail interface so you can access email from any browser
  • SpamAssassin: Spam filtering to keep your inbox clean
  • OpenDKIM: DomainKeys Identified Mail for email authentication
  • Let’s Encrypt: Free SSL/TLS certificates for encrypted connections

All components will run on a single server, though you can separate them later if needed.

Step 1: DNS Configuration

Proper DNS setup is critical for email. Get this wrong and your mail won’t deliver. You need to configure these records at your domain registrar or DNS provider:

A Record

Points your mail server’s hostname to its IP address.

mail.yourdomain.com.  A  203.0.113.10

Replace yourdomain.com with your actual domain and 203.0.113.10 with your server’s public IP.

MX Record

Tells other mail servers where to deliver email for your domain.

yourdomain.com.  MX  10  mail.yourdomain.com.

The 10 is the priority (lower numbers = higher priority). If you only have one mail server, the number doesn’t matter much.

PTR Record (Reverse DNS)

This maps your IP address back to your hostname. It’s set by your hosting provider, not your DNS registrar. Most VPS control panels let you configure it. Set it to mail.yourdomain.com.

To verify:

1
dig -x 203.0.113.10

You should see mail.yourdomain.com in the answer.

SPF Record

Sender Policy Framework tells receiving servers which IPs are allowed to send email for your domain.

yourdomain.com.  TXT  "v=spf1 mx ~all"

This says “only servers listed in the MX record can send mail for this domain.”

DKIM Record

We’ll generate the DKIM key later, but you’ll add a TXT record that looks like:

default._domainkey.yourdomain.com.  TXT  "v=DKIM1; k=rsa; p=MIGfMA0GCS..."

DMARC Record

DMARC tells receivers what to do if SPF or DKIM checks fail.

_dmarc.yourdomain.com.  TXT  "v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com"

This quarantines suspicious emails and sends reports to dmarc@yourdomain.com.

DNS propagation can take up to 48 hours, but usually completes in a few minutes to hours. Use dig to check your records:

1
2
3
dig yourdomain.com MX
dig yourdomain.com TXT
dig mail.yourdomain.com A

Step 2: Install and Configure Postfix

Postfix is the workhorse that sends and receives email. Let’s install and configure it.

Installation

1
2
sudo apt update
sudo apt install postfix -y

During installation, select “Internet Site” and enter your domain name (e.g., yourdomain.com).

Basic Configuration

Edit /etc/postfix/main.cf:

1
sudo nano /etc/postfix/main.cf

Update or add these settings:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# Hostname and domain
myhostname = mail.yourdomain.com
mydomain = yourdomain.com
myorigin = $mydomain

# Network settings
inet_interfaces = all
inet_protocols = ipv4

# Destinations
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
mynetworks = 127.0.0.0/8

# Mailbox settings
home_mailbox = Maildir/

# SMTP Authentication
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $mydomain

# TLS/SSL
smtpd_use_tls = yes
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.yourdomain.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.yourdomain.com/privkey.pem
smtpd_tls_security_level = may

smtp_tls_security_level = may
smtp_tls_note_starttls_offer = yes

# Recipient restrictions
smtpd_recipient_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination

Replace yourdomain.com with your actual domain.

Create Mail Users

Create a system user for email:

1
sudo adduser mailuser

Set a strong password. This user will authenticate via SMTP/IMAP.

Restart Postfix:

1
2
sudo systemctl restart postfix
sudo systemctl enable postfix

Step 3: Install and Configure Dovecot

Dovecot handles IMAP (retrieving email) and provides SASL authentication for Postfix.

Installation

1
sudo apt install dovecot-core dovecot-imapd dovecot-lmtpd -y

Configuration

Edit /etc/dovecot/dovecot.conf:

1
sudo nano /etc/dovecot/dovecot.conf

Ensure this line is uncommented:

1
protocols = imap lmtp

Edit /etc/dovecot/conf.d/10-mail.conf:

1
sudo nano /etc/dovecot/conf.d/10-mail.conf

Set the mail location:

1
mail_location = maildir:~/Maildir

Edit /etc/dovecot/conf.d/10-auth.conf:

1
sudo nano /etc/dovecot/conf.d/10-auth.conf

Disable plaintext auth (we’ll use TLS):

1
2
disable_plaintext_auth = yes
auth_mechanisms = plain login

Edit /etc/dovecot/conf.d/10-master.conf to enable authentication for Postfix:

1
sudo nano /etc/dovecot/conf.d/10-master.conf

Find the service auth section and update:

1
2
3
4
5
6
7
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
}

Edit /etc/dovecot/conf.d/10-ssl.conf:

1
sudo nano /etc/dovecot/conf.d/10-ssl.conf

Configure SSL:

1
2
3
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.yourdomain.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.yourdomain.com/privkey.pem

Restart Dovecot:

1
2
sudo systemctl restart dovecot
sudo systemctl enable dovecot

Step 4: Obtain SSL/TLS Certificates

Install Certbot:

1
sudo apt install certbot -y

Get a certificate:

1
sudo certbot certonly --standalone -d mail.yourdomain.com

Follow the prompts. Certbot will automatically renew certificates via a systemd timer.

After obtaining certificates, restart Postfix and Dovecot:

1
sudo systemctl restart postfix dovecot

Step 5: Install and Configure OpenDKIM

DKIM signs outgoing emails so recipients can verify they came from your server.

Installation

1
sudo apt install opendkim opendkim-tools -y

Configuration

Edit /etc/opendkim.conf:

1
sudo nano /etc/opendkim.conf

Add or update:

1
2
3
4
Domain                  yourdomain.com
KeyFile                 /etc/opendkim/keys/yourdomain.com/default.private
Selector                default
Socket                  inet:8891@localhost

Create the key directory:

1
2
3
4
sudo mkdir -p /etc/opendkim/keys/yourdomain.com
cd /etc/opendkim/keys/yourdomain.com
sudo opendkim-genkey -s default -d yourdomain.com
sudo chown opendkim:opendkim default.private

View the public key:

1
sudo cat default.txt

Copy the value inside the parentheses (starting with v=DKIM1...) and add it to your DNS as a TXT record at default._domainkey.yourdomain.com.

Edit /etc/default/opendkim:

1
sudo nano /etc/default/opendkim

Add:

1
SOCKET="inet:8891@localhost"

Restart OpenDKIM:

1
2
sudo systemctl restart opendkim
sudo systemctl enable opendkim

Update Postfix to use DKIM. Edit /etc/postfix/main.cf:

1
sudo nano /etc/postfix/main.cf

Add:

1
2
3
4
5
# DKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

Restart Postfix:

1
sudo systemctl restart postfix

Step 6: Install SpamAssassin

SpamAssassin filters incoming spam.

1
sudo apt install spamassassin spamc -y

Edit /etc/default/spamassassin:

1
sudo nano /etc/default/spamassassin

Enable the daemon:

1
ENABLED=1

Start SpamAssassin:

1
2
sudo systemctl start spamassassin
sudo systemctl enable spamassassin

Integrate with Postfix by editing /etc/postfix/master.cf:

1
sudo nano /etc/postfix/master.cf

Add this line:

1
2
smtp      inet  n       -       y       -       -       smtpd
  -o content_filter=spamassassin

And at the end:

1
2
spamassassin unix -     n       n       -       -       pipe
  user=debian-spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}

Restart Postfix:

1
sudo systemctl restart postfix

Step 7: Install Roundcube Webmail

Roundcube provides a modern webmail interface.

Install Dependencies

1
sudo apt install apache2 php php-mysql php-mbstring php-intl php-xml php-zip php-curl php-gd mariadb-server -y

Set Up the Database

1
sudo mysql -u root

Inside the MySQL prompt:

1
2
3
4
5
CREATE DATABASE roundcube;
CREATE USER 'roundcube'@'localhost' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON roundcube.* TO 'roundcube'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Download and Install Roundcube

1
2
3
4
5
cd /var/www/html
sudo wget https://github.com/roundcube/roundcubemail/releases/download/1.6.6/roundcubemail-1.6.6-complete.tar.gz
sudo tar -xzf roundcubemail-1.6.6-complete.tar.gz
sudo mv roundcubemail-1.6.6 roundcube
sudo chown -R www-data:www-data /var/www/html/roundcube

Configure Apache

Create a virtual host:

1
sudo nano /etc/apache2/sites-available/roundcube.conf

Add:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<VirtualHost *:80>
    ServerName mail.yourdomain.com
    DocumentRoot /var/www/html/roundcube

    <Directory /var/www/html/roundcube>
        Options +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/roundcube_error.log
    CustomLog ${APACHE_LOG_DIR}/roundcube_access.log combined
</VirtualHost>

Enable the site:

1
2
3
sudo a2ensite roundcube
sudo a2enmod rewrite
sudo systemctl reload apache2

Run the Installer

Visit http://mail.yourdomain.com/installer in your browser. Follow the wizard:

  1. Check dependencies (should all be green)
  2. Configure database: host localhost, database roundcube, user roundcube, password from earlier
  3. Configure IMAP: host localhost, port 143 (or 993 for SSL)
  4. Configure SMTP: host localhost, port 25 (or 587 for submission)

After setup, delete the installer:

1
sudo rm -rf /var/www/html/roundcube/installer

Access Roundcube at http://mail.yourdomain.com and log in with your mail user credentials.

Step 8: Testing Your Email Server

Send a Test Email

Use the mail command:

1
echo "This is a test email" | mail -s "Test" youremail@gmail.com

Check your Gmail (or other provider) inbox. If it arrives, your outbound mail works!

Receive a Test Email

Send an email to mailuser@yourdomain.com from an external account. Check /home/mailuser/Maildir/new/ for the message file.

Check Email Headers

Look at the headers of received emails to verify DKIM signatures and SPF pass.

Use Mail Tester

Visit mail-tester.com, send an email to the provided address, and check your score. Aim for 10/10. Common issues:

  • Missing or invalid SPF/DKIM/DMARC records
  • PTR record not set
  • IP on a blacklist (check MXToolbox)

Security Hardening

Firewall Rules

1
2
3
4
5
6
sudo ufw allow 25/tcp    # SMTP
sudo ufw allow 587/tcp   # Submission
sudo ufw allow 993/tcp   # IMAPS
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw enable

Fail2Ban

Protect against brute-force attacks:

1
sudo apt install fail2ban -y

Create /etc/fail2ban/jail.local:

1
2
3
4
5
[postfix]
enabled = true

[dovecot]
enabled = true

Restart Fail2Ban:

1
sudo systemctl restart fail2ban

Disable Root Login

Edit /etc/ssh/sshd_config:

1
sudo nano /etc/ssh/sshd_config

Set:

1
PermitRootLogin no

Restart SSH:

1
sudo systemctl restart sshd

Maintenance and Troubleshooting

Check Logs

  • Postfix: /var/log/mail.log
  • Dovecot: /var/log/mail.log
  • Apache: /var/log/apache2/

Monitor IP Reputation

Regularly check your server’s IP on blacklists:

1
dig +short blacklist.spamhaus.org.203.0.113.10

(Reverse your IP: 10.113.0.203 becomes 203.0.113.10)

Backups

Backup these directories regularly:

  • /home/mailuser/Maildir/ (emails)
  • /etc/postfix/
  • /etc/dovecot/
  • /var/www/html/roundcube/config/
  • MySQL database: mysqldump roundcube > roundcube_backup.sql

Performance Optimization

For a small server (under 100 users), the default settings work fine. For larger deployments:

  • Use Redis for caching in Roundcube
  • Enable Postfix queue management with multiple delivery agents
  • Tune Dovecot IMAP connections limits in 10-master.conf

Consider a dedicated mini PC if hosting at home for better reliability.

Alternatives and Comparisons

If this setup feels too complex, consider:

  • Mail-in-a-Box: Automated Ubuntu email server setup
  • Mailu: Dockerized email stack
  • iRedMail: Full-featured open-source mail server solution
  • Managed providers: Fastmail, Migadu, or ProtonMail with custom domains

Each has trade-offs between control, complexity, and convenience.

Final Thoughts

Congratulations! You now have a fully functional, self-hosted email server. This is no small achievement—email is genuinely hard to get right. But now you control your communications, understand how email infrastructure works, and have a foundation you can build on.

Keep monitoring your logs, maintain your IP reputation, and stay on top of security updates. Email is a long-term commitment, but for many self-hosters, it’s the ultimate declaration of digital independence.

If you run into issues, the Postfix and Dovecot documentation is excellent, and communities like Reddit’s r/selfhosted are helpful. Good luck, and welcome to the world of independent email!