By default, most services will start just fine on boot when they bind to 0.0.0.0
on the host to listen on any IP that might happen to appear. However, if you try to get a service to bind to a specific IP, it can fail on boot.
This is the case with memcached
for example (which can bind to a specific IP with the -l, --listen
option), but fails with error, Cannot assign requested address
.
$ sudo systemctl status memcached
? memcached.service - memcached daemon
Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Thu 2022-10-20 00:54:34 AEDT; 18min ago
Process: 936 ExecStart=/usr/bin/memcached -p ${PORT} -u ${USER} -m ${CACHESIZE} -c ${MAXCONN} $OPTIONS (code=exited, status=71)
Main PID: 936 (code=exited, status=71)
Oct 20 00:54:34 swift-02 systemd[1]: Started memcached daemon.
Oct 20 00:54:34 swift-02 memcached[936]: bind(): Cannot assign requested address
Oct 20 00:54:34 swift-02 memcached[936]: failed to listen on TCP port 11211: Cannot assign requested address
Oct 20 00:54:34 swift-02 systemd[1]: memcached.service: Main process exited, code=exited, status=71/OSERR
Oct 20 00:54:34 swift-02 systemd[1]: memcached.service: Failed with result 'exit-code'.
Often services only have a dependency on network.target
but this isn’t enough in this case as an IP isn’t necessarily obtained by this point. So the fix is to add a further dependency on network-online.target
to start the service once the machine is actually on the network.
Adding this dependency to an existing service is pretty easy, we just need to create a systemd service override, like this one for memcached
.
sudo mkdir -p /etc/systemd/system/memcached.service.d
cat << EOF | sudo tee /etc/systemd/system/memcached.service.d/memcached.service
[Unit]
After=network-online.target
EOF
sudo systemctl daemon-reload
Now when you reboot, the new dependency will be taken into account and memcached
will be started once the machine is actually on the network.