2015-04-01 24 views
9

Ho creato un'immagine Docker, da un Dockerfile, e voglio un cronjob eseguito periodicamente quando un contenitore basato su questa immagine è in esecuzione. Il mio Dockerfile è questo (le parti rilevanti):All'interno del contenitore Docker, i cronjob non vengono eseguiti

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"] 

Dopo la creazione dell'immagine ho eseguito un contenitore e verificare che effettivamente il cronjob è stato aggiunto:

crontab -l 

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

Ora, il problema è che il cronjob non viene mai eseguito. Ho, ovviamente, verificato che "node /srv/visitor/visitor.js" sia eseguito correttamente quando viene eseguito manualmente dalla console.

Qualche idea?

+3

cron richiede un daemon. metà del processo sta creando il lavoro, che risiede nell'archiviazione dei file di cron. L'altra metà di cron sta eseguendo lavori. potresti dare un'occhiata a: http://stackoverflow.com/questions/20545554/how-do-i-start-cron-on-docker-ubuntu-base. Se vuoi che il demone cron dell'host esegua il tuo cronwork, probabilmente dovresti montare la directory del cron degli host quando avvii il contenitore? Ciò non suona bene però! – Greg

+0

Greg, perché non lo aggiungi come risposta? Stavo per dire lo stesso. Inoltre, l'immagine di Phusion viene fornita con cron in esecuzione. –

+0

@Greg Ora posso capire cosa stai dicendo. Il fatto è che non voglio né montare la directory del cron dell'host, né eseguire systemd all'interno del contenitore (come da altri suggerimenti). Mi sento come se entrambi questi metodi "inquinassero" inutilmente un sistema altrimenti pulito. Quali sono le mie alternative? Posso eseguire cronie senza systemd? O c'è un'alternativa? – dsljanus

risposta

6

E 'un po' difficile rispondere a questa definitiva, come io non ho tempo per testare, ma avete diverse opzioni aperte a voi:

  • è possibile utilizzare l'immagine di base Phusion, che viene fornito con un sistema init e cron installati. Si basa su Ubuntu e è relativamente pesante (almeno rispetto a Archlinux) https://registry.hub.docker.com/u/phusion/baseimage/

  • Se sei felice di avere tutto partito da cron jobs, si può solo iniziare cron dal CMD e tenerlo in primo piano (cron -f).

  • È possibile utilizzare il gestore processi leggero per avviare cron e qualsiasi altro processo necessario (Phusion usa runit, Docker sembra raccomandare supervisor).

  • È possibile scrivere il proprio script CMD o ENTRYPOINT che avvia cron e il processo. L'unico problema con questo è che dovrai fare attenzione a gestire i segnali correttamente o potresti finire con i processi di zombi.

Nel tuo caso, se il vostro solo giocando intorno, mi piacerebbe andare con l'ultima opzione, se si tratta di qualcosa di più serio, mi piacerebbe andare con un gestore di processo.

+0

Per prima cosa, grazie per la tua risposta completa. Sono incline ad andare con la seconda opzione, eseguendo cron con il comando CMD, poiché tutto ciò che voglio fare è eseguire un singolo comando ogni 2 minuti all'infinito. Il fatto è che Arch non ha "cron" dato che cronie è un pacchetto aftermarket. Inoltre, se questo è ovunque, posso eseguire cron in background? Quindi posso allegare al contenitore se mai lo voglio. – dsljanus

+0

Non so nulla di cronie, ma mi aspetto che funzioni ugualmente. Puoi ancora entrare nel container con 'docker exec -it CONTAINER/bin/bash', quindi non è un problema. –

+0

All'interno del contenitore in esecuzione, crond è in esecuzione e verificato da "ps -aux | grep cron". Ovviamente è stato dichiarato manualmente. Il fatto è che ancora nessun cronjob viene eseguito. – dsljanus

7

Una possibilità è quella di utilizzare crontab del padrone di casa nel modo seguente:

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

È possibile che periodicamente fare un backup giornaliero di un database MySQL.

Se avete bisogno di comandi a catena complicato è anche possibile utilizzare questo formato:

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' 

È possibile che questo prende un rotolamento di backup 30 giorni di più database e fa un bash ciclo for in una singola linea piuttosto che scrivere e chiamare uno script di shell per fare lo stesso. Quindi è piuttosto flessibile.

Oppure si potrebbe anche mettere script complessi all'interno del contenitore finestra mobile ed eseguirli in questo modo:

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

Questo approccio non può aiutarti a mantenere l'applicazione configurata sul lato dell'applicazione. – BigDong

3

Se si sta eseguendo il vostro contenitore Docker con --net = host, vedi questa discussione: https://github.com/docker/docker/issues/5899

Ho avuto lo stesso problema e le mie attività cron sono state avviate quando ho incluso --pid = host nella finestra mobile esegue gli argomenti della riga di comando.

Problemi correlati