Complete Email Server Setup Tutorial with Dovecot, Postfix, and Virtual Users (Debian)
This guide walks you through a complete setup of a self-hosted email server using Postfix for sending mail, Dovecot for IMAP access, and virtual users stored in a flat file. This tutorial avoids using any personal domain or user information.
β Prerequisites
- Debian 12 VPS
- Root access
- Domain name with DNS control (e.g., example.com)
- Ports 993 (IMAPS) and 587 (SMTP with STARTTLS) open in firewall
π§ System Setup
1. Create Mail Directory Structure
mkdir -p /var/mail/vhosts/example.com/user
# Create virtual mail user and group
groupadd -g 5000 vmail
useradd -u 5000 -g vmail -s /sbin/nologin -d /var/mail/vhosts vmail
# Set ownership
chown -R vmail:vmail /var/mail/vhosts
π¨ Dovecot Configuration
2. Install Dovecot
apt update
apt install dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-managesieved
3. Configure /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:/var/mail/vhosts/%d/%n
mail_privileged_group = mail
namespace inbox {
inbox = yes
}
4. Create /etc/dovecot/users
user@example.com:{PLAIN}password123
chown dovecot:dovecot /etc/dovecot/users
chmod 600 /etc/dovecot/users
5. Configure /etc/dovecot/conf.d/10-auth.conf
auth_username_format = %Lu
disable_plaintext_auth = no
auth_mechanisms = plain login
#!include auth-system.conf.ext
!include auth-passwdfile.conf.ext
6. Configure /etc/dovecot/conf.d/auth-passwdfile.conf.ext
passdb {
driver = passwd-file
args = /etc/dovecot/users
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}
7. Restart Dovecot
systemctl restart dovecot
8. Test Dovecot
doveadm user user@example.com
Should show: home=/var/mail/vhosts/example.com/user and uid/gid info.
βοΈ Postfix Configuration
9. Install Postfix
apt install postfix
Select “Internet Site” and set system mail name to example.com
10. Edit /etc/postfix/main.cf
Add or modify the following lines:
myhostname = mail.example.com
mydomain = example.com
myorigin = /etc/mailname
inet_interfaces = all
inet_protocols = ipv4
virtual_mailbox_domains = example.com
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_minimum_uid = 5000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_alias_maps = hash:/etc/postfix/virtual
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination
11. Create /etc/postfix/vmailbox
user@example.com example.com/user/
postmap /etc/postfix/vmailbox
12. Create /etc/postfix/virtual
(Optional aliases)
admin@example.com user@example.com
postmap /etc/postfix/virtual
13. Configure Dovecot SASL for Postfix
Create /etc/dovecot/conf.d/10-master.conf (edit service auth block):
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}
14. Reload Postfix
systemctl reload postfix
π DKIM Setup (with OpenDKIM)
15. Install OpenDKIM
apt install opendkim opendkim-tools
16. Configure /etc/opendkim.conf
Add:
Mode sv
Canonicalization relaxed/simple
Domain example.com
KeyFile /etc/opendkim/keys/example.com/mail.private
Selector mail
Socket local:/var/spool/postfix/opendkim/opendkim.sock
InternalHosts 127.0.0.1
KeyTable /etc/opendkim/key.table
SigningTable /etc/opendkim/signing.table
17. Key Setup
mkdir -p /etc/opendkim/keys/example.com
cd /etc/opendkim/keys/example.com
opendkim-genkey -s mail -d example.com
chown opendkim:opendkim mail.private
18. Create Supporting Files
/etc/opendkim/key.table
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private
/etc/opendkim/signing.table
*@example.com mail._domainkey.example.com
/etc/opendkim/trusted.hosts
127.0.0.1
localhost
example.com
19. Connect Postfix to OpenDKIM
In /etc/postfix/main.cf:
milter_default_action = accept
milter_protocol = 2
smtpd_milters = unix:/var/spool/postfix/opendkim/opendkim.sock
non_smtpd_milters = unix:/var/spool/postfix/opendkim/opendkim.sock
20. Restart Services
systemctl restart opendkim
systemctl restart postfix
21. Add DKIM DNS Record
Use the contents of mail.txt in /etc/opendkim/keys/example.com/ Add it as a TXT record:
- Name:
mail._domainkey - Type:
TXT - Value: (contents of p=… string, one line, no quotes)
π± Email Client Settings (IMAP)
| Setting | Value |
|---|---|
| IMAP Server | mail.example.com |
| IMAP Port | 993 |
| Encryption | SSL/TLS |
| SMTP Server | mail.example.com |
| SMTP Port | 587 |
| Encryption | STARTTLS |
| Username | user@example.com |
| Password | password123 |
| Authentication | Required (no SPA) |
β Test Tools
- IMAP test:
openssl s_client -connect mail.example.com:993 - SMTP test:
openssl s_client -starttls smtp -connect mail.example.com:587 - DKIM check: dkimvalidator.com
- Mail delivery logs:
journalctl -u postfix -f
journalctl -u dovecot -f
This setup supports multiple users and domains and is ideal for small businesses or self-hosters seeking privacy and control.

Leave a Reply