Cronjob in einem Docker Container einrichten
Ich habe eine App mit der ich regelmäßig Push Notifications verschicken möchte. Dazu bedarf es eines Cronjobs, der alle zwei Stunden ein PHP Skript anstößt. Das Projekt läuft in einem Docker Container. Daher möchte ich den Cronjob nicht händisch im Container pflegen, sondern automatisch beim Deployment über das Dockerfile
.
Da es sich um ein PHP Skript handelt, macht es Sinn ein entsprechendes Docker image zu wählen. In diesem Fall habe ich mich für das Image php:8.1-rc-apache entschieden, da der Container ja nicht nur den cronjob ausführen soll, sondern auch meine App mittels Apache ausspielt.
Es bedarf lediglich drei Dateien, um den Cronjob in einem Docker Container einzurichten:
my-project
├── mycron # Cronjob, der ausgeführt werden soll
├── Dockerfile
└── docker-compose.yml
docker-compose.yml
übereinstimmt.Der Cronjob
In der „mycron“ gebt ihr die bekannte cronjob Syntax ein. Diese Datei wird später im Dockerfile an die richtige Stelle im Docker Container kopiert. Den Output könnt ihr in eine Log-Datei schreiben. Aber Achtung: Je nach Ausgabe kann die Datei irgendwann zu groß werden.
0 9-23/2 * * * /usr/local/bin/php /var/www/html/api/MyAwesomeScript.php >> /var/log/cron.log 2>&1
Falls du genauso wie ich Probleme hast dir die cronjob Syntax zu merken, kann ich dir die Seite crontab.guru sehr empfehlen. Dort kannst du verschiedene Werte ausprobieren und die Seite übersetzt diese dann in einen leicht verständlichen Satz.
Das Dockerfile
Im Dockerfile installieren wir cron
um überhaupt Cronjobs ausführen zu können. Anschließend kopieren wir die Cron Datei in den Container und stellen sicher, dass sie die richtigen Berechtigungen bekommt. In der letzten Zeile registrieren wir abschließend den Cronjob in der crontab.
FROM php:8.1-rc-apache
# Install vim + cron
RUN apt-get update && apt-get install -y vim cron
# Configure cronjob
RUN touch /var/log/cron.log
COPY mycron /etc/cron.d/mycron
RUN chmod 0644 /etc/cron.d/mycron
RUN crontab /etc/cron.d/mycron
Die docker-compose.yml
Der Inhalt der docker-compose.yml
hängt natürlich stark von deinem Projekt und deinem Setup ab. Daher hier nur die wichtigsten Zeilen, damit das Dockerfile beim Deployment verwendet wird.
services:
app:
container_name: my_container
build:
context: .
dockerfile: Dockerfile
Überprüfe die Installation
Damit ist schon alles erledigt. Starte den Container und überprüfe, ob cron installiert und die cron Datei erstellt wurde. Wenn die Ausgabe stimmt, hast du erfolgreich deinen Cronjob in einem Docker Container eingerichtet.
$ docker compose build && docker compose up -d
# In den Docker einloggen
$ docker exect -it "my_container" bash
# Sollte "/usr/sbin/cron" zurückgeben
$ which cron
# Sollte "/etc/cron.d/mycron" zurückgeben
$ ls /etc/cron.d/mycron