Schedule jobs with systemd-timer
Since I had trouble using cron, and crontab, in the past I decided to use systemd instead. You are also able to monitor them in a better way than in cron.
1st Example: CrowdSec hub update in docker container
Hub updates in the CrowdSec container must be handled manually because there is no (systemd) services installed which can handle that.
At first I created a basic shell script, for instance, called crowdsec-hub-update. Yes, without .sh file extension.
1
2
3
#!/usr/bin/bash
docker exec crowdsec cscli hub update
docker exec crowdsec cscli hub upgrade
Hint: Create this file in
/usr/local/binto make it globally available.
Configuration
Create a timer-file in /etc/systemd/system called crowdsec-hub-update.timer.
1
2
3
4
5
6
7
8
[Unit]
Description="CrowdSec hub update everyday at every hour."
[Timer]
Unit=crowdsec-hub-update.service
OnBootSec=1min
OnCalendar=*-*-* *:00:00 # DOW YYYY-MM-DD HH:MM:SS
[Install]
WantedBy=timers.target
| value | description |
|---|---|
| Unit= | which unit (or service-file) this timer triggers |
| OnBootSec= | waiting after boot before 1st executing, comment or delete this line if you just want to make use of OnCalendar entry |
| OnCalendar= | defines a exact time, like in cron, when the unit is executed next |
After that create the corresponding unit in the same folder called crowdsec-hub-update.service.
1
2
3
4
5
6
7
[Unit]
Description="Update and upgrade CrowdSec Hub."
Requires=crowdsec-hub-update.timer
[Service]
Type=simple
ExecStart=/path/to/crowdsec-hub-update
User=root
| value | description |
|---|---|
| Requires= | On which object does it depend |
| ExecStart= | path to the script, this is handy if you have more than one command |
| User= | which user executes the command |
Usage
1
2
systemctl enable crowdsec-hub-update.timer
systemctl ( start | stop ) crowdsec-hub-update.timer
When you start the timer the service will be executed once!
2nd Example: Add MACVLAN interface for AdGuard Home container
I want my AdGuard Home container to have its own IP address, but this setting, however, gets lost on every reboot. So… I created a bash script named add-macvlan-interface.
1
2
3
4
#!/bin/bash
ip link add mac0 link eth0 type macvlan mode bridge
ip addr add 192.168.0.252/30 dev mac0
ifconfig mac0 up
This creates a new device called
mac0linked as bridge toeth0with an gateway IP set. When the docker container boots, it is a member of this network, the network interface will obtain the first ip which is.253.
Configuration tasks at boot
Create a service-file in /etc/systemd/system named, e.g., add-mac-vlan-int.service.
1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description="Add Docker MacVLAN interface for AdGuard Home."
Wants=network.target
After=syslog.target network-online.target
[Service]
Type=simple
ExecStart=/home/dietpi/git/add-macvlan-interface
Restart=on-failure
RestartSec=10
KillMode=process
User=root
[Install]
WantedBy=multi-user.target
It is the same process as creating recurring tasks, but without a timer-file. This unit will start at boot (when you enable it) after the network got initialized.
Usage
1
systemctl enable add-macvlan-int.service
You can add
--nowif you want to also start the service with enabling.
Troubleshooting
1
2
systemctl status crowdsec-hub-update.timer
systemctl status crowdsec-hub-update.service
1
jounralctl -u crowdsec-hub-update.service
