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