Automate tasks with docker-compose and systemd
I have several tasks encapsulated in Docker containers which I need to trigger on a regular basis. The scheduling can be done with systemd. Both tools together have proven to be a quite powerful combination.
# Example: Backup service
Let's assume we have a backup service that lives in
This folder contains a
docker-compose.yaml file which contains the configuration of a backup service.
We need one systemd unit for the service and one for the timer. Both are shown below. The setup is pretty straight forward.
# /etc/systemd/system/backup.service [Unit] Description=Backup service Requires=docker.service After=docker.service # Send mail in case of an error OnFailure=status-email-user@%n.service [Service] WorkingDirectory=/opt/backup ExecStart=/usr/local/bin/docker-compose up [Install] WantedBy=multi-user.target
# /etc/systemd/system/backup.timer [Unit] Description=Timer for backup service Requires=backup.service [Timer] Unit=backup.service # Time to wait after booting before we run first time OnBootSec=10min # Define a calendar event (see `man systemd.time`) OnCalendar=*-*-* 03:00:00 Europe/Berlin [Install] WantedBy=multi-user.target
The service unit has a
OnFailure hook which runs a separate systemd service in case the exit code of the service is non-zero.
This idea comes from the Arch Wiki.
The status email service can be configured in a generic way such that it can be re-used in other systemd services as well.
# /etc/systemd/system/status-email-user@.service [Unit] Description=Status Email for %i to user [Service] Type=oneshot ExecStart=/usr/local/bin/systemd-email firstname.lastname@example.org %i User=nobody Group=systemd-journal
ERRMAIL To: $1 From: Monitor (systemd) <email@example.com> Subject: $2 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 $(systemctl status --full "$2") ERRMAIL/usr/bin/mail -Ssendwait -t <<
Finally the timer needs to be started/enabled as usual:
systemctl start backup.timer systemctl enable backup.timer
# Show logs
Logs can be read with
journalctl -b -u backup.service