Email Server on a VPS with Postfix and Dovecot: From Zero to Working SMTP/IMAP
Self-hosting your mail server on a VPS gives you control over retention, data sovereignty, and deliverability configuration. This guide sets up Postfix + Dovecot with TLS, SPF, DKIM, and DMARC on a clean Ubuntu VPS.
A self-hosted email server gives you complete control over message routing, retention policies, data jurisdiction, and deliverability tuning. The cost is maintenance responsibility: certificate renewals, security patching, and reputation management are yours. This guide builds a minimal production-grade setup using Postfix (MTA) and Dovecot (IMAP/POP3) with correct authentication records.
Prerequisites Checklist
- KVM Linux VPS with a dedicated public IPv4 address (not NAT)
- A domain with full DNS control
- Port 25 (SMTP) unblocked outbound from your VPS—confirm with VPSWala before ordering
- Reverse DNS (PTR) record set for your server IP: should resolve to your mail hostname (e.g.
mail.yourdomain.com) - Ubuntu 22.04 LTS or Debian 12 recommended
Install the Stack
apt update && apt install -y postfix dovecot-core dovecot-imapd \
opendkim opendkim-tools certbot
When prompted by the Postfix installer, select Internet Site and set your mail hostname (e.g. mail.yourdomain.com).
Obtain a Let's Encrypt TLS Certificate
certbot certonly --standalone -d mail.yourdomain.com
This requires port 80 to be reachable. Certbot will store the certificate and private key under /etc/letsencrypt/live/mail.yourdomain.com/. Add an auto-reload hook so Postfix and Dovecot pick up renewed certificates without a manual restart:
echo 'post-hook = systemctl reload postfix dovecot' \
>> /etc/letsencrypt/renewal/mail.yourdomain.com.conf
Postfix Configuration Essentials
# /etc/postfix/main.cf (key additions)
myhostname = mail.yourdomain.com
mydomain = yourdomain.com
myorigin = $mydomain
inet_interfaces = all
mydestination = $myhostname, localhost, $mydomain
# TLS
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_use_tls=yes
smtpd_tls_auth_only=yes
smtp_tls_security_level=may
# SASL for authenticated client submissions
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
Enable the submission port (587) for authenticated outbound email from mail clients by uncommenting the submission block in /etc/postfix/master.cf.
Dovecot Configuration Essentials
# /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Maildir
# /etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = yes
auth_mechanisms = plain login
# /etc/dovecot/conf.d/10-ssl.conf
ssl = required
ssl_cert = SPF Record
yourdomain.com. IN TXT "v=spf1 mx ip4:YOUR_VPS_IP ~all"
SPF tells receiving servers which IPs may send email on behalf of your domain. ~all softfails messages from unauthorised sources without hard-rejecting them, which is safer during initial rollout. Tighten to -all once you have confirmed all legitimate senders are listed.
DKIM with OpenDKIM
mkdir -p /etc/opendkim/keys/yourdomain.com
opendkim-genkey -s mail -d yourdomain.com \
-D /etc/opendkim/keys/yourdomain.com/
# View the TXT record to add to DNS
cat /etc/opendkim/keys/yourdomain.com/mail.txt
Add the output as a TXT record at mail._domainkey.yourdomain.com. Configure OpenDKIM to sign all outgoing messages from your domain and integrate it with Postfix via the milter interface.
DKIM cryptographically signs each outgoing message with a private key. The receiving server fetches the public key from DNS and verifies the signature, proving the message body was not altered in transit.
DMARC Record
_dmarc.yourdomain.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com; pct=100"
DMARC instructs receiving servers to quarantine (move to spam) or reject messages that fail both SPF and DKIM alignment. The rua address receives aggregate reports showing your domain's sending sources and authentication pass rates—useful for detecting misconfigured mail flows early.
Pre-Send Deliverability Checklist
PTR record: dig -x YOUR_VPS_IP returns mail.yourdomain.comMX record: dig MX yourdomain.com returns mail.yourdomain.com with priority 10SPF TXT record publishedDKIM TXT record published and verified: opendkim-testkey -d yourdomain.com -s mail -vvvDMARC TXT record publishedPort 25 inbound open: nc -zv YOUR_VPS_IP 25Server IP not on major blocklists (MXToolbox Blacklist Check)Test delivery to a Gmail or Outlook address and confirm it lands in inbox, not spam
VPSWala Plan for a Mail Server
A mail server for a small organisation (50–200 mailboxes, moderate traffic) runs on a 2 vCPU / 4 GB RAM VPSWala plan with 50–80 GB RAID NVMe for mail storage and logs. Larger deployments with retention requirements should plan storage at mailboxes × average mailbox size × retention months, then add 50% headroom. VPSWala's KVM VPS plans include full root access and RAID NVMe on all tiers.
Managing Multiple Mailboxes
For an organisation with multiple users, manage mailboxes through Dovecot's virtual user database rather than system users. This approach stores each user's credentials in a file or database, maps their mail to a designated directory under a single system user (e.g. vmail), and avoids creating Linux system accounts for every email address.
A simple /etc/dovecot/users flat file:
alice@yourdomain.com:{SHA512-CRYPT}$6$...hashed_password...::::::
bob@yourdomain.com:{SHA512-CRYPT}$6$...hashed_password...::::::
Generate the hashed password with: doveadm pw -s SHA512-CRYPT. Each user's mail lands in a subdirectory of /var/mail/vhosts/yourdomain.com/alice/Maildir/.
Backup Strategy for Mail Data
Email data is high-value and difficult to reconstruct after loss. A reliable backup strategy:
Daily rsync to a remote VPS: rsync -avz /var/mail/vhosts/ backup-user@remote-vps:/mail-backup/ run via cron at 03:00. Store at least 7 days of daily snapshots.Periodic full archive: Monthly tar.gz of the entire mail directory, stored off-server (object storage or a second VPS in a different region).Database backup: If using MySQL for virtual user accounts, dump daily with mysqldump --single-transaction.
Test restoration before you need it. A backup you have never tested is an assumption, not a guarantee.
See VPSWala VPS plans for specifications, and VPSWala 9950X VPS for high-throughput mail relay configurations.
Sources
Not sure which size?
Send the stack, get a size.
Tell us the operating system, application stack, current traffic, database size and where it hurts today. You get a sizing recommendation, the matching plan and a price.
Related
Laravel VPS Deployment Guide: Nginx Configuration, PHP-FPM Pools & OPcache Tuning
A production deployment runbook for Laravel on Linux KVM VPS, covering Nginx server blocks, PHP-FPM process pools, OPcache tuning, and queue management.
MongoDB VPS Requirements: WiredTiger Cache Sizing, Memory & NVMe Storage
A technical database sizing guide for MongoDB on Linux KVM VPS, covering WiredTiger cache calculations, memory allocation, and swap tuning.
VPS Hosting for Varanasi: Which VPSWala Node to Pick and How to Test It
A technical node selection and ICMP diagnostic guide for Varanasi developers and businesses deploying KVM Cloud VPS instances across India.