Skip to content

Deploying a Dovecot App

Dovecot is a high-performance, secure open-source IMAP and POP3 server designed for Linux and UNIX-like systems. With over 20 years of development, Dovecot has become one of the most widely used mail servers, powering millions of mailboxes worldwide. It’s known for its exceptional performance, rock-solid stability, and extensive feature set that makes it suitable for everything from small personal mail servers to large-scale ISP deployments.

At its core, Dovecot excels at mail retrieval and delivery. It implements the IMAP4rev1 and POP3 protocols with extensive extensions, allowing mail clients to efficiently access and manage email messages stored on the server. Beyond basic mail access, Dovecot includes LMTP (Local Mail Transfer Protocol) for receiving mail from MTAs, SMTP submission support for sending mail, and advanced features like server-side mail filtering through Sieve, full-text search capabilities, and push notifications.

What sets Dovecot apart is its focus on security and performance. The server uses a modular architecture with privilege separation, where different processes run with minimal required permissions, significantly reducing the attack surface. It supports multiple authentication mechanisms including PLAIN, LOGIN, CRAM-MD5, DIGEST-MD5, and external authentication through SQL databases, LDAP, or PAM. Dovecot also implements modern security standards like SSL/TLS encryption, SNI (Server Name Indication), and automatic certificate reloading.

Why Deploy Dovecot on Klutch.sh?

Deploying Dovecot on Klutch.sh offers several advantages for running your mail server infrastructure:

  1. Automatic Dockerfile Detection - Klutch.sh automatically detects and builds your Dovecot container from your Dockerfile, streamlining the deployment process without manual configuration.

  2. TCP Traffic Support - Dovecot requires TCP connections for IMAP, POP3, and other mail protocols. Klutch.sh provides native TCP traffic routing with external port access on port 8000.

  3. Persistent Storage - Mail storage requires reliable persistence. Klutch.sh volumes ensure your mailboxes, indexes, and configuration remain intact across container restarts and deployments.

  4. Environment-Based Configuration - Configure Dovecot settings through environment variables, making it easy to adjust authentication, storage paths, and protocol settings without rebuilding containers.

  5. GitHub Integration - Deploy directly from your GitHub repository containing your Dovecot configuration and Dockerfile, enabling version-controlled infrastructure and easy rollbacks.

  6. Scalable Infrastructure - Start with a basic mail server setup and scale resources as your user base grows, without infrastructure management overhead.

  7. Security by Default - Klutch.sh’s containerized environment provides isolation, and you can easily implement SSL/TLS certificates for encrypted mail access.

  8. Cost-Effective - Run a production-grade mail server without the overhead of managing virtual machines or bare metal servers, paying only for the resources you use.

  9. Quick Deployment - Go from a GitHub repository to a running mail server in minutes, not hours, with automatic builds and deployments.

  10. No Complex Orchestration - Deploy Dovecot without managing Kubernetes, Docker Swarm, or other orchestration tools. Klutch.sh handles container management automatically.

Prerequisites

Before deploying Dovecot on Klutch.sh, ensure you have:

  • A Klutch.sh account
  • A GitHub account with a repository for your Dovecot configuration
  • Basic understanding of email protocols (IMAP, POP3, SMTP)
  • Familiarity with Docker and Dockerfile syntax
  • Understanding of mail server security practices
  • (Optional) Domain name with DNS access for production deployments
  • (Optional) SSL/TLS certificates for encrypted connections

Dovecot Architecture Overview

Understanding Dovecot’s architecture helps you configure and optimize your deployment:

Core Components

Master Process The dovecot master process manages all other processes, handles configuration reloading, and maintains privilege separation. It runs as root but spawns child processes with appropriate reduced privileges.

Authentication Process Dovecot uses dedicated authentication processes (dovecot-auth) that handle user authentication through various backends like passwd, SQL, LDAP, or PAM. This separation ensures authentication code runs with minimal privileges.

IMAP/POP3 Processes For each mail protocol connection, Dovecot spawns a dedicated login process that handles the initial connection and authentication, then transitions to a mail process that runs with the user’s privileges for accessing their mailbox.

LMTP Process The LMTP (Local Mail Transfer Protocol) service receives mail from MTAs (like Postfix or Exim) and delivers it to user mailboxes. It’s more efficient than traditional LDA (Local Delivery Agent) for high-volume deployments.

Storage Architecture

Mailbox Formats Dovecot supports multiple mailbox formats including Maildir (one file per message), mbox (all messages in one file), and its own high-performance dbox format. Maildir is the most common choice for its simplicity and reliability.

Index Files Dovecot maintains index files that cache mailbox metadata and message headers, significantly improving IMAP performance. These indexes are automatically maintained and rebuilt if corrupted.

Mail Location Mail is typically stored in user home directories (e.g., /home/vmail/%u) with support for virtual users where actual system users don’t exist.

Security Model

Privilege Separation Different Dovecot processes run with different privileges: the master process as root, authentication as a dedicated user, and mail access processes as the actual mailbox owner or virtual mail user.

SSL/TLS Support Dovecot supports both SSL/TLS encryption for IMAP (port 993) and POP3 (port 995), as well as STARTTLS for upgrading plain connections on standard ports (143 for IMAP, 110 for POP3).

Preparing Your Repository

Create a new GitHub repository for your Dovecot deployment with the following structure:

dovecot-mail-server/
├── Dockerfile
├── dovecot.conf
├── conf.d/
│ ├── 10-auth.conf
│ ├── 10-mail.conf
│ ├── 10-master.conf
│ └── 10-ssl.conf
├── users
└── README.md

Creating the Dockerfile

Create a Dockerfile in your repository root:

FROM debian:bookworm-slim
# Install Dovecot and required packages
RUN apt-get update && apt-get install -y \
dovecot-core \
dovecot-imapd \
dovecot-pop3d \
dovecot-lmtpd \
dovecot-sieve \
dovecot-managesieved \
openssl \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Create required directories
RUN mkdir -p /var/mail/vhosts \
/var/mail/sieve \
/etc/dovecot/conf.d \
/var/log/dovecot
# Create virtual mail user
RUN groupadd -g 5000 vmail && \
useradd -g vmail -u 5000 vmail -d /var/mail
# Copy configuration files
COPY dovecot.conf /etc/dovecot/dovecot.conf
COPY conf.d/* /etc/dovecot/conf.d/
COPY users /etc/dovecot/users
# Set correct permissions
RUN chown -R vmail:vmail /var/mail/vhosts \
&& chmod -R 700 /var/mail/vhosts \
&& chown -R vmail:vmail /var/mail/sieve \
&& chmod 600 /etc/dovecot/users
# Expose mail ports
# IMAP
EXPOSE 143
# IMAPS
EXPOSE 993
# POP3
EXPOSE 110
# POP3S
EXPOSE 995
# LMTP
EXPOSE 24
# ManageSieve
EXPOSE 4190
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD doveadm who || exit 1
# Start Dovecot in foreground
CMD ["dovecot", "-F"]

Main Configuration File

Create dovecot.conf:

# Dovecot main configuration file
# Protocols to enable
protocols = imap pop3 lmtp sieve
# Listen on all interfaces
listen = *
# Disable SSL by default (enable in 10-ssl.conf if needed)
ssl = no
# Log file locations
log_path = /var/log/dovecot/dovecot.log
info_log_path = /var/log/dovecot/dovecot-info.log
debug_log_path = /var/log/dovecot/dovecot-debug.log
# Authentication process
auth_mechanisms = plain login
# Mail location for virtual users
mail_location = maildir:/var/mail/vhosts/%d/%n
# Valid UID and GID for mail access
first_valid_uid = 5000
last_valid_uid = 5000
first_valid_gid = 5000
last_valid_gid = 5000
# Mail privileged group
mail_privileged_group = vmail
# Include additional configuration
!include conf.d/*.conf

Authentication Configuration

Create conf.d/10-auth.conf:

# Authentication configuration
# Disable system user authentication
!include auth-system.conf.ext
# Enable passwd-file authentication
passdb {
driver = passwd-file
args = scheme=PLAIN username_format=%u /etc/dovecot/users
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}
# Allow plaintext authentication
auth_mechanisms = plain login
disable_plaintext_auth = no

Mail Storage Configuration

Create conf.d/10-mail.conf:

# Mail storage configuration
# Mail location
mail_location = maildir:/var/mail/vhosts/%d/%n
# Namespace configuration
namespace inbox {
type = private
separator = /
prefix =
inbox = yes
mailbox Drafts {
auto = subscribe
special_use = \Drafts
}
mailbox Junk {
auto = subscribe
special_use = \Junk
}
mailbox Trash {
auto = subscribe
special_use = \Trash
}
mailbox Sent {
auto = subscribe
special_use = \Sent
}
}
# Mail process permissions
mail_uid = vmail
mail_gid = vmail
mail_privileged_group = vmail
# Mailbox creation settings
mail_home = /var/mail/vhosts/%d/%n

Service Configuration

Create conf.d/10-master.conf:

# Service configuration
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}
service pop3-login {
inet_listener pop3 {
port = 110
}
inet_listener pop3s {
port = 995
ssl = yes
}
}
service lmtp {
unix_listener lmtp {
mode = 0600
user = vmail
group = vmail
}
inet_listener lmtp {
port = 24
}
}
service auth {
unix_listener auth-userdb {
mode = 0600
user = vmail
}
}
service auth-worker {
user = vmail
}

SSL Configuration

Create conf.d/10-ssl.conf:

# SSL/TLS configuration
# Disable SSL by default (enable if you have certificates)
ssl = no
# SSL certificate locations (uncomment and configure if using SSL)
#ssl_cert = </etc/ssl/certs/dovecot.pem
#ssl_key = </etc/ssl/private/dovecot.key
# SSL protocols and ciphers
ssl_min_protocol = TLSv1.2
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
ssl_prefer_server_ciphers = yes
# SSL options
ssl_dh = </usr/share/dovecot/dh.pem

User Database File

Create a users file with test accounts (format: username:password:uid:gid::home:):

user1@example.com:{PLAIN}password1:5000:5000::/var/mail/vhosts/example.com/user1::
user2@example.com:{PLAIN}password2:5000:5000::/var/mail/vhosts/example.com/user2::
admin@example.com:{PLAIN}adminpass:5000:5000::/var/mail/vhosts/example.com/admin::

Security Note: In production, use hashed passwords instead of PLAIN. Generate SHA512-CRYPT passwords with:

Terminal window
doveadm pw -s SHA512-CRYPT

Deploying on Klutch.sh

    Create a New Project

    1. Log in to your Klutch.sh dashboard
    2. Click “New Project” to create a project for your mail server
    3. Give it a descriptive name like “dovecot-mail-server”

    Connect Your Repository

    1. Click “New Deployment” within your project
    2. Select GitHub as your git source
    3. Authorize Klutch.sh to access your repositories if you haven’t already
    4. Select the repository containing your Dovecot configuration
    5. Choose the branch you want to deploy (e.g., main or master)

    Configure TCP Traffic

    Since Dovecot is a mail server that requires TCP connections:

    1. In the deployment settings, select TCP as the traffic type
    2. Set the internal port to 143 (IMAP default port)
    3. Your Dovecot server will be accessible externally on port 8000
    4. Click “Deploy” to start the build process

    Important: While Dovecot listens on multiple ports internally (143, 993, 110, 995, 24, 4190), the TCP traffic type on Klutch.sh routes external connections from port 8000 to your specified internal port (143). For production use with multiple protocols, you may need to run separate Dovecot instances or use a mail gateway.

    Attach Persistent Storage

    Mail data requires persistent storage:

    1. Navigate to your deployment’s “Storage” section
    2. Click “Add Volume”
    3. Set the mount path to /var/mail/vhosts
    4. Allocate storage size (start with 10GB, increase based on usage)
    5. Add another volume for configuration if needed:
      • Mount path: /etc/dovecot
      • Size: 1GB
    6. Save the volume configuration

    Your deployment will restart automatically with persistent storage attached.

    Environment Variables

    Configure your Dovecot deployment with environment variables (optional for advanced configurations):

    DOVECOT_HOSTNAME=mail.example.com
    MAIL_LOCATION=maildir:/var/mail/vhosts/%d/%n
    ENABLE_SIEVE=true
    LMTP_SAVE_TO_DETAIL_MAILBOX=yes

    These variables can be used in your configuration files through substitution if you modify the Dockerfile to process them.

Initial Configuration

After your Dovecot server is deployed, complete these initial setup steps:

Verify Server Status

Connect to your container to check Dovecot is running:

Terminal window
# Check Dovecot version
doveadm --version
# View running Dovecot processes
doveadm who
# Check service status
doveconf -n

Test IMAP Connection

Test IMAP connectivity from your local machine:

Terminal window
# Using telnet (replace with your deployment URL)
telnet example-app.klutch.sh 8000
# Once connected, try to login
a1 LOGIN user1@example.com password1
a2 LIST "" "*"
a3 SELECT INBOX
a4 LOGOUT

Or use openssl for testing:

Terminal window
# For plain IMAP
openssl s_client -connect example-app.klutch.sh:8000 -starttls imap
# Test authentication
a1 LOGIN user1@example.com password1

Configure Mail Client

Configure your email client (Thunderbird, Outlook, Apple Mail, etc.):

IMAP Settings:

  • Server: example-app.klutch.sh
  • Port: 8000
  • Security: None (or STARTTLS if configured)
  • Username: user1@example.com
  • Password: your_password

POP3 Settings:

  • Server: example-app.klutch.sh
  • Port: 8000
  • Security: None
  • Username: user1@example.com
  • Password: your_password

Create Mailboxes

Create standard IMAP mailboxes for a user:

Terminal window
# Create mailbox structure
doveadm mailbox create -u user1@example.com INBOX
doveadm mailbox create -u user1@example.com Sent
doveadm mailbox create -u user1@example.com Drafts
doveadm mailbox create -u user1@example.com Trash
doveadm mailbox create -u user1@example.com Junk
# Subscribe to mailboxes
doveadm mailbox subscribe -u user1@example.com INBOX
doveadm mailbox subscribe -u user1@example.com Sent
doveadm mailbox subscribe -u user1@example.com Drafts
doveadm mailbox subscribe -u user1@example.com Trash

User Management

Adding New Users

Add users to the passwd-file:

Terminal window
# Generate a password hash
doveadm pw -s SHA512-CRYPT
# Add to /etc/dovecot/users
echo "newuser@example.com:{SHA512-CRYPT}hash:5000:5000::/var/mail/vhosts/example.com/newuser::" >> /etc/dovecot/users
# Create mailbox directory
mkdir -p /var/mail/vhosts/example.com/newuser
chown -R vmail:vmail /var/mail/vhosts/example.com/newuser
chmod 700 /var/mail/vhosts/example.com/newuser
# Reload Dovecot
doveadm reload

Using SQL Authentication

For larger deployments, switch to SQL authentication:

Update conf.d/10-auth.conf:

passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}

Create dovecot-sql.conf.ext:

driver = mysql
connect = host=db.example.com dbname=mailserver user=dovecot password=secret
password_query = SELECT email as user, password FROM users WHERE email='%u'
user_query = SELECT email as user, 'maildir:/var/mail/vhosts/%d/%n' as mail, 5000 as uid, 5000 as gid FROM users WHERE email='%u'
iterate_query = SELECT email as user FROM users

Managing Passwords

Change user passwords:

Terminal window
# Generate new password hash
doveadm pw -s SHA512-CRYPT -p newpassword
# Update users file with new hash
# Or update database if using SQL authentication
# Force password change on next login (SQL only)
UPDATE users SET password_change_required = 1 WHERE email = 'user@example.com';

Mail Filtering with Sieve

Dovecot includes powerful server-side mail filtering through Sieve:

Enable Sieve Support

Update dovecot.conf:

protocols = imap pop3 lmtp sieve
plugin {
sieve = file:~/sieve;active=~/.dovecot.sieve
sieve_default = /var/mail/sieve/default.sieve
sieve_dir = ~/sieve
sieve_global_dir = /var/mail/sieve/
}

Update conf.d/10-master.conf to add ManageSieve:

service managesieve-login {
inet_listener sieve {
port = 4190
}
}
service managesieve {
process_limit = 1024
}

Create Sieve Filters

Example Sieve script (~/.dovecot.sieve):

require ["fileinto", "envelope", "reject"];
# Filter spam
if header :contains "X-Spam-Status" "Yes" {
fileinto "Junk";
stop;
}
# File mailing list messages
if header :contains "List-Id" "<announce.example.com>" {
fileinto "Lists/Announce";
stop;
}
# Reject messages with specific subject
if header :contains "subject" "URGENT: Wire Transfer" {
reject "Suspected phishing attempt";
stop;
}
# Vacation auto-reply
if header :contains "subject" "vacation" {
vacation :days 7 :subject "Out of Office"
"I'm currently out of office. Will respond when I return.";
}
# Default: keep in INBOX
keep;

Common Sieve Filters

Spam Filtering:

require ["fileinto", "variables"];
if header :contains "X-Spam-Flag" "YES" {
fileinto "Junk";
stop;
}

Domain-Based Filtering:

require ["fileinto", "envelope"];
if envelope :domain :is "from" "marketing.example.com" {
fileinto "Marketing";
stop;
}

Size-Based Filtering:

require ["fileinto", "relational", "comparator-i;ascii-numeric"];
if size :over 5M {
fileinto "Large Messages";
stop;
}

Testing Sieve Scripts

Validate Sieve scripts before deploying:

Terminal window
# Check syntax
sieve-test -t - ~/.dovecot.sieve < test-email.txt
# Compile sieve script
sievec ~/.dovecot.sieve
# List active sieve scripts for user
doveadm sieve list -u user@example.com
# Activate a sieve script
doveadm sieve activate -u user@example.com script-name

SSL/TLS Configuration

Enable encrypted connections for secure mail access:

Generate SSL Certificates

For testing, create self-signed certificates:

Terminal window
# Generate private key
openssl genrsa -out /etc/ssl/private/dovecot.key 4096
# Generate certificate
openssl req -new -x509 -key /etc/ssl/private/dovecot.key \
-out /etc/ssl/certs/dovecot.pem -days 365 \
-subj "/C=US/ST=State/L=City/O=Organization/CN=mail.example.com"
# Set permissions
chmod 600 /etc/ssl/private/dovecot.key
chmod 644 /etc/ssl/certs/dovecot.pem

For production, use Let’s Encrypt or your certificate provider.

Update SSL Configuration

Modify conf.d/10-ssl.conf:

# Enable SSL
ssl = yes
# Certificate paths
ssl_cert = </etc/ssl/certs/dovecot.pem
ssl_key = </etc/ssl/private/dovecot.key
# Require SSL for authentication
disable_plaintext_auth = yes
# SSL protocols
ssl_min_protocol = TLSv1.2
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
ssl_prefer_server_ciphers = yes
# DH parameters
ssl_dh = </usr/share/dovecot/dh.pem
# SSL options
ssl_options = no_compression

Test SSL Connection

Terminal window
# Test IMAPS (port 993)
openssl s_client -connect example-app.klutch.sh:8000 -showcerts
# Test STARTTLS on IMAP
openssl s_client -connect example-app.klutch.sh:8000 -starttls imap
# Verify certificate
openssl x509 -in /etc/ssl/certs/dovecot.pem -text -noout

Quota Management

Implement mailbox quotas to prevent unlimited storage usage:

Configure Quota Plugin

Update dovecot.conf:

mail_plugins = $mail_plugins quota
plugin {
quota = maildir:User quota
quota_rule = *:storage=1GB
quota_rule2 = Trash:storage=+100M
quota_warning = storage=95%% quota-warning 95 %u
quota_warning2 = storage=80%% quota-warning 80 %u
}

Create quota warning script (/usr/local/bin/quota-warning.sh):

#!/bin/bash
PERCENT=$1
USER=$2
cat << EOF | /usr/lib/dovecot/dovecot-lda -d $USER -o "plugin/quota=maildir:User quota:noenforcing"
From: postmaster@example.com
Subject: Quota warning - $PERCENT% full
Content-Type: text/plain; charset=utf-8
Your mailbox is now $PERCENT% full. Please delete unwanted messages to avoid delivery failures.
Current quota: $PERCENT%
EOF

Set User-Specific Quotas

For SQL authentication, add quota to user query:

user_query = SELECT email as user,
'maildir:/var/mail/vhosts/%d/%n' as mail,
5000 as uid, 5000 as gid,
concat('*:storage=', quota_mb, 'M') as quota_rule
FROM users WHERE email='%u'

Check Quota Usage

Terminal window
# Check user quota
doveadm quota get -u user@example.com
# Recalculate quota
doveadm quota recalc -u user@example.com
# List users over quota
doveadm quota get -A | grep "STORAGE.*100"

Enable fast mail searching with FTS (Full-Text Search):

Configure FTS with Squat

Update dovecot.conf:

mail_plugins = $mail_plugins fts fts_squat
plugin {
fts = squat
fts_squat = partial=4 full=10
fts_autoindex = yes
fts_enforced = no
}

Using FTS with Solr

For larger deployments, use Solr for better performance:

mail_plugins = $mail_plugins fts fts_solr
plugin {
fts = solr
fts_solr = url=http://solr:8983/solr/dovecot/
fts_autoindex = yes
fts_enforced = yes
}

Reindex Mailboxes

Terminal window
# Index a single user
doveadm index -u user@example.com INBOX
# Index all mailboxes for user
doveadm index -u user@example.com '*'
# Index all users
doveadm index -A '*'
# Force FTS reindex
doveadm fts rescan -u user@example.com
doveadm index -u user@example.com '*'

Integrating with Postfix

Connect Dovecot with Postfix for complete mail server functionality:

Configure LMTP Delivery

In Postfix main.cf:

# Use Dovecot LMTP for local delivery
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = example.com, example.org
virtual_mailbox_maps = hash:/etc/postfix/virtual_mailboxes
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

Update Dovecot conf.d/10-master.conf:

service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}

SMTP Authentication

Configure Dovecot SASL for Postfix SMTP authentication:

In conf.d/10-master.conf:

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

In Postfix main.cf:

# SMTP AUTH configuration
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes

Backup and Recovery

Implement regular backups for mail data:

Manual Backup

Terminal window
# Backup mail directory
tar -czf dovecot-backup-$(date +%Y%m%d).tar.gz /var/mail/vhosts/
# Backup configuration
tar -czf dovecot-config-$(date +%Y%m%d).tar.gz /etc/dovecot/
# Backup user database
cp /etc/dovecot/users /backup/users-$(date +%Y%m%d).bak
# For SQL authentication
mysqldump -u root -p mailserver > maildb-$(date +%Y%m%d).sql

Automated Backup Script

Create /usr/local/bin/backup-dovecot.sh:

#!/bin/bash
BACKUP_DIR="/backup/dovecot"
DATE=$(date +%Y%m%d-%H%M%S)
RETENTION_DAYS=30
# Create backup directory
mkdir -p $BACKUP_DIR
# Backup mail data
echo "Backing up mail data..."
tar -czf $BACKUP_DIR/mail-$DATE.tar.gz /var/mail/vhosts/
# Backup configuration
echo "Backing up configuration..."
tar -czf $BACKUP_DIR/config-$DATE.tar.gz /etc/dovecot/
# Backup databases
echo "Backing up user database..."
cp /etc/dovecot/users $BACKUP_DIR/users-$DATE.bak
# Remove old backups
echo "Cleaning old backups..."
find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR -name "*.bak" -mtime +$RETENTION_DAYS -delete
echo "Backup completed: $DATE"

Schedule with cron:

Terminal window
# Run daily at 2 AM
0 2 * * * /usr/local/bin/backup-dovecot.sh >> /var/log/dovecot-backup.log 2>&1

Restore Procedures

Terminal window
# Restore mail data
tar -xzf dovecot-backup-20231215.tar.gz -C /
# Restore configuration
tar -xzf dovecot-config-20231215.tar.gz -C /
# Restore users file
cp /backup/users-20231215.bak /etc/dovecot/users
# Fix permissions
chown -R vmail:vmail /var/mail/vhosts/
chmod 600 /etc/dovecot/users
# Rebuild indexes
doveadm force-resync -A '*'
# Restart Dovecot
doveadm reload

Disaster Recovery Strategy

  1. Regular Backups: Schedule daily full backups and incremental backups every 6 hours
  2. Off-site Storage: Store backups in separate location or cloud storage (S3, B2)
  3. Test Restores: Monthly test restore procedures to verify backup integrity
  4. Documentation: Maintain recovery runbook with step-by-step procedures
  5. Monitoring: Alert on backup failures or missing backups
  6. Replication: Consider real-time replication to standby server for high availability

Performance Optimization

Connection Limits

Optimize connection handling in dovecot.conf:

# Login process configuration
service imap-login {
service_count = 1
process_min_avail = 3
process_limit = 100
# High-performance mode
client_limit = 1
}
# IMAP process configuration
service imap {
process_limit = 1024
client_limit = 1
}
# Authentication cache
auth_cache_size = 10M
auth_cache_ttl = 1 hour
auth_cache_negative_ttl = 5 minutes

Memory and CPU

# Process VSZ limits
default_vsz_limit = 256M
default_process_limit = 1000
# Login process limits
service imap-login {
vsz_limit = 64M
}
# Mail process limits
service imap {
vsz_limit = 512M
}

Index and Cache

# Mail index optimization
mail_index_min_size = 128k
mail_cache_min_mail_count = 10
# Mailbox list indexes
mailbox_list_index = yes
mailbox_list_index_very_dirty_syncs = yes

High-Performance Configuration

For high-traffic servers:

# Protocol optimizations
protocol imap {
mail_max_userip_connections = 20
imap_idle_notify_interval = 2 mins
imap_max_line_length = 64k
}
# Performance plugins
mail_plugins = $mail_plugins zlib lazy_expunge
plugin {
# Compress old mail
zlib_save_level = 6
zlib_save = gz
# Lazy expunge for trash
lazy_expunge = Trash
}

Monitoring Performance

Terminal window
# Check active connections
doveadm who
# View process statistics
doveadm stats dump
# Check mailbox performance
doveadm mailbox status -u user@example.com all '*'
# Monitor slow queries
doveadm log find -S anvil

Security Best Practices

Disable Unnecessary Services

# Only enable required protocols
protocols = imap lmtp
# Disable unused authentication mechanisms
auth_mechanisms = plain login

Rate Limiting

Protect against brute-force attacks:

# Login attempt limits
auth_policy_server_url = http://localhost:4001/
auth_policy_server_api_header = Authorization: Basic secret
auth_policy_check_before_auth = no
auth_policy_check_after_auth = yes
auth_policy_report_after_auth = yes
auth_policy_request_attributes = login=%{requested_username} pwhash=%{hashed_password}
# Alternative: fail2ban integration
service auth {
unix_listener auth-master {
mode = 0600
}
}

Firewall Rules

Limit access to mail ports:

Terminal window
# Allow only specific IPs to IMAP
iptables -A INPUT -p tcp --dport 143 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 143 -j DROP
# Rate limit new connections
iptables -A INPUT -p tcp --dport 143 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 143 -m state --state NEW -m recent --update --seconds 60 --hitcount 10 -j DROP

Audit Logging

Enable comprehensive logging:

# Detailed authentication logging
auth_verbose = yes
auth_verbose_passwords = no
auth_debug = no
auth_debug_passwords = no
# Mail access logging
mail_debug = no
verbose_ssl = no
# Log all IMAP commands (for debugging)
protocol imap {
mail_log_prefix = "%s(%u)<%{pid}><%{session}>: "
}
# Login events
login_log_format_elements = user=<%u> method=%m rip=%r lip=%l mpid=%e %c %k

Security Headers

Configure secure mail headers:

# Submission service configuration
protocol submission {
mail_max_userip_connections = 10
}
service submission-login {
inet_listener submission {
port = 587
}
}

Troubleshooting

Dovecot Won’t Start

Check logs:

Terminal window
# View error logs
tail -f /var/log/dovecot/dovecot.log
# Check system journal
journalctl -u dovecot -f
# Verify configuration
doveconf -n
# Test configuration syntax
doveconf > /dev/null

Common issues:

  • Incorrect file permissions on /var/mail or config files
  • Port conflicts (another service using 143, 993, etc.)
  • Missing SSL certificates when SSL is enabled
  • Invalid configuration syntax

Solutions:

Terminal window
# Fix permissions
chown -R vmail:vmail /var/mail/vhosts
chmod -R 700 /var/mail/vhosts
chmod 600 /etc/dovecot/users
# Check port usage
netstat -tuln | grep -E ':(143|993|110|995)'
# Disable SSL temporarily
echo "ssl = no" >> /etc/dovecot/conf.d/10-ssl.conf

Authentication Failures

Symptoms:

  • Users cannot log in
  • “Authentication failed” errors in mail clients
  • Empty inbox after login

Debugging:

Terminal window
# Enable auth debugging
doveconf auth_debug=yes auth_verbose=yes auth_debug_passwords=yes
# Test authentication manually
doveadm auth test user@example.com password
# Check user database
doveadm user user@example.com
# View auth logs
tail -f /var/log/dovecot/dovecot.log | grep auth

Common causes:

  • Incorrect password hash format in users file
  • Wrong username format (missing @domain)
  • Incorrect permission on /etc/dovecot/users
  • SQL connection failures
  • PAM configuration issues

Connection Issues

Cannot connect to server:

Terminal window
# Test network connectivity
telnet example-app.klutch.sh 8000
# Check if Dovecot is listening
netstat -tuln | grep :143
# Verify firewall rules
iptables -L -n | grep 143
# Test from inside container
nc -zv localhost 143

Timeout errors:

Terminal window
# Check process limits
doveconf | grep process_limit
# View connection statistics
doveadm who
doveadm stats dump
# Increase limits if needed
echo "default_process_limit = 2000" >> /etc/dovecot/dovecot.conf

Mailbox Corruption

Symptoms:

  • Missing messages
  • “Internal error” when accessing mailbox
  • Incorrect message counts

Recovery:

Terminal window
# Force rebuild of indexes
doveadm force-resync -u user@example.com '*'
# Fix mailbox consistency
doveadm mailbox verify -u user@example.com '*'
# Rebuild FTS indexes
doveadm fts rescan -u user@example.com
doveadm index -u user@example.com '*'
# Check filesystem
fsck /dev/sda1

Performance Issues

Slow IMAP responses:

Terminal window
# Check index status
doveadm mailbox status -u user@example.com all '*'
# Rebuild slow indexes
doveadm index -u user@example.com INBOX
# Check for large mailboxes
du -sh /var/mail/vhosts/*/* | sort -h
# Monitor process resources
top -u vmail

High CPU usage:

Terminal window
# Identify problematic processes
ps aux | grep dovecot | sort -k3 -r
# Check for infinite loops
strace -p <pid>
# Review configuration
doveconf -n | grep -E '(process_limit|client_limit|vsz_limit)'

SSL/TLS Errors

Certificate issues:

Terminal window
# Verify certificate validity
openssl x509 -in /etc/ssl/certs/dovecot.pem -text -noout
# Check certificate expiration
openssl x509 -in /etc/ssl/certs/dovecot.pem -noout -dates
# Test SSL connection
openssl s_client -connect example-app.klutch.sh:8000 -starttls imap
# Verify certificate chain
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/dovecot.pem

Protocol errors:

Terminal window
# Check SSL configuration
doveconf -n | grep ssl
# Test specific TLS version
openssl s_client -connect example-app.klutch.sh:8000 -tls1_2 -starttls imap
# View SSL session
openssl s_client -connect example-app.klutch.sh:8000 -showcerts -starttls imap

Production Checklist

Before going live with your Dovecot deployment, verify:

Security

  • SSL/TLS certificates installed and valid
  • Plaintext authentication disabled (requires SSL)
  • Strong password hashing (SHA512-CRYPT or better)
  • Firewall rules configured and tested
  • Rate limiting enabled for auth attempts
  • Fail2ban or similar intrusion prevention configured
  • Regular security updates scheduled
  • Audit logging enabled
  • Root login disabled
  • Unnecessary services disabled

Performance

  • Connection limits configured appropriately
  • Process limits set based on expected load
  • Memory limits configured (vsz_limit)
  • Indexes enabled and optimized
  • FTS (Full-Text Search) configured
  • Quota management implemented
  • Log rotation configured
  • Resource monitoring in place

Backup and Recovery

  • Automated backup script created and tested
  • Backup retention policy defined
  • Off-site backup storage configured
  • Restore procedures documented and tested
  • Recovery time objective (RTO) defined
  • Recovery point objective (RPO) defined
  • Disaster recovery plan documented

Monitoring

  • Health checks configured
  • Log aggregation set up
  • Alerting for critical errors
  • Performance metrics collection
  • Disk space monitoring
  • Connection monitoring
  • Authentication failure alerts
  • SSL certificate expiration alerts

Documentation

  • Server configuration documented
  • User management procedures documented
  • Backup/restore procedures documented
  • Troubleshooting guide created
  • Emergency contact information listed
  • DNS records documented (MX, SPF, DKIM, DMARC)
  • Mail client configuration guide created

Compliance

  • Data retention policy defined
  • Privacy policy created (GDPR, CCPA)
  • Encryption at rest configured
  • Encryption in transit enforced
  • Audit trail maintained
  • Legal hold procedures defined

Additional Resources

Conclusion

You’ve successfully deployed Dovecot on Klutch.sh, creating a powerful and secure mail server capable of handling IMAP, POP3, and LMTP protocols. With persistent storage for mail data, SSL/TLS encryption for secure connections, and advanced features like Sieve filtering and full-text search, your Dovecot server provides a complete mail retrieval and storage solution.

Dovecot’s robust architecture, combined with Klutch.sh’s container platform, gives you a scalable mail server that can grow from serving a handful of users to thousands of mailboxes. The combination of TCP traffic routing, persistent volumes, and GitHub-based deployments makes maintaining and updating your mail infrastructure straightforward and reliable.

Remember to implement regular backups, monitor server performance, keep your Dovecot installation updated with security patches, and follow email best practices including proper DNS configuration (MX, SPF, DKIM, DMARC records) for a production mail server. Whether you’re running a personal mail server, small business email, or a larger mail hosting service, Dovecot on Klutch.sh provides the foundation for reliable, secure email communication.