Jak uruchomić zadanie CRON w kontenerze dokera?


275

Próbuję uruchomić cronjob w kontenerze dokera, który wywołuje skrypt powłoki.

Wczoraj szukałem w Internecie i przepełniałem stosy, ale tak naprawdę nie mogłem znaleźć rozwiązania, które działa.
W jaki sposób mogę to zrobić?

EDYTOWAĆ:

Utworzyłem (komentowane) repozytorium github z działającym kontenerem cron dokera, który wywołuje skrypt powłoki w danym odstępie czasu.

Odpowiedzi:


365

Możesz skopiować crontab do obrazu, aby kontener uruchomiony z tego obrazu mógł uruchomić zadanie.

Zobacz „ Uruchom pracę z cronem z DockeremJuliena Boulaya w jego Ekito/docker-cron:

Utwórzmy nowy plik o nazwie „ hello-cron”, aby opisać naszą pracę.

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

Poniższy plik Docker opisuje wszystkie etapy tworzenia obrazu

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

(patrz Gaafar dydaktycznego komentarz i Jak zrobić apt-getzainstalować mniej hałaśliwe? :
apt-get -y install -qq --force-yes cronmoże pracować zbyt)

Jak zauważył Nathan Lloyd w komentarzach :

Szybka uwaga na temat gotcha:
jeśli dodajesz plik skryptu i każesz cronowi go uruchomić, pamiętaj, że Cron zawiedzie cicho, jeśli zapomnisz .
RUN chmod 0744 /the_script


OR, upewnij się, że praca sama przekierowuje bezpośrednio do stdout / stderr zamiast pliku dziennika, w sposób opisany w hugoShaka jest odpowiedź :

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

Zamień ostatnią linię Dockerfile na

CMD ["cron", "-f"]

Zobacz także (about cron -f, czyli cron „pierwszy plan”) „ ubuntu dokera cron -fnie działa


Zbuduj i uruchom:

sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example

Bądź cierpliwy, poczekaj 2 minuty, a Twój wiersz poleceń powinien wyświetlać:

Hello world
Hello world

Eric dodaje w komentarzach :

Pamiętaj, że tailmoże nie wyświetlać poprawnego pliku, jeśli zostanie on utworzony podczas kompilacji obrazu.
W takim przypadku należy utworzyć plik lub go dotknąć podczas działania kontenera, aby tail mógł pobrać poprawny plik.

Zobacz „Dane wyjściowe tail -fna końcu okna dokowanego CMDnie są wyświetlane ”.


1
Najpierw musiałem zainstalować crona, ponieważ nie jest on dołączony. Ale dodając to do Dockerfile, działa. Dzięki! RUN apt-get update && apt-get install cron
C Heyer

2
powinieneś prawdopodobnie dodać -ydo instalacji crona, aby uniknąć wyjścia kompilacji
dokera

1
@Gaafar Racja! Uwzględniłem twój komentarz w odpowiedzi dla większej widoczności i dodałem kolejną opcję.
VonC

6
Czy to rozwiązanie nadal działa? Kiedy postępuję zgodnie z podanymi wytycznymi, kiedy loguję się do kontenera jako root i crontab -lpiszę, otrzymuję Brak zainstalowanego crontab dla roota , a także mój ekran pozostaje pusty. Jednak gdy zaznaczam „/etc/cron.d/”, widzę, że jest tam /var/log/cron.logplik crontab (i jeszcze bardziej zaskakujące), kiedy sprawdzam , widzę, że skrypt działa (zawartość pliku jest dołączana Hello World). Ja ciągnąc ten obraz w moim Dockerfile: FROM phusion/baseimage:0.10.0. Wszelkie pomysły dotyczące rozbieżności w zachowaniu?
Homunculus Reticulli

11
Od 2018 r. To podejście już nie działa; czy ktoś był w stanie zmusić cronjob do pracy z Ubuntu jako obrazem podstawowym? Nie interesuje mnie alpejskie zdjęcie, w którym cron wybiega z pudełka
pelikan

147

Przyjęte rozwiązanie może być niebezpieczne w środowisku produkcyjnym .

W oknie dokowanym powinieneś wykonać tylko jeden proces na kontener, ponieważ jeśli tego nie zrobisz, proces, który rozwidlił się i przeszedł w tle, nie jest monitorowany i może się zatrzymać bez Twojej wiedzy.

Gdy używasz CMD cron && tail -f /var/log/cron.logprocesu cron w zasadzie fork, aby wykonać go cronw tle, główny proces kończy działanie i umożliwia wykonanie tailfna pierwszym planie. Proces cron w tle może zostać zatrzymany lub zawieść, czego nie zauważysz, kontener nadal będzie działał w trybie cichym, a narzędzie do aranżacji go nie uruchomi ponownie.

Możesz tego uniknąć, przekierowując bezpośrednio polecenia crona do dokera stdouti stderrktóre znajdują się odpowiednio w /proc/1/fd/1i /proc/1/fd/2.

Używając podstawowych przekierowań powłoki, możesz chcieć zrobić coś takiego:

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

A twoje CMD będzie: CMD ["cron", "-f"]


14
Nicea: cron -fjest dla „pierwszego planu crona”. Dla większej widoczności umieściłem twoją odpowiedź powyżej. +1
VonC

Powiedzmy, że mój program niczego nie wyświetla. Czy nadal mogę korzystać z tej metody i mieć pewność, że mój proces nie zatrzyma się w tle?
Arcsector,

1
@Arcsector ta metoda pozwala uniknąć umieszczania procesu w tle, dlatego nie zawiedzie go po cichu. Posiadanie procesu w tle w kontenerze dokowanym nie jest proste. Jeśli chcesz mieć działający proces w tle, możesz użyć procesu init do monitorowania wielu procesów uruchomionych w kontenerze. Innym sposobem jest uruchomienie procesu w innym pojemniku obok głównego o nazwie „wózek boczny”. Najlepszym sposobem jest często unikanie wielu procesów w kontenerze.
hugoShaka

Ładnie i czysto! Uwielbiam to :)
AmaelH

1
To dobre rozwiązanie i działa dobrze dla nas oprócz jednego problemu. Gdy kontener odbiera sygnał SIGTERM, wydaje się, że nie czeka na zakończenie zaplanowanego procesu i z wdziękiem się go zamknie, zamiast tego zabija proces, który może powodować problemy.
James Hulse

107

Dla tych, którzy chcą użyć prostego i lekkiego obrazu:

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

Gdzie cronjobs to plik zawierający twoje cronjobs, w tej formie:

* * * * * echo "hello stackoverflow" >> /test_file 2>&1
# remember to end this file with an empty new line

10
Prosty, lekki i standardowy obraz. To powinna być zaakceptowana odpowiedź. Użyj również > /proc/1/fd/1 2> /proc/1/fd/2przekierowania, aby uzyskać dostęp do danych wyjściowych cronjobs bezpośrednio z dzienników dokera.
HenriTel

2
Dla osób nie używających alpine: crond obsługujący -d 8parametr nie jest standardowym cronem, jest to komenda crond z busybox. Na przykład z Ubuntu możesz uruchomić to jako busybox crond -f -d 8. W przypadku starszych wersji musisz użyć -L /dev/stdout/.
Trendfischer

2
Dałbym to +100, gdybym mógł. Jest to zdecydowanie najlepszy sposób na uruchamianie zadań cron w środowisku Docker.
Jitsusama,

1
Jeśli nie chcesz budować nowego obrazu za każdym razem, gdy zmieniasz zadanie crona (lub jeśli potrzebujesz wielu), możesz po prostu uruchomić Alpine i użyć woluminu, aby ustawić crona. Testowałem go stosując następujący: docker run -v ${PWD}/cronjobs:/etc/crontabs/root alpine:3.6 crond -f -d 8. @Groostav możesz użyć podobnej rzeczy w Docker Compose.
duality_

1
CMD ["crond"czy CMD ["cron"?
kowal

38

To, co sugeruje @VonC, jest fajne, ale wolę wykonywać wszystkie konfiguracje zadań cron w jednym wierszu. Pozwoli to uniknąć problemów międzyplatformowych, takich jak lokalizacja cronjob i nie potrzebujesz osobnego pliku cron.

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

Po uruchomieniu kontenera dokowanego możesz sprawdzić, czy usługa cron działa:

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

Jeśli wolisz mieć ENTRYPOINT zamiast CMD, możesz zastąpić CMD powyżej

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

1
Ciekawa alternatywa. +1
VonC,

2
RUN apt-get update && apt-get -y install cronw przeciwnym razie nie będzie w stanie znaleźć paczkicron
alphabetasoup

2
Dzięki Youness, podsunąłeś mi pomysł zrobienia tego, co zadziałało w moim przypadku, gdy każdy cron jest określony w innym pliku: RUN cat $APP_HOME/crons/* | crontab Like a charm :)
marcostvz

dodanie crondo skryptu punktu wejścia wydaje się najlepszą opcją: ENTRYPOINT ["entrypoint.sh"]
bozdoz

20

Można to zrobić na inny sposób, korzystając z Taskera , programu uruchamiającego zadania, który obsługuje cron (harmonogram).

Czemu ? Czasami, aby uruchomić zadanie crona, musisz mieszać obraz podstawowy (python, java, nodejs, ruby) z crond. To oznacza kolejny obraz do utrzymania. Tasker uniknie tego, oddzielając crond i kontener. Możesz po prostu skupić się na obrazie, który chcesz wykonać, i skonfigurować Taskera, aby go używał.

Oto docker-compose.ymlplik, który uruchomi dla ciebie niektóre zadania

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")'

Są tam 3 zadania, wszystkie będą uruchamiane co minutę ( every: minute) i każde z nich wykona scriptkod wewnątrz obrazu zdefiniowanego wimage sekcji.

Po prostu biegnij docker-compose upi zobacz, jak działa. Oto repozytorium Tasker z pełną dokumentacją:

http://github.com/opsxcq/tasker


Dockerception (uruchamianie kontenerów dokerów z innego kontenera) jest złą praktyką i powinien być ograniczony do ciągłej integracji. Obejściem byłoby użycie docker execna określonych kontenerach.
HenriTel,

1
Tasker nie używa okna dokowanego w oknie dokowanym (Dind / Dockerception), pamiętaj, że przekazane jest gniazdo dokowania jako mapowanie, wszystkie odradzane pojemniki są odradzane w demonie, który uruchamia zadanie. A jeśli nie chcesz uruchamiać zadania w oknie dokowanym, możesz go wdrożyć jak każdą inną aplikację.
OPSXCQ

1
Nie mam zalet korzystania z Tasker. Wydaje mi się, że to przesada, używając java i sh *** tylko po to, żeby uruchomić zadanie crona.
Karl Adler

Mieszanie crona i potrzebnego obrazu podstawowego (na przykład python / node) tworzy dodatkową zależność, którą należy zachować i wdrożyć, w tym scenariuszu wszystkie zadania mają ten sam kontener, co oznacza, że ​​musisz się martwić o wyczyszczenie wszystkiego po każda praca działa. Zadania uruchomione na Taskerze są idempotentne, więc masz mniej problemów.
OPSXCQ,

13

Odpowiedź VonC jest dość dokładna. Ponadto chciałbym dodać jedną rzecz, która mi pomogła. Jeśli chcesz po prostu uruchomić zadanie crona bez modyfikowania pliku, pokusa może po prostu usunąć plik&& tail -f /var/log/cron.log z polecenia cron.

Spowoduje to jednak zamknięcie kontenera Docker wkrótce po uruchomieniu, ponieważ gdy komenda cron zakończy działanie, Docker uważa, że ​​ostatnia komenda została zakończona, a zatem zabija kontener. Można tego uniknąć, uruchamiając crona na pierwszym planie przez cron -f.


9

Chociaż ma to na celu uruchamianie zadań obok uruchomionego procesu w kontenerze za pośrednictwem Dockera exec interfejsu , może to być dla Ciebie interesujące.

Napisałem demona, który obserwuje na nich kontenery i planuje zadania zdefiniowane w ich metadanych. Przykład:

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

Możliwa jest także „klasyczna” konfiguracja podobna do crona.

Oto dokumenty , oto repozytorium obrazów .


Dziękuję Ci. Ta odpowiedź jest najbardziej odpowiednia dla środowiska kontenerów Docker. Żadnych zmian w obrazach Dockera, tylko dodanie specjalnego kontenera do wykonywania zadań, działa jak polecenie docker exec <container_name> <some_command>według harmonogramu.
PRIHLOP

To najczystsza i najprostsza odpowiedź „zrób zadanie”.
Ibrahim Awad

9

Stworzyłem obraz Dockera na podstawie innych odpowiedzi, które można wykorzystać jak

docker run -v "/path/to/cron:/etc/cron.d/crontab" gaafar/cron

gdzie /path/to/cron: ścieżka bezwzględna do pliku crontab lub można go użyć jako podstawy w pliku Docker:

FROM gaafar/cron

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

# Add your commands here

W celach informacyjnych obraz jest tutaj .


Ciekawy obraz. +1
VonC

5

Po wdrożeniu kontenera na innym hoście pamiętaj, że nie uruchomi on automatycznie żadnych procesów. Musisz upewnić się, że usługa „cron” działa w twoim kontenerze. W naszym przypadku używam Supervisord z innymi usługami do uruchomienia usługi 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

W pliku supervisor.log pojawia się błąd polegający na tym, że usługa cron zatrzymała się wiele razy i weszła w stan FATAL. Jednak wydaje się, że cron działa na górze i normalnie wykonuje cronjobs. Dzięki za to!
lephleg

Tak, to samo mi się przydarzyło, ale działa normalnie, więc nie musisz się tym przejmować.
Sagar Ghuge,

5

Zdefiniuj cronjob w dedykowanym kontenerze, który uruchamia polecenie za pośrednictwem exec docker do twojej usługi.

Zapewnia to większą spójność, a uruchomiony skrypt będzie miał dostęp do zmiennych środowiskowych zdefiniowanych dla usługi.

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

Nie udało mi się tego uruchomić za pomocą roju dokerów. Występują myservice unknownbłędy.
Mark Grimes

Powinno być ostrzeżenie o wysokim wpływie na bezpieczeństwo zamontowania gniazda dokera
casual

4

Jeśli używasz okna dokowanego dla systemu Windows, pamiętaj, że musisz zmienić format zakończenia linii z CRLF na LF (tj. Z dos na unix), jeśli zamierzasz importować plik crontab z systemu Windows do kontenera ubuntu. Jeśli nie, twoje zadanie cron nie zadziała. Oto działający przykład:

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

Właściwie zajęło mi to wiele godzin, ponieważ debugowanie zadań cron w kontenerach dokerów jest żmudnym zadaniem. Mam nadzieję, że pomoże to każdemu, kto nie może uruchomić swojego kodu!


3

Z powyższych przykładów stworzyłem tę kombinację:

Alpine Image & Edit przy użyciu Crontab w Nano (nienawidzę 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

2

Skonfiguruj crona równolegle do jednorazowego zadania

Utwórz plik skryptu, powiedzmy run.sh, z zadaniem, które ma być uruchamiane okresowo.

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

Zapisz i wyjdź.

Użyj Entrypoint zamiast CMD

Jeśli masz wiele zadań do uruchomienia podczas konteneryzacji dokera, użyj pliku punktu wejścia, aby je wszystkie uruchomić.

Plik punktu wejścia to plik skryptu, który zaczyna działać po wydaniu polecenia uruchamiania dokera. Tak więc wszystkie kroki, które chcemy uruchomić, można umieścić w tym pliku skryptu.

Na przykład mamy 2 zadania do uruchomienia:

Uruchom raz zadanie : echo „Kontener Docker został uruchomiony”

Uruchom okresową pracę : run.sh

Utwórz 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

Rozumiemy crontab, który został ustawiony w pliku

* * * * *: Harmonogram Cron; zadanie musi działać co minutę. Możesz zaktualizować harmonogram zgodnie ze swoimi wymaganiami.

/run.sh: Ścieżka do pliku skryptu, który ma być uruchamiany okresowo

/var/log/cron.log: Nazwa pliku do zapisania wyniku zaplanowanego zadania cron.

2>&1: Dzienniki błędów (jeśli istnieją) również zostaną przekierowane do tego samego pliku wyjściowego, który został użyty powyżej.

Uwaga : Nie zapomnij dodać nowej nowej linii, ponieważ czyni ją to prawidłowym cronem. Scheduler.txt: pełna konfiguracja crona zostanie przekierowana do pliku.

Używanie zmiennych środowiskowych specyficznych dla systemu / użytkownika w cron

Moje rzeczywiste zadanie cron oczekiwało większości argumentów, gdy zmienne środowiskowe były przekazywane do komendy uruchamiania dokera. Ale dzięki bash nie byłem w stanie użyć żadnej ze zmiennych środowiskowych należących do systemu lub kontenera dokowanego.

Później pojawiło się to obejście tego problemu:

  1. Dodaj następujący wiersz w pliku entrypoint.sh
declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env
  1. Zaktualizuj konfigurację crona i określ-
SHELL=/bin/bash
BASH_ENV=/container.env

W końcu entrypoint.shpowinieneś wyglądać

#!/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

Last but not least: utwórz plik Docker

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

Otóż ​​to. Zbuduj i uruchom obraz Docker!


1
@himanshuIIITian Próbowałem tego, problem polega na tym, że skrypt „uruchom raz zadanie” nigdy nie powraca, a kukurydza -f nie wraca, więc ... to nie działa dla mnie, jakieś pomysły? dzięki
Doron Levi

@DoronLevi - czy możesz udostępnić dzienniki, aby sprawdzić problem? Możesz też sprawdzić cały kod stąd - github.com/nehabhardwaj01/docker-cron
himanshuIIITian

Dziękujemy za opinię. Cieszę się, że odpowiedź była pomocna.
himanshuIIITian

1

Zadania Crona są przechowywane w / var / spool / cron / crontabs (wspólne miejsce we wszystkich dystrybucjach, jakie znam). BTW, możesz utworzyć kartę cron w bash, używając czegoś takiego:

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

Spowoduje to utworzenie pliku tymczasowego z zadaniem cron, a następnie zaprogramowanie go za pomocą crontab. Ostatnia linia usuwa plik tymczasowy.


cronDemon zwykle nie działają w pojemniku.
Matt

@BhargavNanekalva musi być specjalnie skonfigurowany w kontenerze, którego ta odpowiedź nie dotyczy.
Matt

@Matt, czy mógłbyś wskazać, jak dokładnie powinien być określony w kontenerze? . Robię crontab -l i wyświetla się polecenie - kagda.ru/i/6d014816d43_29-06-2017-11:38:59_6d01.png, ale nadal nie działa
Tebe

@ Копать_Шо_я_нашел Musisz uruchomić crondoprócz usługi uruchomionej w kontenerze, zwykle z menedżerem usług, takim jak s6. Prawdopodobnie zadaj to pytanie, aby uzyskać właściwą odpowiedź
Matt

1

Podczas pracy z niektórymi przyciętymi obrazami, które ograniczają dostęp do roota, musiałem dodać mojego użytkownika do sudoers i uruchomić jako 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

Może to komuś pomaga


Wierzę, że obraz węzła używa użytkownika węzła; więc może trzeba było dodać uprawnienia dla tego użytkownika
bozdoz

1

Mój problem był taki sam. Poprawka polegała na zmianie sekcji poleceń wdocker-compose.yml .

Z

polecenie: crontab / etc / crontab && tail -f / etc / crontab

Do

polecenie: crontab / etc / crontab

polecenie: tail -f / etc / crontab

Problemem był „&&” pomiędzy poleceniami. Po usunięciu tego wszystko było w porządku.


-1

Najbardziej niezawodnym sposobem, jaki do tej pory znalazłem, jest uruchomienie niezależnego kontenera cron - zainstaluj klienta dokera i powiąż zamontowanie skarpety dokera, aby móc rozmawiać z serwerem dokera na hoście.

Następnie wystarczy użyć zmiennych env dla każdego zadania cron i skryptu punktu wejścia do wygenerowania pliku / etc / crontab

Oto obraz, który stworzyłem, stosując tę ​​zasadę i używając go w produkcji przez ostatnie 3-4 lata.

https://www.vip-consult.solutions/post/better-docker-cron#content


Odpowiedzi powinny być niezależne i nie zawierać linków do zasobów zewnętrznych
Nicolas Bouliane

-2

Spróbuj użyć klejnotu w zegarku, aby zaplanować zadania. Postępuj zgodnie z instrukcjami podanymi w tym łączu.

http://fuzzyblog.io/blog/rails/2017/05/11/adding-cron-to-a-dockerized-rails-application-using-clockwork.html

Możesz wywołać zadanie prowizji w pliku lib / clock.rb jak poniżej.

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

Utwórz osobny kontener w pliku skompiluj okno dokowane i uruchom poniższe polecenie w kontenerze.

command: bundle exec clockwork lib/clock.rb

1
Fajny pomysł, aby użyć innego narzędzia do planowania. Jednak pytanie to dotyczyło konkretnie crona, więc moja sugestia byłaby lepsza jako komentarz do pytania, moim zdaniem.
Richard Kiefer,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.