How can I configure a systemd service to restart periodically?

LinuxServiceSystemd

Linux Problem Overview


I have a simple systemd service that needs to be periodically restarted to keep its process from bugging out. Is there a configuration option for systemd services to periodically restart them? All of the Restart* options seem to pertain to restarting the service when it exits.

Linux Solutions


Solution 1 - Linux

For systemd version >= 229, there is an option called RuntimeMaxSec, which terminates the service after it has been running for the given period of time.

e.g.

[Service]
Restart=always
RuntimeMaxSec=604800

To me this seems more elegant than abusing Type=notify and WatchdogSec.

systemd provides a clean way to add and override directives in systemd unit files provided by vendors. Drop-In Units are described in man systemd.unit. For example, if you wanted to periodically restart the foo service provided by a package, you would create a file named /etc/systemd/system/foo.service.d/periodic-restart.conf. The contents would be as shown above. Then:

 systemctl daemon-reload
 systemctl restart foo

You can confirm that the Drop-In unit has been loaded because it will be reported in the status output:

 systemctl status

Finally, you can confirm the directive has been included by searching the systemctl show output:

 systemctl show foo.service | grep RuntimeMax

The directive reported by systemctl show will be "RuntimeMaxUSec`

Solution 2 - Linux

I saw a solution here that seemed elegant, if a bit roundabout. The key idea is to create a one-shot service triggered by a timer that restarts another service.

For the timer:

[Unit]
Description=Do something daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

For the one-shot service:

[Unit]
Description=Restart service

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl try-restart my_program.service

For the one-shot service on Ubuntu 16.04 LTS:

[Unit]
Description=Restart service

[Service]
Type=oneshot
ExecStart=/bin/systemctl try-restart my_program.service

This solution lets you leverage systemd's timers, including the ability to restart the service at a particular time of day, and not just after some amount of time has elapsed.

Solution 3 - Linux

How about a crontab. Example:

30 3 * * sun /bin/systemctl restart yourService

That would restart the service named yourService at 3:30 AM each Sunday.

You may like this solution if you want something working in whatever Unix-like server (e.g. you do not want to worry about a specific systemd version, etc.).

Solution 4 - Linux

Yes, you can make your service to restart it periodically by making your service of Type=notify. Add this option in [Service] section of your service file along with Restart=always and give WatchdogSec=xx, where xx is the time period in second you want to restart your service. Here your process will be killed by systemd after xx time period and will be restarted by systemd again. for eg.

[Unit]
.
.

[Service]
Type=notify
.
.
WatchdogSec=10
Restart=always
.
.

[Install]
WantedBy= ....

Solution 5 - Linux

Wanted to comment on the

[Service]
Restart=always
RuntimeMaxSec=604800

answer above but can't w/o more points.

Comment is that this solution will invoke failure handling set by OnFailure=failure_handling.service. Since the scheduled restart isn't a real failure any logging, notifications, etc. from the failure handling service will be unwanted and probably disruptive.

An actual periodic restart would be a sensible feature for systemd, but I won't hold my breath.

Solution 6 - Linux

Just some alternate approaches to ultimately reach the same goal:

  • if you have control over the service implementation you could make it end voluntarily after a while, for example either plain exiting after a certain number of iterations (if applicable) or using a timeout timer with a handler sendin itself a SIGTERM/SIGKILL
  • if voluntary service ending is not feasible/practical you could have a small cron-based script killing the service process(es).

Solution 7 - Linux

Copy-paste solution for systemd version >= 229:

SERVICE="systemd-resolved.service"
env SYSTEMD_EDITOR=tee sudo -E systemctl edit --system ${SERVICE} <<EOF
[Service]
Restart=always
RuntimeMaxSec=7200
EOF

sudo systemctl daemon-reload && sudo systemctl restart "${SERVICE}"

Check:

systemd-delta | grep ${SERVICE}
# NOTE: property here must be requested with "U": RuntimeMaxUSec
systemctl show ${SERVICE} --property=RuntimeMaxUSec

Rollback:

SERVICE="systemd-resolved.service"
sudo rm -r "/etc/systemd/system/${SERVICE}.d"
sudo systemctl daemon-reload
sudo systemctl restart ${SERVICE}

More elegant would be the following:

SERVICE="systemd-resolved.service"
sudo systemctl set-property ${SERVICE} RuntimeMaxSec=7200

But it does not work for some reason:

Failed to set unit properties on systemd-resolved.service: Cannot set property RuntimeMaxUSec, or unknown property.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwesView Question on Stackoverflow
Solution 1 - LinuxAlex ForbesView Answer on Stackoverflow
Solution 2 - LinuxmatmatView Answer on Stackoverflow
Solution 3 - LinuxFritz ZauckerView Answer on Stackoverflow
Solution 4 - LinuxSaturnView Answer on Stackoverflow
Solution 5 - LinuxE GowView Answer on Stackoverflow
Solution 6 - LinuxDan CornilescuView Answer on Stackoverflow
Solution 7 - LinuxjetnetView Answer on Stackoverflow