A Dovecot high availability setup keeps IMAP and POP access reachable during node failures by moving a single floating IP between cluster members. Mail clients continue to connect to one stable endpoint (commonly a DNS name pointing at the floating IP) while the active node changes behind the scenes.
A Pacemaker and Corosync cluster managed with pcs runs resources on one node at a time and monitors them for failures. An IPaddr2 resource assigns the floating IP on the active node, a systemd resource starts dovecot.service, and a resource group enforces ordering so the IP is online before Dovecot accepts connections.
This design is active/passive and relies on shared or replicated mailbox storage plus identical Dovecot configuration under /etc/dovecot/ on every node. Keep TLS certificates and authentication backends consistent across nodes, avoid running Dovecot outside of cluster control, and plan a failover test because existing client sessions drop during the stop/start sequence.
Steps to set up Dovecot high availability with PCS:
- Confirm the cluster is online with quorum.
$ sudo pcs status Cluster name: clustername Cluster Summary: * Stack: corosync (Pacemaker is running) * Current DC: node-01 (version 2.1.6-6fdc9deea29) - partition with quorum * Last updated: Thu Jan 1 04:42:38 2026 on node-01 * Last change: Thu Jan 1 04:30:13 2026 by root via cibadmin on node-01 * 3 nodes configured * 0 resource instances configured Node List: * Online: [ node-01 node-02 node-03 ] Full List of Resources: * No resources Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled
- Identify the Dovecot service unit name used by systemd.
$ systemctl list-unit-files --type=service | grep -E '^dovecot\.service' dovecot.service enabled enabled
- Check the listen setting to ensure Dovecot binds to the floating IP address.
$ sudo doveconf -h listen *
Use * to listen on all addresses, or set listen to the floating IP when binding must be restricted.
- Stop the local dovecot.service unit on every cluster node.
$ sudo systemctl stop dovecot
No output indicates the unit was stopped.
- Disable dovecot.service autostart on every cluster node.
$ sudo systemctl disable dovecot Synchronizing state of dovecot.service with SysV service script with /usr/lib/systemd/systemd-sysv-install. Executing: /usr/lib/systemd/systemd-sysv-install disable dovecot Removed "/etc/systemd/system/multi-user.target.wants/dovecot.service". Synchronizing state of dovecot.service with SysV service script with /usr/lib/systemd/systemd-sysv-install. Executing: /usr/lib/systemd/systemd-sysv-install disable dovecot Removed "/etc/systemd/system/multi-user.target.wants/dovecot.service". Synchronizing state of dovecot.service with SysV service script with /usr/lib/systemd/systemd-sysv-install. Executing: /usr/lib/systemd/systemd-sysv-install disable dovecot Removed "/etc/systemd/system/multi-user.target.wants/dovecot.service".
Do not mask dovecot.service, because masking prevents pcs from starting the resource.
- Create a floating IP resource for the mailbox endpoint.
$ sudo pcs resource create dovecot_ip ocf:heartbeat:IPaddr2 ip=192.0.2.70 cidr_netmask=24 op monitor interval=30s
Using the wrong cidr_netmask or an in-use IP can break routing and cause client outages.
- Create the Dovecot service resource.
$ sudo pcs resource create dovecot_service systemd:dovecot op monitor interval=30s
The systemd:dovecot agent manages dovecot.service through systemd, so boot autostart can remain disabled without breaking cluster starts.
- Group the resources so dovecot_ip starts before dovecot_service.
$ sudo pcs resource group add dovecot-stack dovecot_ip dovecot_service
- Verify the resource group placement.
$ sudo pcs status resources * Resource Group: dovecot-stack: * dovecot_ip (ocf:heartbeat:IPaddr2): Started node-01 * dovecot_service (systemd:dovecot): Started node-01 - Confirm the floating IP is assigned on the node running the group.
$ ip -brief address show | grep 192.0.2.70 eth0@if456 UP 192.0.2.11/24 192.0.2.70/24
- Move the resource group to another node for a failover test.
$ sudo pcs resource move dovecot-stack node-02
Active IMAP and POP sessions drop during the failover while the IP and service restart on the new node.
- Confirm the group starts on the target node after the move.
$ sudo pcs status resources * Resource Group: dovecot-stack: * dovecot_ip (ocf:heartbeat:IPaddr2): Started node-02 * dovecot_service (systemd:dovecot): Started node-02 - Clear the temporary move constraint.
$ sudo pcs resource clear dovecot-stack
Leaving the constraint in place pins dovecot-stack to that node until the constraint is removed.
- Test a Dovecot listener port on the floating IP from a separate host.
$ nc -vz 192.0.2.70 993 Connection to 192.0.2.70 993 port [tcp/imaps] succeeded!
Common ports are 143 (IMAP), 993 (IMAPS), 110 (POP3), and 995 (POP3S).
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
