Cron Jobs in time

Für zeitgesteuerte Aufgaben ist der Cron Daemon auf dem Raspberry Pi immer eine gute Wahl. So möchte ich, das meine Raspberry Pis regelmässig einen Health Report an einen zentralen Server melden. Damit erhalte ich an einer Stelle die Einsicht, wie es meinen Geräten eigentlich so geht. Für diesen Bericht schreibe ich ein Python Script, das den Zustand von Speicher und Disk Space ausliest und diese Daten per HTTP POST Request alle 10 Minuten versendet. Damit diese Aufgabe pünktlich erledigt wird, verwende ich den Cron Daemon (crond).


Variante #1: Cron Jobs im Container

Eine Möglich besteht darin, den Cron-Job im Container einzutragen. Der Cron Daemon im Container ist dann zuständig, die Einträge in der cron Tabelle (crontab) zu verarbeiten.

Wir erzeugen in unserem Projekt die crontab Datei:

0,10,20,30,40,50 * * * * python /device-reporter/main.py
# crontab requires an empty line at the end of the file

Dockerfile:

FROM arm32v7/python:3.7-slim-buster

# Update sytem, install requisites, Python 
# and create & activate virtual environment for my project
RUN apt-get update && apt-get install build-essential -y && python3 -m venv /device-reporter/venv && chmod +x /device-reporter/venv/bin/activate && /device-reporter/venv/bin/activate 

# Install project dependencies 
COPY requirements.txt /device-reporter/
WORKDIR /device-reporter/ 
RUN pip install -r requirements.txt 

# Copy my Python source to the target directory
COPY ./ /device-reporter/
COPY ./devicereporter /device-reporter/devicereporter

# Copy the crontab with my cron job definition
COPY ./crontab /etc/cron/crontab

# Initialize the cron table on my Pi
RUN crontab /etc/cron/crontab

# Now run the cron daemon (in the foreground -> "-f")
CMD ["crond", "-f"]

Jetzt können wir den Container bauen und ausführen:

docker image build -t cron-device-reporter:latest
docker container run -d --rm cron-device-reporter:latest

Und nach einer Weil kann ich auf meinen zentralen Server prüfen, ob die Post Requests mit den entsprechenden Daten eintreffen.


Variante #2: Cron Jobs auf dem Host

Ein anderer Weg für die pünktliche Ausführung von Cron-Jobs, ist der Crond Daemon des Hosts (d.h. des Raspberry Pis) zu verwenden. Hierfür fügen wir den Eintrag zur Cron-Tabelle des Betriebssystems hinzu, um den Container mit dem Python Script auszuführen.

Wir passen das Dockerfile so an, das es das Python Script direkt ausgeführt wird. Das Skript beendet sich von selbst, und damit endet anschließend der Container.

Dockerfile:

FROM arm32v7/python:3.7-slim-buster

# Update sytem, install requisites, Python 
# and create & activate virtual environment for my project
RUN apt-get update && apt-get install build-essential -y && python3 -m venv /device-reporter/venv && chmod +x /device-reporter/venv/bin/activate && /device-reporter/venv/bin/activate 

# Install project dependencies 
COPY requirements.txt /device-reporter/
WORKDIR /device-reporter/ 
RUN pip install -r requirements.txt 

# Copy my Python source to the target directory
COPY ./ /device-reporter/
COPY ./devicereporter /device-reporter/devicereporter

ENTRYPOINT python /device-reporter/main.py 

Danach wieder den Container bauen:

docker build -t cron-device-reporter:latest

Und auf den Raspberry Pi verschieben (per Copy oder per Hub).

Danach starten wir den crontab Editor des Systems:

pi@raspberrypi:~ $ crontab -e

Und fügen folgende Zeile hinzu:

0,10,20,30,40,50 * * * * docker run -rm cron-device-reporter:latest

Bitte daran denken, das bereits ausgeführte Container wieder entfernt werden, sonst platzt die Festplatte/Disk des Raspberry Pi bald aus allen Nähten! Dafür verwenden wir die Option --rm (remove) damit der ausgeführte Container automatisch entfernt wird.

Beispiel der crontab:

# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
0,10,20,30,40,50 * * * * docker run -rm cron-device-reporter:latest

Und das war’s – jetzt noch abwarten, ob die HTTP Requests auf dem Server eintreffen…


  1. crontab guru - A quick and simple editor for cron schedule expression by Cronitor.
  2. Dockerfile Reference - Dockerfile Dokumentation mit der Erklärung aller Ausdrücke.