Auf die Minute genau: Cronjobs im Docker-Container

Für zeitgesteuerte Aufgaben hilft noch immer das gute alte crond. In diesem Beitrag möchte ich zeigen, wie man auf Basis eines schlanken Alpine Linux wiederkehrende Befehle ausführt.

Ich beginne mit einer schmalen Datei (crontab) in Cron-Syntax. Die Ausgabe wird, wie für einen Docker-Container üblich, nach /dev/stdout geschrieben, damit Docker sie fangen und je nach gewählten Logging Driver (Beitrag dazu) verarbeiten kann. Im Standard lässt sich die Ausgabe einfach mit docker container logs verfolgen. Man beachte die Leerzeile am Ende der Datei (!!!).

* * * * * echo "Hello world" >> /dev/stdout 2>&1
# crontab requires empty line at end of file

Nun brauchen wir einen Bauplan für unser Container-Image in Form des Dockerfiles. Ich gehe davon aus, dass unsere beiden Dateien im gleichen Verzeichnis liegen.

FROM alpine:3.7
LABEL maintainer "Patrick Baber <patrick.baber@ueber.io>"

# Configure cron
COPY crontab /etc/cron/crontab

# Init cron
RUN crontab /etc/cron/crontab

CMD ["crond", "-f"]

Um ein möglichst kleines Image zu erhalten, wähle ich als Base-Image alpine mit dem Tag 3.7, um eine konkrete Version im Sinne der Reproduzierbarkeit zu erhalten. Es wird unsere zuvor erstellte Datei im Image platziert. Der nachfolgende Schritt ist wichtig. Er führt crontab aus und veranlasst somit unsere Datei dorthin zu verschieben, wo sie crond erwartet. Nebenbei werden auch noch die Dateirechte angepasst. Zum Abschluss des Dockerfiles wird der Cron-Daemon im Vordergrund gestartet.

Wir haben nun alle Zutaten parat und beginnen mit dem Bau des Docker Images und starten im Anschluss unser Werk.

# Build
docker image build -t cron-image .

# Run
docker container run -d --rm --name cron-container cron-image

Ob alles funktioniert überprüfen wir in den Logs, die nach einem kurzen In-den-Stuhl-fallen-lassen die erwartete Meldung auch bereits zeigen.

$ docker container logs cron-container
Hello world
Hello world
Hello world

Das Image ist mit seinen knapp 4 MB nun bereit für größere Aufgaben. Es braucht also nicht immer ein „full-blown“ Ubuntu als Basis. Ein Blick in die Kommandozeilenhilfe von crond zeigt weitere interessante Einstellungen, wie das Log-Level.

Gern wird ein Cronjob auch im PHP-Umfeld gebraucht, um asynchrone Aufgabe anzustoßen. Tipp: Unter Umständen braucht es hier nur PHP als CLI und nicht den FPM (FastCGI Process Manager).

Patrick Baber

Als erfahrener Programmierer löst Patrick jeden Gordischen Knoten, findet die geeignete Methode und entwickelt damit flexible Software-Systeme.