Comment exécuter un travail cron dans un conteneur Docker?

275

J'essaie d'exécuter un cronjob dans un conteneur docker qui invoque un script shell.

Hier, j'ai cherché partout sur le Web et les débordements de pile, mais je n'ai pas vraiment trouvé de solution qui fonctionne.
Comment puis-je faire ceci?

ÉDITER:

J'ai créé un référentiel github (commenté) avec un conteneur cron docker qui appelle un script shell à un intervalle donné.

C Heyer
la source

Réponses:

365

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-getinstaller moins bruyants? :
apt-get -y install -qq --force-yes cronpeut 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 -fne 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 taille 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 CMDne s'affiche pas ".

VonC
la source
1
J'ai d'abord dû installer cron, car il n'est pas inclus. Mais en l'ajoutant au Dockerfile, cela fonctionne. Merci! RUN apt-get update && apt-get install cron
C Heyer
2
vous devriez probablement ajouter -yà l'installation de cron pour éviter la fin de la construction du docker
gafi
1
@Gaafar Droite! J'ai inclus votre commentaire dans la réponse pour plus de visibilité et ajouté une autre option.
VonC
6
Cette solution fonctionne-t-elle toujours? Lorsque je suis les instructions données, lorsque je me connecte au conteneur en tant que root et type crontab -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é avec Hello World). Je tire cette image dans mon Dockerfile: FROM phusion/baseimage:0.10.0. Des idées sur la différence de comportement?
Homunculus Reticulli
11
Depuis 2018, cette approche ne fonctionne plus; Quelqu'un a-t-il pu faire fonctionner son cronjob avec Ubuntu comme image de base? Je ne suis pas intéressé par l'image alpine qui vient avec le cron qui sort de la boîte
pélican
148

La solution adoptée peut être dangereuse dans un environnement de production .

Dans Docker, vous ne devez exécuter qu'un seul processus par conteneur, car si vous ne le faites pas, le processus qui a bifurqué et est passé en arrière-plan n'est pas surveillé et peut s'arrêter à votre insu.

Lorsque vous utilisez CMD cron && tail -f /var/log/cron.logessentiellement le processus cron fork pour exécuter cronen arrière-plan, le processus principal se termine et vous permet d'exécuter tailfen 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.

Vous pouvez éviter une telle chose en redirigeant directement la sortie des commandes du cron dans votre docker stdoutet stderrqui se trouvent respectivement dans /proc/1/fd/1et /proc/1/fd/2.

En utilisant les redirections de base du shell, vous voudrez peut-être faire quelque chose comme ceci:

* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2

Et votre CMD sera: CMD ["cron", "-f"]

hugoShaka
la source
14
Nice: cron -fc'est pour "cron premier plan". J'ai inclus votre réponse dans la mienne ci-dessus, pour plus de visibilité. +1
VonC
Disons que mon programme ne produit rien. Puis-je toujours utiliser cette méthode et être sûr que mon processus ne s'arrêtera pas en arrière-plan?
Arcsector
1
@Arcsector cette méthode évite de mettre un processus en arrière-plan, c'est pourquoi il n'échoue pas en silence. Avoir un processus d'arrière-plan dans un conteneur Docker n'est pas simple. Si vous souhaitez avoir un processus d'arrière-plan en cours d'exécution, vous pouvez utiliser un processus d'initialisation pour surveiller les multiples processus que vous exécutez dans le conteneur. Une autre façon consiste à démarrer le processus dans un autre conteneur à côté du conteneur principal appelé «sidecar». Le meilleur moyen est souvent d'éviter plusieurs processus dans le conteneur.
hugoShaka
Agréable et propre ! J'adore :)
AmaelH
1
Ceci est une bonne solution et fonctionne bien pour nous à part un problème. Lorsque le conteneur reçoit un signal SIGTERM, il ne semble pas attendre la fin du processus planifié et son arrêt normal, mais il tue le processus, ce qui peut provoquer des problèmes.
James Hulse
107

Pour ceux qui souhaitent utiliser une image simple et légère:

FROM alpine:3.6

# copy crontabs for root user
COPY config/cronjobs /etc/crontabs/root

# start crond with log level 8 in foreground, output to stderr
CMD ["crond", "-f", "-d", "8"]

cronjobs est le fichier qui contient vos cronjobs, sous cette forme:

* * * * * echo "hello stackoverflow" >> /test_file 2>&1
# remember to end this file with an empty new line
Oscar Fanelli
la source
10
Basé sur une image simple, légère et standard. Ce devrait être la réponse acceptée. Utilisez également la > /proc/1/fd/1 2> /proc/1/fd/2redirection pour accéder aux sorties cronjobs directement à partir des journaux de docker.
HenriTel
2
Pour les personnes n'utilisant pas alpine: le crond supportant le -d 8paramè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 que busybox crond -f -d 8. Pour les anciennes versions, vous devez utiliser -L /dev/stdout/.
Trendfischer
2
Je donnerais ce +100 si je le pouvais. C'est de loin le meilleur moyen d'exécuter des tâches cron dans un environnement Docker.
Jitsusama
1
Si vous ne souhaitez pas créer une nouvelle image à chaque fois que vous modifiez le travail cron (ou si vous en avez besoin de plusieurs), vous pouvez simplement exécuter Alpine et utiliser un volume pour définir le cron. Je l' ai testé en utilisant ce qui suit: 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.
duality_
1
CMD ["crond"ou CMD ["cron"?
codesmith
38

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.

FROM ubuntu:latest

# Install cron
RUN apt-get -y install cron

# Create the log file to be able to run tail
RUN touch /var/log/cron.log

# Setup cron job
RUN (crontab -l ; echo "* * * * * echo "Hello world" >> /var/log/cron.log") | crontab

# Run the command on container startup
CMD cron && tail -f /var/log/cron.log

Après avoir exécuté votre conteneur Docker, vous pouvez vous assurer que le service cron fonctionne en:

# To check if the job is scheduled
docker exec -ti <your-container-id> bash -c "crontab -l"
# To check if the cron service is running
docker exec -ti <your-container-id> bash -c "pgrep cron"

Si vous préférez avoir ENTRYPOINT au lieu de CMD, vous pouvez remplacer le CMD ci-dessus par

ENTRYPOINT cron start && tail -f /var/log/cron.log
Youness
la source
1
Alternative intéressante. +1
VonC
2
RUN apt-get update && apt-get -y install cronsinon il ne pourra pas trouver le paquetcron
alphabetasoup
2
Merci Youness, vous m'avez donné l'idée de faire ce qui suit, ce qui a fonctionné dans mon cas où chaque cron est spécifié dans un fichier différent: RUN cat $APP_HOME/crons/* | crontab Like a charm :)
marcostvz
l'ajout cronà un script de point d'entrée semble être la meilleure option: ENTRYPOINT ["entrypoint.sh"]
bozdoz
20

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.ymlfichier, qui va exécuter quelques tâches pour vous

version: "2"

services:
    tasker:
        image: strm/tasker
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
        environment:
            configuration: |
                logging:
                    level:
                        ROOT: WARN
                        org.springframework.web: WARN
                        sh.strm: DEBUG
                schedule:
                    - every: minute
                      task: hello
                    - every: minute
                      task: helloFromPython
                    - every: minute
                      task: helloFromNode
                tasks:
                    docker:
                        - name: hello
                          image: debian:jessie
                          script:
                              - echo Hello world from Tasker
                        - name: helloFromPython
                          image: python:3-slim
                          script:
                              - python -c 'print("Hello world from python")'
                        - name: helloFromNode
                          image: node:8
                          script:
                              - node -e 'console.log("Hello from node")'

Il y a 3 tâches là-bas, toutes s'exécuteront toutes les minutes ( every: minute), et chacune exécutera le scriptcode, à l'intérieur de l'image définie dansimage section.

Il suffit de courir docker-compose upet de le voir fonctionner. Voici le dépôt Tasker avec la documentation complète:

http://github.com/opsxcq/tasker

OPSXCQ
la source
Dockerception (exécuter des conteneurs Docker à partir d'un autre conteneur) est une mauvaise pratique et devrait se limiter à une intégration continue. Une solution de contournement serait d'utiliser docker execsur des conteneurs spécifiés.
HenriTel
1
Tasker n'utilise pas docker dans docker (Dind / Dockerception), notez que le socket docker est passé en tant que mappage, tous les conteneurs générés sont générés dans le démon que le gestionnaire exécute. Et si vous ne voulez pas exécuter Tasker dans Docker, vous pouvez simplement le déployer comme n'importe quelle autre application.
OPSXCQ
1
Je n'ai pas les avantages d'utiliser Tasker. Cela me semble vraiment exagéré d'utiliser java et sh *** juste pour exécuter un travail cron.
Karl Adler
Le mélange de cron et de l'image de base dont vous avez besoin (python / nœud par exemple) crée une dépendance supplémentaire qui doit être maintenue et déployée, dans ce scénario, tous les travaux partagent le même conteneur, cela signifie que vous devez vous soucier de tout nettoyer après chaque travail s'exécute. Les travaux exécutés sur tasker sont idempotents, vous avez donc moins de choses à vous soucier.
OPSXCQ
13

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.logde 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.

vanugrah
la source
9

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:

version: '2'

services:
  wordpress:
    image: wordpress
  mysql:
    image: mariadb
    volumes:
      - ./database_dumps:/dumps
    labels:
      deck-chores.dump.command: sh -c "mysqldump --all-databases > /dumps/dump-$$(date -Idate)"
      deck-chores.dump.interval: daily

Une configuration «classique» de type cron est également possible.

Voici les documents , voici le référentiel d'images .

funky-future
la source
Je vous remercie. Cette réponse convient parfaitement à l'environnement des conteneurs Docker. Aucune modification dans les images Docker, ajoutant uniquement un conteneur spécial pour l'exécution des tâches, cela fonctionne comme une commande docker exec <container_name> <some_command>par programme.
PRIHLOP
C'est la réponse la plus simple et la plus simple «faire le travail».
Ibrahim Awad
9

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

/path/to/cron: chemin absolu vers le fichier crontab, ou vous pouvez l'utiliser comme base dans un Dockerfile:

FROM gaafar/cron

# COPY crontab file in the cron directory
COPY crontab /etc/cron.d/crontab

# Add your commands here

Pour référence, l'image est ici .

gafi
la source
Image intéressante. +1
VonC
5

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.

[program:misc]
command=/etc/init.d/cron restart
user=root
autostart=true
autorestart=true
stderr_logfile=/var/log/misc-cron.err.log
stdout_logfile=/var/log/misc-cron.out.log
priority=998
Sagar Ghuge
la source
Je reçois une erreur dans supervisor.log indiquant que le service cron s'est arrêté plusieurs fois et est entré dans un état FATAL. Cependant, cron semble fonctionner en haut et exécuter les cronjobs normalement. Merci pour cela!
lephleg le
Oui, la même chose m'est également arrivée, mais cela fonctionne comme d'habitude, alors ne vous inquiétez pas.
Sagar Ghuge
5

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.

#docker-compose.yml
version: "3.3"
services:
    myservice:
      environment:
        MSG: i'm being cronjobbed, every minute!
      image: alpine
      container_name: myservice
      command: tail -f /dev/null

    cronjobber:
     image: docker:edge
     volumes:
      - /var/run/docker.sock:/var/run/docker.sock
     container_name: cronjobber
     command: >
          sh -c "
          echo '* * * * * docker exec myservice printenv | grep MSG' > /etc/crontabs/root
          && crond -f"
Jakob Eriksson
la source
Je n'ai pas réussi à faire fonctionner cela à l'aide de l'essaim de docker. Obtenir des myservice unknownerreurs.
Mark Grimes
Il devrait y avoir un avertissement concernant l'impact de haute sécurité du montage d'une prise Docker sur
casual
4

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:

FROM ubuntu:latest

RUN apt-get update && apt-get -y install cron
RUN apt-get update && apt-get install -y dos2unix

# Add crontab file (from your windows host) to the cron directory
ADD cron/hello-cron /etc/cron.d/hello-cron

# Change line ending format to LF
RUN dos2unix /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/hello-cron.log

# Run the command on container startup
CMD cron && tail -f /var/log/hello-cron.log

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!

Andreas Forslöw
la source
3

À partir des exemples ci-dessus, j'ai créé cette combinaison:

Alpine Image & Edit à l'aide de Crontab dans Nano (je déteste vi)

FROM alpine

RUN apk update
RUN apk add curl nano

ENV EDITOR=/usr/bin/nano 

# start crond with log level 8 in foreground, output to stderr
CMD ["crond", "-f", "-d", "8"]

# Shell Access
# docker exec -it <CONTAINERID> /bin/sh

# Example Cron Entry
# crontab -e
# * * * * * echo hello > /proc/1/fd/1 2>/proc/1/fd/2
# DATE/TIME WILL BE IN UTC
Dan Watts
la source
2

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.

#!/bin/bash
timestamp=`date +%Y/%m/%d-%H:%M:%S`
echo "System path is $PATH at $timestamp"

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

#!/bin/bash

# Start the run once job.
echo "Docker container has been started"

# Setup a cron schedule
echo "* * * * * /run.sh >> /var/log/cron.log 2>&1
# This extra line makes it a valid cron" > scheduler.txt

crontab scheduler.txt
cron -f

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:

  1. Ajoutez la ligne suivante dans le point d'entrée.sh
declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env
  1. Mettez à jour la configuration cron et spécifiez-
SHELL=/bin/bash
BASH_ENV=/container.env

Enfin, vous entrypoint.shdevriez ressembler à

#!/bin/bash

# Start the run once job.
echo "Docker container has been started"

declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env

# Setup a cron schedule
echo "SHELL=/bin/bash
BASH_ENV=/container.env
* * * * * /run.sh >> /var/log/cron.log 2>&1
# This extra line makes it a valid cron" > scheduler.txt

crontab scheduler.txt
cron -f

Dernier point mais non le moindre: créer un Dockerfile

FROM ubuntu:16.04
MAINTAINER Himanshu Gupta

# Install cron
RUN apt-get update && apt-get install -y cron

# Add files
ADD run.sh /run.sh
ADD entrypoint.sh /entrypoint.sh

RUN chmod +x /run.sh /entrypoint.sh

ENTRYPOINT /entrypoint.sh

C'est tout. Créez et exécutez l'image Docker!

himanshuIIITian
la source
1
@himanshuIIITian J'ai essayé cela, le problème est que le script du "travail à exécuter une fois" ne revient jamais et que le maïs -f ne revient pas donc ... cela ne fonctionne pas pour moi, des idées? merci
Doron Levi
@DoronLevi - pouvez-vous s'il vous plaît partager quelques journaux pour examiner le problème? Ou vous pouvez vérifier tout le code d'ici - github.com/nehabhardwaj01/docker-cron
himanshuIIITian
Merci pour les commentaires. Je suis content que la réponse ait été utile.
himanshuIIITian
1

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:

crontab -l > cronexample
echo "00 09 * * 1-5 echo hello" >> cronexample
crontab cronexample
rm cronexample

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.

Jesus Segnini
la source
Le crondémon ne s'exécute normalement pas dans un conteneur.
Matt
@BhargavNanekalva, il doit être spécifiquement configuré dans un conteneur auquel cette réponse ne répond pas.
Matt
@Matt, pourriez-vous s'il vous plaît indiquer comment il doit être spécifié exactement dans le conteneur? . Je fais crontab -l et la commande est affichée - kagda.ru/i/6d014816d43_29-06-2017-11:38:59_6d01.png mais n'est toujours pas exécuté
Tebe
@ Копать_Шо_я_нашел Vous devez exécuter cronden 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 correcte
Matt
1

Lors 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

FROM node:8.6.0
RUN apt-get update && apt-get install -y cron sudo

COPY crontab /etc/cron.d/my-cron
RUN chmod 0644 /etc/cron.d/my-cron
RUN touch /var/log/cron.log

# Allow node user to start cron daemon with sudo
RUN echo 'node ALL=NOPASSWD: /usr/sbin/cron' >>/etc/sudoers

ENTRYPOINT sudo cron && tail -f /var/log/cron.log

Peut-être que cela aide quelqu'un

Senica Gonzalez
la source
Je crois que l'image du nœud utilise l'utilisateur du nœud; alors peut-être que vous deviez ajouter des autorisations pour cet utilisateur
bozdoz
1

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.

Di Santi
la source
-1

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

Krasi Georgiev
la source
Les réponses doivent être autonomes et ne pas être liées à des ressources externes
Nicolas Bouliane
-2

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.

every(1.day, 'Import large data from csv files', :at => '5:00') do |job|
  `rake 'portal:import_data_from_csv'`
end

Créez un conteneur séparé dans le fichier docker-compose et exécutez la commande ci-dessous à l'intérieur du conteneur.

command: bundle exec clockwork lib/clock.rb
Shobha Deepak
la source
1
Belle idée d'utiliser un autre outil pour la planification. Cependant, cette question demandait spécifiquement pour cron, donc votre suggestion serait mieux comme un commentaire à la question à mon avis.
Richard Kiefer