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:

  1. 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
  2. Identify the Dovecot service unit name used by systemd.
    $ systemctl list-unit-files --type=service | grep -E '^dovecot\.service'
    dovecot.service                              enabled         enabled
  3. 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.

  4. Stop the local dovecot.service unit on every cluster node.
    $ sudo systemctl stop dovecot

    No output indicates the unit was stopped.

  5. 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.

  6. 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.

  7. 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.

  8. Group the resources so dovecot_ip starts before dovecot_service.
    $ sudo pcs resource group add dovecot-stack dovecot_ip dovecot_service
  9. 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
  10. 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 
  11. 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.

  12. 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
  13. 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.

  14. 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).