I don’t often have to restart my public-facing virtual server, but when I do, I have had trouble with one or two services not starting properly. The server picks up my mail via Postfix. From my office, I then run a periodic task which connects via POP to Dovecot on the server, and transfers the mail to my main office machine. This happens over an encrypted OpenVPN connection, so Dovecot itself doesn’t need to implement any encrypted transport, or accept connections on any publicly-accessible ports. One problem was, there was by default no coordination between the startup of the VPN connection and the startup of the Dovecot process. If the latter got going first, then it would fail to open a listening socket on the LAN-internal interface, because the VPN connection had not created that interface yet. Today I finally sat down and worked out a fix. This requires adding a dependency between the two services, via their systemd service configuration files. systemd offers a convenient method for allowing you to customize service configurations without having to completely replace their .service files. Instead, you create “drop-in” files, which amend the configuration in the desired ways. In this case, the original Dovecot service config file is /lib/systemd/system/dovecot.service, which I didn’t need to touch. Instead, I created the directory /etc/systemd/system/dovecot.service.d, to contain my amendments to the service definition. In here, I put a file which I decided to call geek-central.conf, which only needed to contain [Unit] Requires=openvpn-server@geek-central.service After=openvpn-server@geek-central.service (Note that the OpenVPN service definitions are “template” files, which means you can start multiple service instances from a common template, with a unique name after the “@” character. It’s up to the software implementing the service to use this instance name as a hint as to which configuration to choose for the service instance -- in this case, it looks for the VPN setup details in /etc/openvpn/server/geek-central.conf.) First I did a “systemctl daemon-reload”, followed by “systemctl show dovecot.service”, just to confirm it was picking up the configuration changes correctly -- namely, that the “Requires=” and “After=” entries showed the combination of the default settings and my amendments. Then, of course, to do a proper test, I had to reboot the server. Which worked. I also did a similar thing to fix a race condition between the startup of the SQLGrey mail greylisting service and the database server it is using. The former requires the latter, but the default service configuration doesn’t specify this, again leading to startup failures -- I would class this as a configuration bug. A fix for this was similarly easy.