Operate Dovecot Directors Safely with doveadm
You will use doveadm director to inspect a Dovecot director, see where a user is assigned, change a backend's share of new connections, and drain a backend in a controlled way. Allow about 20 minutes for a read-only check, or longer if you are changing production traffic. The examples use the installed dovecot-core package, version 1:2.3.21+dfsg1-2ubuntu6.5, and the local doveadm-director(1) manual page describes Dovecot v2.3 behaviour.
The route
Jump straight to the step you need, or tick off Done means at the end.
These commands manage live mail routing. Read-only status, map, ring status and dump commands are normally safe for an operator with access to the director socket. Adding, removing, flushing, moving or changing a backend can affect users immediately. Use a maintenance window for disruptive work, record the original status first, and use the account and privileges that your Dovecot installation requires. Do not add sudo automatically: the socket permissions are part of the deployment's access control.
1. Confirm the command and socket
Start by checking which binary and package you are about to use:
$ command -v doveadm
/usr/bin/doveadm
$ dpkg-query -W -f='${Package} ${Version}\n' dovecot-core
dovecot-core 1:2.3.21+dfsg1-2ubuntu6.5
$ doveadm director
usage: doveadm [-Dv] [-f <formatter>] director <command> ...
The local manual gives /run/dovecot/director-admin as the default admin socket. A different base_dir can place it elsewhere. Use -a with an absolute UNIX socket path, or with HOSTNAME:PORT for a TCP director socket:
$ doveadm director -a /run/dovecot/director-admin status
If this reports a connection or permission error, stop and check the running Dovecot configuration and socket ownership. Do not work around a denied admin socket by exposing a new TCP listener without reviewing its authentication and network boundaries.
2. Record the current director state
Run the read-only status commands before changing anything:
$ doveadm director status
mail server ip vhosts users
192.168.10.1 100 125
192.168.10.2 100 144
192.168.10.3 100 115
$ doveadm director ring status
director ip port type last failed status
192.168.10.10 9090 self never synced
Your rows will differ. The first command shows the assigned mail servers, their virtual-host counts and current users. The ring command shows director peers; a healthy peer normally reaches synced. Save this output in your change record. The command doveadm director dump is also useful: it prints the current host configuration as doveadm commands that can restore the state after a full director-cluster restart.
$ doveadm director dump > director-state-before.txt
$ test -s director-state-before.txt && echo 'state dump saved'
state dump saved
Keep that file private because it describes internal hosts. It is a recovery record, not a substitute for a tested configuration backup.
3. Check one user's assignment
Use the exact login name understood by your user database:
$ doveadm director status [email protected]
Current: 192.168.10.1 (expires 2030-06-18 20:17:04)
Hashed: 192.168.10.2
Initial config: 192.168.10.3
The names and timestamps are examples of the documented fields, not values to expect literally. Current is the live assignment while connections remain. Hashed is where the user would go after the saved assignment expires, assuming the director state stays unchanged. Initial config describes the result after the proxy cluster returns to its initial configuration. This distinction prevents a common mistake: treating the hashed destination as proof that existing connections have already moved.
To inspect mappings rather than one user, use:
$ doveadm director map 192.168.10.1
[email protected] 192.168.10.1
The director uses 32-bit hashes, so the manual warns that a map cannot reliably enumerate every user who recently logged in. Treat it as an operational view, not an authoritative account of all sessions.
4. Add a backend or change its weight
The vhost_count controls the backend's relative share of new assignments. The documented default is 100. Adding a host that already exists changes its count, so check the spelling and current status first:
$ doveadm director add mail04.example.net 150
$ doveadm director status
mail server ip vhosts users
mail04.example.net 150 0
A higher count gives a backend more virtual hosts relative to its peers; it is a weighting mechanism, not a fixed user limit. If you are introducing a new machine, also add it to the persistent director_mail_servers setting in /etc/dovecot/dovecot.conf as part of the normal configuration change. Otherwise a later full restart can lose the manually added host.
There is no separate undo operation for this example. Restore the previous count explicitly, then verify:
$ doveadm director add mail04.example.net 100
$ doveadm director status
5. Drain a backend carefully
Before maintenance, first stop new assignments by setting the backend's count to zero with the management method used by your installed Dovecot, then confirm the status. On the local binary, the command list includes update:
$ doveadm director update mail04.example.net 0
$ doveadm director status
mail04.example.net 0 87
The local v2.3 manpage documents the equivalent operational idea through add, which changes an existing host's count. Prefer the syntax exposed by doveadm director on the machine you are operating, and test it during a maintenance window. A zero count does not remove existing assignments by itself.
To move users away, run the documented flush command. This is service-disrupting: without -F, existing connections are kicked and users are moved in batches:
$ doveadm director flush --max-parallel 25 mail04.example.net
$ doveadm director status
mail04.example.net 0 0
The default maximum parallelism is 100. A smaller value reduces the temporary load spike but takes longer. Do not use -F casually: it drops associations without kicking existing connections and does not run configured flush scripts. If the backend must return, set its count back to its previous value and confirm that the service and director ring are healthy before allowing traffic.
6. Move or remove only with a recovery path
For one known user, move changes the assignment and kills that user's existing connections:
$ doveadm director move [email protected] mail02.example.net
$ doveadm director status [email protected]
Use this for a targeted repair, not as a substitute for draining a host. To remove a backend permanently, first set its weight to zero, flush its users, confirm that the count is zero, and only then run:
$ doveadm director remove mail04.example.net
$ doveadm director status
mail server ip vhosts users
Removal is a configuration change, not a shutdown command. Keep the dump and update director_mail_servers in the persistent configuration if the server is gone for good. Recovery is to re-add the host with its intended count and restore the persistent setting, provided the host and its Dovecot services are available.
Done means
- You confirmed the installed
doveadmanddovecot-coreversions and the correct admin socket. - You saved a director dump and checked ring and backend status before changing traffic.
- You interpreted a user's current, hashed and initial assignments separately.
- You treated vhost counts as relative weights, not capacity guarantees.
- You drained users in a planned window and understood the connection impact of
flush,moveandremove. - You verified the final status and retained a route to restore the previous backend state.