2015-04-01 2 views
9

Ich habe ein Docker-Bild, aus einer Dockerfile, und ich möchte einen Cronjob regelmäßig ausgeführt, wenn ein Container auf dieses Bild basiert ausgeführt wird. Mein Dockerfile ist dies (die relevanten Teile):Innerhalb Docker Container, Cronjobs werden nicht ausgeführt

FROM l3iggs/archlinux:latest 

COPY source /srv/visitor 

WORKDIR /srv/visitor 

RUN pacman -Syyu --needed --noconfirm \ 
     && pacman -S --needed --noconfirm make gcc cronie python2 nodejs phantomjs \ 
     && printf "*/2 * * * *  node /srv/visitor/visitor.js \n" >> cronJobs \ 
     && crontab cronJobs \ 
     && rm cronJobs \ 
     && npm install -g node-gyp \ 
     && PYTHON=/usr/sbin/python2 && export PYTHON \ 
     && npm install 

EXPOSE 80 

CMD ["/bin/sh", "-c"] 

Nach der Erstellung des Bildes I einen Behälter laufen und stellen Sie sicher, dass in der Tat die cronjob wurde hinzugefügt:

crontab -l 

*/2 * * * *  node /srv/visitor/visitor.js 

Nun, das Problem ist, dass die Cronjob wird nie ausgeführt. Ich habe natürlich getestet, dass "node /srv/visitor/visitor.js" korrekt ausgeführt wird, wenn es manuell von der Konsole aus ausgeführt wird.

Irgendwelche Ideen?

+3

cron benötigt einen Daemon. Die Hälfte des Prozesses erstellt den Job, der sich im Dateispeicher des Cron befindet. Die andere Hälfte von Cron führt Jobs aus. Sie könnten sich anschauen: http://stackoverflow.com/questions/20545554/how-do-i-start-cron-on-docker-ubuntu-base. Wenn Sie möchten, dass der Cron-Daemon des Hosts Ihre Cron-Arbeit erledigt, müssten Sie wahrscheinlich das Cron-Verzeichnis des Hosts mounten, wenn Sie den Container starten. Das klingt aber nicht gut! – Greg

+0

Greg, warum fügst du das nicht als Antwort hinzu? Ich wollte das selbe sagen. Beachten Sie auch, dass das Phusion-Image mit cron running geliefert wird. –

+0

@Greg Ich kann jetzt verstehen, was Sie sagen. Die Sache ist, ich möchte entweder das Cron-Verzeichnis des Hosts nicht mounten oder systemd im Container ausführen (wie bei einigen anderen Vorschlägen). Ich denke, beide Methoden würden ein ansonsten sauberes System unnötigerweise "verschmutzen". Was sind meine Alternativen? Kann ich cronie ohne systemd ausführen? Oder gibt es eine Alternative? – dsljanus

Antwort

6

Es ist ein wenig heikel diese endgültig zu beantworten, da ich zu testen, keine Zeit haben, aber Sie haben verschiedene Möglichkeiten offen:

  • Sie die Phusion Grundbild verwenden könnte, die mit kommt ein init-System und Cron installiert. Es basiert auf Ubuntu und ist vergleichsweise Schwergewicht (zumindest im Vergleich zu archlinux) https://registry.hub.docker.com/u/phusion/baseimage/

  • Wenn Sie glücklich sind alles von Cron-Jobs zu starten, könnten Sie einfach cron von Ihrem CMD starten und im Vordergrund halten (cron -f).

  • können Sie leichte Prozess-Manager verwenden cron zu starten und was auch immer andere Prozesse, die Sie benötigen (Phusion Verwendung runit scheinen Docker supervisor zu empfehlen).

  • Sie könnten Ihre eigenen CMD oder ENTRYPOINT Skript schreiben, das cron und Ihren Prozess beginnt. Das einzige Problem mit diesem ist, dass Sie vorsichtig sein müssen, um Signale richtig zu behandeln, oder Sie können mit Zombie-Prozessen enden.

In Ihrem Fall, wenn Ihr um nur zu spielen, würde ich mit der letzten Option gehen, wenn es etwas ernster ist, würde ich mit einem Prozess-Manager gehen.

+0

Erste Dinge zuerst, danke für Ihre gründliche Antwort. Ich bin geneigt, mit der zweiten Option zu gehen, cron mit dem Befehl CMD auszuführen, da ich nur einen einzigen Befehl alle 2 Minuten ad infinitum ausführen möchte. Die Sache ist, Arch hat kein "cron", da cronie ein Aftermarket-Paket ist. Wenn dies auch möglich ist, kann ich Cron im Hintergrund ausführen? So kann ich den Container anhängen, sollte ich es jemals wollen. – dsljanus

+0

Ich weiß nichts über Cronie, aber ich denke, es wird genauso funktionieren. Sie können immer noch mit 'docker exec -it CONTAINER/bin/bash' in den Container gelangen, das ist also kein Problem. –

+0

Innerhalb des laufenden Containers wird crond ausgeführt und von "ps -aux | grep cron" überprüft. Natürlich wurde es manuell angegeben. Tatsache ist, dass immer noch keine Cronjobs ausgeführt werden. – dsljanus

7

Eine Option ist die Host-crontab auf folgende Weise zu verwenden:

0 5 * * * docker exec mysql mysqldump --databases myDatabase -u myUsername -pmyPassword > /backups/myDatabase.sql 

oben Das wird eine tägliche Sicherung einer MySQL-Datenbank in regelmäßigen Abständen zu nehmen.

Wenn Sie Kette komplizierte Befehle benötigen, können Sie auch dieses Format verwenden:

0 5 * * * docker exec mysql sh -c 'mkdir -p /backups/`date +\%d` && for DB in myDB1 myDB2 myDB3; do mysqldump --databases $DB -u myUser -pmyPassword > /backups/`date +\%d`/$DB.sql; done' 

Die oben dauert 30 Tage Roll Sicherung mehrerer Datenbanken und macht einen bash for-Schleife in einer einzigen Zeile, anstatt zu schreiben und Ein Shell-Skript aufrufen, um dasselbe zu tun. Es ist also ziemlich flexibel.

Oder Sie könnten auch komplizierte Skripte innerhalb des Docker Behälter gegeben und sie wie so laufen:

0 5 * * * docker exec mysql /dailyCron.sh 
+0

Dieser Ansatz kann Ihnen nicht helfen, die auf der Anwendungsseite konfigurierte Aufgabe beizubehalten. – BigDong

3

Wenn Sie Ihren Docker Container laufen mit --net = Host finden Sie in diesem Thread: https://github.com/docker/docker/issues/5899

Ich hatte das gleiche Problem, und meine Cron-Aufgaben gestartet, wenn ich --pid = Host in den Docker Run-Befehlszeilenargumente enthalten.