How to create a systemd backup timer & service in 10 seconds
In our previous post Create a systemd service for your docker-compose project in 10 seconds we introduced a script that automatically creates a systemd service to start a docker-compose-based project. In this post, we’ll show
First, you need to create a file named backup.sh
in the directory where docker-compose.yml
is located. This file will be run by the systemd service every day. What that file contains is entirely up to you and we will provide examples in future blogposts.
Secondly, run
wget -qO- https://techoverflow.net/scripts/create-backup-service.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/redmine-mydomain
will cause redmine-mydomain-backup
to be used a service name.
Example output from the script:
Creating systemd service... /etc/systemd/system/redmine-mydomain-backup.service
Creating systemd timer... /etc/systemd/system/redmine-mydomain-backup.timer
Enabling & starting redmine-mydomain-backup.timer
Created symlink /etc/systemd/system/timers.target.wants/redmine-mydomain-backup.timer → /etc/systemd/system/redmine-mydomain-backup.timer.
The script will create /etc/systemd/systemd/redmine-mydomain-backup.service
containing the specification on what exactly to run:
[Unit]
Description=redmine-mydomain-backup
[Service]
Type=oneshot
ExecStart=/bin/bash backup.sh
WorkingDirectory=/var/lib/redmine-mydomain
and /etc/systemd/systemd/redmine-mydomain-backup.timer
containing the logic when the .service
is started:
[Unit]
Description=redmine-mydomain-backup
[Timer]
OnCalendar=daily
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 redmine-mydomain-backup.timer
Example output:
● redmine-mydomain-backup.timer - redmine-mydomain-backup
Loaded: loaded (/etc/systemd/system/redmine-mydomain-backup.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Thu 2020-12-10 02:50:31 CET; 19min ago
Trigger: Fri 2020-12-11 00:00:00 CET; 20h left
Triggers: ● redmine-mydomain-backup.service
Dec 10 02:50:31 myserverhostname systemd[1]: Started redmine-mydomain-backup.
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 redmine-mydomain-backup.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 redmine-mydomain-backup.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 redmine-mydomain-backup.timer
Source code:
#!/bin/bash
# Create a systemd service & timer that runs the given backup daily
# by Uli Köhler - https://techoverflow.net
# Licensed as CC0 1.0 Universal
export SERVICENAME=$(basename $(pwd))-backup
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=/bin/bash backup.sh
WorkingDirectory=$(pwd)
EOF
echo "Creating systemd timer... $TIMERFILE"
sudo cat >$TIMERFILE <<EOF
[Unit]
Description=$SERVICENAME
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
EOF
echo "Enabling & starting $SERVICENAME.timer"
sudo systemctl enable $SERVICENAME.timer
sudo systemctl start $SERVICENAME.timer