Vous pouvez copier votre crontab dans une image, afin que le conteneur lancé à partir de cette image exécute le travail.
Voir " Exécuter un travail cron avec Docker " de Julien Boulay dans son Ekito/docker-cron
:
Créons un nouveau fichier appelé " hello-cron
" pour décrire notre travail.
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1
# An empty line is required at the end of this file for a valid cron file.
Le Dockerfile suivant décrit toutes les étapes pour construire votre image
FROM ubuntu:latest
MAINTAINER docker@ekito.fr
RUN apt-get update && apt-get -y install cron
# Copy hello-cron file to the cron.d directory
COPY hello-cron /etc/cron.d/hello-cron
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/hello-cron
# Apply cron job
RUN crontab /etc/cron.d/hello-cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Run the command on container startup
CMD cron && tail -f /var/log/cron.log
(voir Gaafar de » commentaire et Comment puis-je faire apt-get
installer moins bruyants? :
apt-get -y install -qq --force-yes cron
peut fonctionner aussi)
Comme l'a noté Nathan Lloyd dans les commentaires :
Note rapide sur un problème:
si vous ajoutez un fichier de script et dites à cron de l'exécuter, n'oubliez pas que Cron échoue silencieusement si vous oubliez .
RUN chmod 0744 /the_script
OU, assurez-vous que votre travail lui-même redirige directement vers stdout / stderr au lieu d'un fichier journal, comme décrit dans la réponse de hugoShaka :
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
Remplacez la dernière ligne Dockerfile par
CMD ["cron", "-f"]
Voir aussi (à propos cron -f
, c'est-à-dire cron "premier plan") " docker ubuntu cron -f
ne fonctionne pas "
Construisez-le et exécutez-le:
sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example
Soyez patient, attendez 2 minutes et votre ligne de commande devrait afficher:
Hello world
Hello world
Eric ajoute dans les commentaires :
Notez que tail
le fichier correct peut ne pas s'afficher s'il est créé lors de la création de l'image.
Si tel est le cas, vous devez créer ou toucher le fichier pendant l'exécution du conteneur afin que tail récupère le fichier correct.
Voir " Sortie de tail -f
à la fin d'un docker CMD
ne s'affiche pas ".
RUN apt-get update && apt-get install cron
-y
à l'installation de cron pour éviter la fin de la construction du dockercrontab -l
, je ne reçois pas de crontab installé pour root , mon écran reste vide. Cependant, lorsque je vérifie '/etc/cron.d/', je vois que le champ crontab est là (et encore plus surprenant), quand je vérifie/var/log/cron.log
, je vois que le script est en cours d'exécution (le contenu du fichier est ajouté avecHello World
). Je tire cette image dans mon Dockerfile:FROM phusion/baseimage:0.10.0
. Des idées sur la différence de comportement?La solution adoptée peut être dangereuse dans un environnement de production .
Lorsque vous utilisez
CMD cron && tail -f /var/log/cron.log
essentiellement le processus cron fork pour exécutercron
en arrière-plan, le processus principal se termine et vous permet d'exécutertailf
en premier plan. Le processus cron en arrière-plan peut s'arrêter ou échouer, vous ne le remarquerez pas, votre conteneur fonctionnera toujours en mode silencieux et votre outil d'orchestration ne le redémarrera pas.En utilisant les redirections de base du shell, vous voudrez peut-être faire quelque chose comme ceci:
Et votre CMD sera:
CMD ["cron", "-f"]
la source
cron -f
c'est pour "cron premier plan". J'ai inclus votre réponse dans la mienne ci-dessus, pour plus de visibilité. +1Pour ceux qui souhaitent utiliser une image simple et légère:
Où cronjobs est le fichier qui contient vos cronjobs, sous cette forme:
la source
> /proc/1/fd/1 2> /proc/1/fd/2
redirection pour accéder aux sorties cronjobs directement à partir des journaux de docker.-d 8
paramètre n'est pas le cron standard, c'est la commande crond de busybox. Par exemple depuis ubuntu, vous pouvez l'exécuter en tant quebusybox crond -f -d 8
. Pour les anciennes versions, vous devez utiliser-L /dev/stdout/
.docker run -v ${PWD}/cronjobs:/etc/crontabs/root alpine:3.6 crond -f -d 8
. @Groostav, vous pouvez utiliser une chose similaire dans Docker Compose.CMD ["crond"
ouCMD ["cron"
?Ce que @VonC a suggéré est bien, mais je préfère faire toute la configuration des tâches cron sur une seule ligne. Cela éviterait les problèmes multiplates-formes comme l'emplacement des tâches cron et vous n'avez pas besoin d'un fichier cron distinct.
Après avoir exécuté votre conteneur Docker, vous pouvez vous assurer que le service cron fonctionne en:
Si vous préférez avoir ENTRYPOINT au lieu de CMD, vous pouvez remplacer le CMD ci-dessus par
la source
RUN apt-get update && apt-get -y install cron
sinon il ne pourra pas trouver le paquetcron
RUN cat $APP_HOME/crons/* | crontab
Like a charm :)cron
à un script de point d'entrée semble être la meilleure option: ENTRYPOINT ["entrypoint.sh"]Il y a une autre façon de le faire, c'est d'utiliser Tasker , un tâches qui prend en charge cron (un planificateur).
Pourquoi ? Parfois, pour exécuter un travail cron, vous devez mélanger votre image de base (python, java, nodejs, ruby) avec le crond. Cela signifie une autre image à maintenir. Tasker éviter cela en découplant le crond et votre conteneur. Vous pouvez simplement vous concentrer sur l'image sur laquelle vous souhaitez exécuter vos commandes et configurer Tasker pour l'utiliser.
Voici un
docker-compose.yml
fichier, qui va exécuter quelques tâches pour vousIl y a 3 tâches là-bas, toutes s'exécuteront toutes les minutes (
every: minute
), et chacune exécutera lescript
code, à l'intérieur de l'image définie dansimage
section.Il suffit de courir
docker-compose up
et de le voir fonctionner. Voici le dépôt Tasker avec la documentation complète:http://github.com/opsxcq/tasker
la source
docker exec
sur des conteneurs spécifiés.La réponse de VonC est assez complète. De plus, j'aimerais ajouter une chose qui m'a aidé. Si vous voulez simplement exécuter un travail cron sans suivre un fichier, vous seriez tenté de simplement supprimer le
&& tail -f /var/log/cron.log
de la commande cron.Cependant, cela entraînera la fermeture du conteneur Docker peu de temps après l'exécution, car lorsque la commande cron se termine, Docker pense que la dernière commande a été fermée et tue donc le conteneur. Cela peut être évité en exécutant cron au premier plan via
cron -f
.la source
Bien que cela vise à exécuter des travaux à côté d'un processus en cours d'exécution dans un conteneur via Docker
exec
interface , cela peut vous intéresser.J'ai écrit un démon qui observe les conteneurs et planifie les travaux, définis dans leurs métadonnées, sur eux. Exemple:
Une configuration «classique» de type cron est également possible.
Voici les documents , voici le référentiel d'images .
la source
docker exec <container_name> <some_command>
par programme.J'ai créé une image Docker basée sur les autres réponses, qui peut être utilisée comme
docker run -v "/path/to/cron:/etc/cron.d/crontab" gaafar/cron
où
/path/to/cron
: chemin absolu vers le fichier crontab, ou vous pouvez l'utiliser comme base dans un Dockerfile:Pour référence, l'image est ici .
la source
Lorsque vous déployez votre conteneur sur un autre hôte, notez simplement qu'il ne démarrera aucun processus automatiquement. Vous devez vous assurer que le service «cron» fonctionne à l'intérieur de votre conteneur. Dans notre cas, j'utilise Supervisord avec d'autres services pour démarrer le service cron.
la source
Définissez le cronjob dans un conteneur dédié qui exécute la commande via docker exec à votre service.
Il s'agit d'une cohésion plus élevée et le script en cours d'exécution aura accès aux variables d'environnement que vous avez définies pour votre service.
la source
myservice unknown
erreurs.Si vous utilisez Docker pour Windows, n'oubliez pas que vous devez changer votre format de fin de ligne de CRLF à LF (c'est-à-dire de dos à Unix) si vous avez l'intention d'importer votre fichier crontab de Windows vers votre conteneur Ubuntu. Sinon, votre cron-job ne fonctionnera pas. Voici un exemple de travail:
Cela m'a effectivement pris des heures à comprendre, car le débogage des tâches cron dans les conteneurs Docker est une tâche fastidieuse. J'espère que cela aide toute autre personne qui ne peut pas faire fonctionner son code!
la source
À partir des exemples ci-dessus, j'ai créé cette combinaison:
Alpine Image & Edit à l'aide de Crontab dans Nano (je déteste vi)
la source
Configurer un cron en parallèle à un travail ponctuel
Créez un fichier de script, par exemple run.sh, avec le travail qui est censé s'exécuter périodiquement.
Sauvegarder et quitter.
Utilisez Entrypoint au lieu de CMD
Si vous avez plusieurs tâches à lancer pendant la conteneurisation du docker, utilisez le fichier de point d'entrée pour les exécuter toutes.
Le fichier Entrypoint est un fichier de script qui entre en action lorsqu'une commande d'exécution de docker est émise. Ainsi, toutes les étapes que nous voulons exécuter peuvent être placées dans ce fichier de script.
Par exemple, nous avons 2 tâches à exécuter:
Exécuter une fois le travail : echo "Docker container has been started"
Exécuter un travail périodique : run.sh
Créez entrypoint.sh
Comprenons la crontab qui a été configurée dans le fichier
* * * * *
: Horaire Cron; le travail doit s'exécuter toutes les minutes. Vous pouvez mettre à jour le calendrier en fonction de vos besoins./run.sh
: Chemin d'accès au fichier de script à exécuter périodiquement/var/log/cron.log
: Nom de fichier pour enregistrer la sortie du travail cron planifié.2>&1
: Les journaux d'erreurs (le cas échéant) seront également redirigés vers le même fichier de sortie utilisé ci-dessus.Remarque : N'oubliez pas d'ajouter une nouvelle ligne supplémentaire, car cela en fait un cron valide.
Scheduler.txt
: la configuration complète de cron sera redirigée vers un fichier.Utilisation de variables d'environnement spécifiques au système / utilisateur dans cron
Mon travail cron réel attendait la plupart des arguments lorsque les variables d'environnement étaient passées à la commande docker run. Mais, avec bash, je n'ai pu utiliser aucune des variables d'environnement appartenant au système ou au conteneur Docker.
Ensuite, cela est venu comme une solution à ce problème:
Enfin, vous
entrypoint.sh
devriez ressembler àDernier point mais non le moindre: créer un Dockerfile
C'est tout. Créez et exécutez l'image Docker!
la source
Les tâches Cron sont stockées dans / var / spool / cron / crontabs (endroit commun dans toutes les distributions que je connais). BTW, vous pouvez créer un onglet cron dans bash en utilisant quelque chose comme ça:
Cela va créer un fichier temporaire avec la tâche cron, puis le programmer en utilisant crontab. La dernière ligne supprime le fichier temporaire.
la source
cron
démon ne s'exécute normalement pas dans un conteneur.crond
en plus du service que vous exécutez dans le conteneur, normalement avec un gestionnaire de services comme s6. Posez probablement cela comme une question pour obtenir une réponse correcteLors de l'exécution sur certaines images réduites qui limitent l'accès root, j'ai dû ajouter mon utilisateur aux sudoers et exécuter en tant que
sudo cron
Peut-être que cela aide quelqu'un
la source
Donc, mon problème était le même. Le correctif consistait à modifier la section de commande dans le
docker-compose.yml
.De
commande: crontab / etc / crontab && tail -f / etc / crontab
À
commande: crontab / etc / crontab
commande: tail -f / etc / crontab
Le problème était le «&&» entre les commandes. Après avoir supprimé cela, tout allait bien.
la source
Le moyen le plus robuste que j'ai trouvé jusqu'à présent est d'exécuter un conteneur Cron indépendant - installez le client Docker et liez le support de la chaussette Docker pour pouvoir parler au serveur Docker sur l'hôte.
Ensuite, utilisez simplement env vars pour chaque tâche cron et un script de point d'entrée pour générer le fichier / etc / crontab
Voici une image que j'ai créée en utilisant ce principe et en l'utilisant en production depuis 3-4 ans.
https://www.vip-consult.solutions/post/better-docker-cron#content
la source
Essayez d'utiliser un joyau d'horlogerie pour planifier des tâches. Suivez les étapes fournies dans ce lien.
http://fuzzyblog.io/blog/rails/2017/05/11/adding-cron-to-a-dockerized-rails-application-using-clockwork.html
Vous pouvez appeler la tâche de râteau dans le fichier lib / clock.rb comme ci-dessous.
Créez un conteneur séparé dans le fichier docker-compose et exécutez la commande ci-dessous à l'intérieur du conteneur.
la source