How to create systemd service timer that runs Nextcloud cron.php in 10 seconds

This post shows you a really quick method to create a systemd timer that runs cron.php on dockerized nextcloud (using docker-compose). We created a script that automatically creates a systemd timer and related service to run cron.php hourly using the command from our previous post How to run Nextcloud cron in a docker-compose based setup:

 

In order to run our autoinstall script, run:

wget -qO- https://techoverflow.net/scripts/install-nextcloud-cron.sh | sudo bash /dev/stdin

from the directory where docker-compose.yml is located. Note that the script will use the directory name as a name for the service and timer that is created. For example, running the script in /var/lib/nextcloud-mydomain will cause nextcloud-mydomain-cron to be used a service name.

Example output from the script:

Creating systemd service... /etc/systemd/system/nextcloud-mydomain-cron.service
Creating systemd timer... /etc/systemd/system/nextcloud-mydomain-cron.timer
Enabling & starting nextcloud-mydomain-cron.timer
Created symlink /etc/systemd/system/timers.target.wants/nextcloud-mydomain-cron.timer → /etc/systemd/system/nextcloud-mydomain-cron.timer.

The script will create /etc/systemd/systemd/nextcloud-mydomain-cron.service containing the specification on what exactly to run:

[Unit]
Description=nextcloud-mydomain-cron

[Service]
Type=oneshot
ExecStart=/usr/bin/docker-compose exec -T -u www-data nextcloud php cron.php
WorkingDirectory=/var/opt/nextcloud-mydomain

and /etc/systemd/systemd/nextcloud-mydomain-cron.timer containing the logic when the .service is started:

[Unit]
Description=nextcloud-mydomain-cron

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target

and will automatically start and enable the timer. This means: no further steps are needed after running this script!

In order to show the current status of the service, use e.g.

sudo systemctl status nextcloud-mydomain-cron.timer

Example output:

● nextcloud-mydomain-cron.timer - nextcloud-mydomain-cron
     Loaded: loaded (/etc/systemd/system/nextcloud-mydomain-cron.timer; enabled; vendor preset: disabled)
     Active: active (waiting) since Fri 2022-04-01 00:33:48 UTC; 6min ago
    Trigger: Fri 2022-04-01 01:00:00 UTC; 19min left
   Triggers: ● nextcloud-mydomain-cron.service

Apr 01 00:33:48 CoreOS systemd[1]: Started nextcloud-mydomain-cron.

In the

Trigger: Fri 2020-12-11 00:00:00 CET; 20h left

line you can see when the service will be run next. By default, the script generates tasks that run OnCalendar=daily, which means the service will be run on 00:00:00 every day. Checkout the systemd.time manpage for further information on the syntax you can use to specify other timeframes.

In order to run the backup immediately (it will still run daily after doing this), do

sudo systemctl start nextcloud-mydomain-cron.service

(note that you need to run systemctl start on the .service! Running systemctl start on the .timer will only enable the timer and not run the service immediately).

In order to view the logs, use

sudo journalctl -xfu nextcloud-mydomain-cron.service

(just like above, you need to run journalctl -xfu on the .service, not on the .timer).

In order to disable automatic backups, use e.g.

sudo systemctl disable nextcloud-mydomain-cron.timer

Source code:

#!/bin/bash
# Create a systemd service & timer that runs cron.php on dockerized nextcloud
# by Uli Köhler - https://techoverflow.net
# Licensed as CC0 1.0 Universal
export SERVICENAME=$(basename $(pwd))-cron

export SERVICEFILE=/etc/systemd/system/${SERVICENAME}.service
export TIMERFILE=/etc/systemd/system/${SERVICENAME}.timer

echo "Creating systemd service... $SERVICEFILE"
sudo cat >$SERVICEFILE <<EOF
[Unit]
Description=$SERVICENAME

[Service]
Type=oneshot
ExecStart=$(which docker-compose) exec -T -u www-data nextcloud php cron.php
WorkingDirectory=$(pwd)
EOF

echo "Creating systemd timer... $TIMERFILE"
sudo cat >$TIMERFILE <<EOF
[Unit]
Description=$SERVICENAME

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target
EOF

echo "Enabling & starting $SERVICENAME.timer"
sudo systemctl enable $SERVICENAME.timer
sudo systemctl start $SERVICENAME.timer