डॉकटर कंटेनर के अंदर क्रॉन जॉब कैसे चलाएं?


275

मैं एक डॉक कंटेनर के अंदर एक क्रोनजोब चलाने की कोशिश कर रहा हूं जो एक शेल स्क्रिप्ट को आमंत्रित करता है।

कल मैं पूरे वेब पर खोज रहा था और ओवरफ्लो हो गया था, लेकिन मुझे वास्तव में ऐसा समाधान नहीं मिला जो काम करता हो।
मैं यह कैसे कर सकता हूँ?

संपादित करें:

मैंने एक काम करने वाले डॉकटर क्रोन कंटेनर के साथ (कमेंटेड) जीथब रिपॉजिटरी बनाई है जो दिए गए अंतराल पर एक शेल स्क्रिप्ट को आमंत्रित करता है।

जवाबों:


365

नौकरी चलाने के लिए उक्त छवि से लॉन्च किए गए कंटेनर के लिए, आप अपने कॉन्ट्राब को एक छवि में कॉपी कर सकते हैं।

"देखो डोकर के साथ एक क्रॉन जॉब चलाने से" जुलिएन Boulay अपने में Ekito/docker-cron:

चलो hello-cronहमारी नौकरी का वर्णन करने के लिए " " नामक एक नई फ़ाइल बनाएं ।

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

निम्नलिखित Dockerfile आपकी छवि बनाने के लिए सभी चरणों का वर्णन करता है

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

(देखें गफ़र की टिप्पणी और मैं कैसे apt-getस्थापित करूँ कम शोर ? :
apt-get -y install -qq --force-yes cronकाम भी कर सकते हैं)

जैसा कि नथन लॉयड ने टिप्पणियों में लिखा है :

एक गोच के बारे में त्वरित नोट:
यदि आप एक स्क्रिप्ट फ़ाइल जोड़ रहे हैं और इसे चलाने के लिए क्रोन बता रहे हैं, तो याद रखें कि क्रोन भूल जाने पर चुपचाप विफल हो जाता है
RUN chmod 0744 /the_script


या, सुनिश्चित करें कि आपकी नौकरी खुद को लॉग फाइल के बजाय सीधे stdout / stderr पर पुनर्निर्देशित करती है, जैसा कि hugoShaka के उत्तर में वर्णित है :

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

अंतिम Dockerfile लाइन को बदलें

CMD ["cron", "-f"]

यह भी देखें (के बारे में cron -f, जो क्रोन को "अग्रभूमि" कहना है) " docker ubuntu cron -fकाम नहीं कर रहा है "


इसे बनाएं और चलाएं:

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

धैर्य रखें, 2 मिनट तक प्रतीक्षा करें और आपकी कमांडलाइन प्रदर्शित होनी चाहिए:

Hello world
Hello world

एरिक टिप्पणी में जोड़ता है :

ध्यान दें कि tailअगर यह छवि निर्माण के दौरान बनाई गई है तो सही फ़ाइल प्रदर्शित नहीं कर सकती है।
यदि ऐसा है, तो आपको सही फ़ाइल लेने के लिए पूंछ के लिए कंटेनर रनटाइम के दौरान फ़ाइल बनाने या स्पर्श करने की आवश्यकता है।

देखें " एक docker के अंत में आउटपुट नहीं दिख रहा हैtail -fCMD "।


1
मेरे पास पहले क्रोन स्थापित करना था, क्योंकि यह शामिल नहीं है। लेकिन इसे डॉकरफाइल से जोड़कर यह काम करता है। धन्यवाद! RUN apt-get update && apt-get install cron
सी हीर

2
आपको संभवतः -y
डीओआर

1
@ गफ़र सही! मैंने आपकी टिप्पणी को अधिक दृश्यता के लिए उत्तर में शामिल किया है और एक और विकल्प जोड़ा है।
VonC

6
क्या यह समाधान अभी भी काम करता है? जब मैं दिए गए दिशानिर्देशों का पालन करता हूं, जब मैं कंटेनर में जड़ और प्रकार के रूप में प्रवेश करता हूं, तो मुझे रूट के crontab -lलिए कोई क्रॉस्टब स्थापित नहीं किया जाता है , साथ ही, मेरी स्क्रीन रिक्त रहती है। हालांकि, जब मैं '/etc/cron.d/' की जांच करता हूं, तो मैं देखता हूं कि क्रैटाब फील्ड वहां (और और भी आश्चर्यजनक रूप से) है, जब मैं जांच करता /var/log/cron.logहूं, तो मैं देखता हूं कि स्क्रिप्ट चल रही है (फ़ाइल सामग्री के साथ जोड़ा जा रहा है Hello World)। मैं इस छवि को अपने Dockerfile में खींच रहा हूं FROM phusion/baseimage:0.10.0:। व्यवहार में विसंगति के बारे में कोई विचार?
होम्युनकुलस रेटिकुल्ली 16

11
2018 तक, यह दृष्टिकोण अब काम नहीं करता है; क्या कोई भी आधार छवि के रूप में उबंटू के साथ काम करने के लिए अपने क्रोनजोब को प्राप्त करने में सक्षम है? मुझे अल्पाइन छवि में कोई दिलचस्पी नहीं है जो क्रॉन बॉक्स के बाहर चलने के साथ आती है
पेलिकन

147

उत्पादन वातावरण में अपनाया गया समाधान खतरनाक हो सकता है

डॉकटर में आपको प्रति कंटेनर केवल एक प्रक्रिया निष्पादित करनी चाहिए क्योंकि यदि आप नहीं करते हैं, तो जिस प्रक्रिया को फोर्क किया गया है और पृष्ठभूमि चला गया है उसकी निगरानी नहीं की जाती है और आप इसे जाने बिना ही रोक सकते हैं।

जब आप पृष्ठभूमि में CMD cron && tail -f /var/log/cron.logनिष्पादित करने के लिए मूल रूप से कांटा प्रक्रिया का उपयोग करते हैं cron, तो मुख्य प्रक्रिया बाहर निकल जाती है और आपको tailfअग्रभूमि में निष्पादित करने देती है। पृष्ठभूमि क्रोन प्रक्रिया को रोक सकता है या आप नोटिस नहीं करेंगे, आपका कंटेनर अभी भी चुपचाप चलेगा और आपका ऑर्केस्ट्रेशन टूल इसे फिर से चालू नहीं करेगा।

आप सीधे अपने कर्ता में क्रोन के कमांड आउटपुट को पुनः निर्देशित करके ऐसी चीज़ से बच सकते हैं stdoutऔर stderrजो क्रमशः /proc/1/fd/1और में स्थित हैं /proc/1/fd/2

मूल शेल पुनर्निर्देश का उपयोग करके आप ऐसा कुछ करना चाह सकते हैं:

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

और आपका CMD होगा: CMD ["cron", "-f"]


14
नीस: cron -f"क्रोन अग्रभूमि" के लिए है। मैंने आपके उत्तर को अधिक दृश्यता के लिए, मेरा उत्तर ऊपर शामिल किया है। +1
वॉनसी

मान लीजिए कि मेरा प्रोग्राम कुछ भी आउटपुट नहीं करता है। क्या मैं अभी भी इस पद्धति का उपयोग कर सकता हूं और सुनिश्चित कर सकता हूं कि मेरी प्रक्रिया पृष्ठभूमि में बंद होने वाली नहीं है?
आर्सेक्टर

1
@ एक्टर इस पद्धति को पृष्ठभूमि में एक प्रक्रिया डालने से बचें, यही कारण है कि यह चुपचाप विफल नहीं होता है। डॉकटर कंटेनर में बैकग्राउंड प्रोसेस सरल नहीं है। यदि आप चाहते हैं कि एक पृष्ठभूमि प्रक्रिया हो, तो आप कंटेनर में चलने वाली कई प्रक्रियाओं की निगरानी के लिए एक init प्रक्रिया का उपयोग करना चाहते हैं। एक अन्य तरीका मुख्य कंटेनर के बगल में एक अन्य कंटेनर में प्रक्रिया शुरू करना है, जिसे 'साइडकार' कहा जाता है। कंटेनर में कई प्रक्रियाओं से बचने के लिए सबसे अच्छा तरीका अक्सर होता है।
ह्यूगोशाका

अच्छा और साफ ! इसे प्यार करें :)
AmaelH

1
यह एक अच्छा समाधान है और एक मुद्दे से अलग हमारे लिए अच्छा काम करता है। जब कंटेनर को एक SIGTERM सिग्नल प्राप्त होता है, तो यह निर्धारित प्रक्रिया के समाप्त होने और शान से बंद होने की प्रतीक्षा नहीं करता है, इसके बजाय यह उस प्रक्रिया को मार रहा है जो समस्या पैदा कर सकता है।
जेम्स हुलसे

107

उन लोगों के लिए जो एक सरल और हल्की छवि का उपयोग करना चाहते हैं:

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 फ़ाइल है कि आपके cronjobs इस रूप में, शामिल हैं:

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

10
सरल, हल्की और मानक छवि आधारित। यह स्वीकृत उत्तर होना चाहिए। साथ ही > /proc/1/fd/1 2> /proc/1/fd/2क्रोनोजर आउटपुट को सीधे डॉक लॉग से एक्सेस करने के लिए पुनर्निर्देशन का उपयोग करें।
हेनरीटेल

2
अल्पाइन का उपयोग नहीं करने वाले लोगों के लिए: -d 8पैरामीटर का समर्थन करने वाला क्रोन मानक क्रोन नहीं है, यह व्यस्त बॉक्स से क्रोन कमांड है। Ubuntu से उदाहरण के लिए, आप इस रूप में चला सकते हैं busybox crond -f -d 8। पुराने संस्करणों के लिए आपको उपयोग करना होगा -L /dev/stdout/
ट्रेंडफिसचर

2
अगर मैं ऐसा कर पाता तो मैं +100 देता। यह एक डॉकर वातावरण में क्रोन नौकरियों को चलाने का सबसे अच्छा तरीका है।
जीतूसमा

1
यदि आप हर बार क्रोन जॉब (या यदि आपको एकाधिक की आवश्यकता है) को बदलने के लिए एक नई छवि नहीं बनाना चाहते हैं, तो आप अल्पाइन चला सकते हैं और क्रोन को सेट करने के लिए वॉल्यूम का उपयोग कर सकते हैं। मैंने निम्नलिखित का उपयोग करके इसका परीक्षण किया docker run -v ${PWD}/cronjobs:/etc/crontabs/root alpine:3.6 crond -f -d 8:। @Groostav आप डॉकटर कम्पोज़ में एक समान चीज़ का उपयोग कर सकते हैं।
द्वितीया_

1
CMD ["crond"या CMD ["cron"?
कोडमिथ

38

@VonC ने जो सुझाव दिया है वह अच्छा है लेकिन मैं सभी क्रॉन जॉब कॉन्फ़िगरेशन को एक लाइन में करना पसंद करता हूं। यह क्रोनजोब स्थान जैसे क्रॉस प्लेटफ़ॉर्म मुद्दों से बचता है और आपको एक अलग क्रोन फ़ाइल की आवश्यकता नहीं होती है।

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

अपना डॉकटर कंटेनर चलाने के बाद, आप यह सुनिश्चित कर सकते हैं कि क्रोन सेवा किसके द्वारा काम कर रही है:

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

यदि आप CMD के बजाय ENTRYPOINT रखना पसंद करते हैं, तो आप CMD को ऊपर से स्थानापन्न कर सकते हैं

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

1
दिलचस्प विकल्प। +1
वॉनसी

2
RUN apt-get update && apt-get -y install cronवरना यह पैकेज खोजने में सक्षम नहीं होगाcron
वर्णानुक्रम

2
धन्यवाद Youness, आपने मुझे निम्नलिखित करने का विचार दिया, जिसने मेरे मामले में काम किया जहां प्रत्येक क्रोन एक अलग फ़ाइल में निर्दिष्ट है: RUN cat $APP_HOME/crons/* | crontab एक आकर्षण की तरह :)
marcostvz

cronएंट्रीपॉइंट स्क्रिप्ट में जोड़ना सबसे अच्छा विकल्प लगता है: ENTRYPOINT ["entrypoint.sh"]
bozdoz

20

ऐसा करने का एक और तरीका है, टास्कर का उपयोग करना , एक कार्य धावक है जिसमें क्रोन (एक अनुसूचक) का समर्थन है।

क्यों ? कभी-कभी क्रोन जॉब चलाने के लिए, आपको क्रोन के साथ अपनी आधार छवि (अजगर, जावा, नोड्ज, रूबी) को मिलाना होगा। इसका मतलब है कि बनाए रखने के लिए एक और छवि। टस्कर क्रोन और आप कंटेनर को डिकॉप करके उससे बचते हैं। आप बस उस छवि पर ध्यान केंद्रित कर सकते हैं जिसे आप अपनी आज्ञाओं को निष्पादित करना चाहते हैं, और इसका उपयोग करने के लिए टास्कर को कॉन्फ़िगर करें।

यहां एक docker-compose.ymlफ़ाइल, जो आपके लिए कुछ कार्य चलाएगी

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

वहाँ 3 कार्य हैं, उनमें से सभी हर मिनट ( every: minute) चलेंगे , और उनमें से प्रत्येक अनुभाग scriptमें परिभाषित छवि के अंदर, कोड को निष्पादित करेगा image

बस चलाएं docker-compose up, और इसे काम करते हुए देखें। यहाँ पूर्ण प्रलेखन के साथ टास्कर रेपो है:

http://github.com/opsxcq/tasker


डॉकरेप्शन (दूसरे कंटेनर से डॉकटर कंटेनर चलाना) एक बुरा अभ्यास है और इसे निरंतर एकीकरण तक सीमित किया जाना चाहिए। docker execनिर्दिष्ट कंटेनरों पर वर्कअराउंड का उपयोग किया जाएगा ।
हेनरीटेल

1
टास्कर docker (Dind / Dockerception) में docker का उपयोग नहीं करता है, ध्यान दें कि docker सॉकेट को एक मैपिंग के रूप में पास किया जाता है, सभी कंटेनर जो स्पैन किए जाते हैं वे डेमॉन में spawned होते हैं जो कि कार्यकर्ता चलाता है। और अगर आप डॉकटर के अंदर टास्कर नहीं चलाना चाहते हैं, तो आप इसे किसी अन्य एप्लिकेशन के रूप में तैनात कर सकते हैं।
OPSXCQ

1
मुझे टास्कर का उपयोग करने के फायदे नहीं मिलते हैं। मुझे वास्तव में जावा और श *** का उपयोग करके एक ओवरकिल मिल गया है, बस एक क्रोन नौकरी चलाने के लिए।
कार्ल एडलर

क्रॉन और आधार छवि को मिलाकर आपकी ज़रूरत है (उदाहरण के लिए अजगर / नोड) जो एक अतिरिक्त निर्भरता बनाता है जिसे बनाए रखने और तैनात करने की आवश्यकता होती है, इस परिदृश्य में सभी नौकरियां समान कंटेनर साझा करती हैं, इसका मतलब है कि आपको बाद में सब कुछ साफ करने के बारे में चिंता करना होगा हर काम चलता है। टास्कर पर चलने वाले जॉब बेकार हैं, इसलिए आपको चिंता करने के लिए कम चीजें हैं।
OPSXCQ

13

VonC का उत्तर पूरी तरह से है। इसके अलावा मैं एक चीज जोड़ना चाहूंगा जिसने मेरी मदद की। यदि आप किसी फ़ाइल को पूंछे बिना केवल क्रोन जॉब चलाना चाहते हैं, तो आपको && tail -f /var/log/cron.logक्रॉन कमांड से बस हटाने का प्रलोभन दिया जाएगा ।

हालाँकि, यह डॉकटर कंटेनर को चलाने के तुरंत बाद बाहर निकलने का कारण होगा क्योंकि जब क्रोन कमांड पूरा हो जाता है, तो डॉकटर को लगता है कि अंतिम कमांड बाहर निकल गया है और इसलिए कंटेनर को मारता है। इसके माध्यम से अग्रभूमि में क्रोन चलाने से बचा जा सकता है cron -f


9

हालांकि इसका उद्देश्य डॉकटर के execइंटरफ़ेस के माध्यम से एक कंटेनर में चल रही प्रक्रिया के बगल में नौकरियों को चलाना है, यह आपके लिए रुचि का हो सकता है।

मैंने एक डेमन लिखा है जो कंटेनरों और शेड्यूल नौकरियों का अवलोकन करता है, उनके मेटाडेटा में परिभाषित किया गया है। उदाहरण:

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

'क्लासिक', क्रोन-जैसे कॉन्फ़िगरेशन भी संभव है।

यहाँ डॉक्स हैं , यहाँ इमेज रिपॉजिटरी है


धन्यवाद। यह उत्तर डॉकर कंटेनर पर्यावरण के लिए सबसे सही है। डॉकर छवियों में कोई बदलाव नहीं, केवल कार्यों को निष्पादित करने के लिए विशेष कंटेनर को जोड़ना, यह docker exec <container_name> <some_command>शेड्यूल द्वारा कमांड की तरह काम करता है ।
PRIHLOP

यह सबसे सरल सरल है "काम पूरा करें" जवाब।
इब्राहिम अवध

9

मैंने अन्य उत्तरों के आधार पर एक डॉकर छवि बनाई, जिसका उपयोग किया जा सकता है

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

जहाँ /path/to/cron: crontab फ़ाइल के लिए पूर्ण पथ, या आप इसे डॉकफ़ाइल में आधार के रूप में उपयोग कर सकते हैं:

FROM gaafar/cron

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

# Add your commands here

संदर्भ के लिए, छवि यहां है


दिलचस्प छवि। +1
वॉनक

5

जब आप अपने कंटेनर को किसी अन्य होस्ट पर तैनात करते हैं, तो ध्यान दें कि यह किसी भी प्रक्रिया को स्वचालित रूप से शुरू नहीं करेगा। आपको यह सुनिश्चित करने की आवश्यकता है कि आपके कंटेनर के अंदर 'क्रोन' सेवा चल रही है। हमारे मामले में, मैं क्रोन सेवा शुरू करने के लिए अन्य सेवाओं के साथ सुपरवाइजर का उपयोग कर रहा हूं।

[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

मुझे पर्यवेक्षक में एक त्रुटि मिलती है। यह बताएं कि क्रोन सेवा कई बार बंद हो गई और एक FATAL राज्य में प्रवेश किया। हालांकि क्रोन शीर्ष पर चल रहा है और सामान्य रूप से क्रोनोजर निष्पादित कर रहा है। इसके लिए धन्यवाद!
लेफहेल

हां, मेरे साथ भी ऐसा ही हुआ, लेकिन यह सामान्य काम करता है, इसलिए परेशान होने की जरूरत नहीं है।
सागर घूघ

5

एक समर्पित कंटेनर में क्रोनजोब को परिभाषित करें जो आपकी सेवा के लिए डॉक निष्पादन के माध्यम से कमांड चलाता है।

यह उच्च सामंजस्य है और चल रही स्क्रिप्ट में आपकी सेवा के लिए आपके द्वारा निर्धारित पर्यावरण चर तक पहुंच होगी।

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

मैं docker swarm का उपयोग कर काम करने के लिए इसे प्राप्त करने में असमर्थ था। myservice unknownत्रुटियां हो रही हैं।
मार्क ग्रिम्स

उच्च सुरक्षा प्रभाव के बारे में चेतावनी होनी चाहिए जिसमें एक डॉक
आकस्मिक

4

यदि आप विंडोज़ के लिए डॉकटर का उपयोग कर रहे हैं, तो याद रखें कि आपको अपने लाइन-एंडिंग फॉर्मेट को CRLF से LF (यानी डॉस से यूनिक्स तक) में बदलना होगा, यदि आप अपने कॉन्टैब फाइल को विंडोज़ से अपने ubuntu कंटेनर में आयात करने का इरादा रखते हैं। यदि नहीं, तो आपका क्रॉन-जॉब काम नहीं करेगा। यहाँ एक काम कर उदाहरण है:

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

वास्तव में मुझे यह पता लगाने में घंटों का समय लगा, क्योंकि डॉकटर कंटेनरों में क्रॉन जॉब डिबगिंग एक थकाऊ काम है। आशा है कि यह किसी और को वहाँ मदद करता है जो काम करने के लिए अपना कोड प्राप्त नहीं कर सकता है!


3

उपरोक्त उदाहरणों से मैंने यह संयोजन बनाया:

अल्पाइन छवि और नैनो में Crontab का उपयोग करके संपादित करें (मुझे नफरत है 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

एक बार की नौकरी के समानांतर एक क्रोन सेटअप करें

स्क्रिप्ट फ़ाइल बनाएं, run.sh कहें, उस नौकरी के साथ जो समय-समय पर चलने वाली है।

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

सुरषित और बहार।

CMD के बजाय Entrypoint का उपयोग करें

च क्या आपके पास डॉकटर कंटेनरीकरण के दौरान किक करने के लिए कई कार्य हैं, इन सभी को चलाने के लिए एंट्रीपॉइंट फ़ाइल का उपयोग करें।

एंट्रीपॉइंट फ़ाइल एक स्क्रिप्ट फ़ाइल है जो एक docker रन कमांड जारी होने पर कार्रवाई में आती है। तो, हम जो भी स्टेप्स चलाना चाहते हैं वह सभी इस स्क्रिप्ट फ़ाइल में डाल सकते हैं।

उदाहरण के लिए, हमारे पास चलाने के लिए 2 काम हैं:

एक बार नौकरी चलाएं : गूंज "डॉकटर कंटेनर शुरू किया गया है"

रन आवधिक नौकरी : run.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

आइए समझते हैं कि फ़ाइल में स्थापित किए गए क्रैस्टैब को क्या करना है

* * * * *: क्रोन अनुसूची; नौकरी को हर मिनट चलना चाहिए। आप अपनी आवश्यकता के आधार पर शेड्यूल को अपडेट कर सकते हैं।

/run.sh: स्क्रिप्ट फ़ाइल का पथ जो समय-समय पर चलाया जाना है

/var/log/cron.log: अनुसूचित क्रोन नौकरी के उत्पादन को बचाने के लिए फ़ाइल नाम।

2>&1: त्रुटि लॉग (यदि कोई है) को भी उसी आउटपुट फ़ाइल पर पुनर्निर्देशित किया जाएगा जो ऊपर उपयोग की गई है।

नोट : एक अतिरिक्त नई लाइन जोड़ना न भूलें, क्योंकि यह इसे एक वैध क्रोन बनाती है। Scheduler.txt: पूरा क्रोन सेटअप एक फ़ाइल पर पुनर्निर्देशित किया जाएगा।

क्रोन में सिस्टम / उपयोगकर्ता विशिष्ट पर्यावरण चर का उपयोग करना

मेरी वास्तविक क्रोन नौकरी अधिकांश तर्कों की अपेक्षा कर रही थी क्योंकि पर्यावरण चर, डॉक रन कमांड को पारित कर दिया गया था। लेकिन, बैश के साथ, मैं किसी भी पर्यावरण चर का उपयोग करने में सक्षम नहीं था जो सिस्टम या डॉकटर कंटेनर से संबंधित है।

फिर, यह इस समस्या के लिए एक बदलाव के रूप में आया:

  1. एंट्रीपॉइंट.sh में निम्न लाइन जोड़ें
declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env
  1. क्रोन सेटअप अपडेट करें और निर्दिष्ट करें-
SHELL=/bin/bash
BASH_ENV=/container.env

अंत में, आपकी entrypoint.shतरह दिखना चाहिए

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

अंतिम लेकिन कम से कम नहीं: एक डॉकरीफाइल बनाएं

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

बस। डॉकर छवि बनाएं और चलाएं!


1
@himanshuIIITian मैंने यह कोशिश की, मुद्दा यह है कि "रन वंस जॉब" की स्क्रिप्ट कभी वापस नहीं आ रही है और साथ ही कॉर्न -फ भी नहीं लौट रही है ... यह मेरे लिए काम नहीं कर रहा है, कोई विचार? धन्यवाद
डोरोन लेवी

@DoronLevi - क्या आप इस मुद्दे पर विचार करने के लिए कुछ लॉग साझा कर सकते हैं? या आप यहाँ से पूरे कोड की जाँच कर सकते हैं - github.com/nehabhardwaj01/docker-cron
himanshuIIITian

प्रतिक्रिया के लिए धन्यवाद। मुझे खुशी है कि उत्तर मददगार था।
himanshuIIITian

1

क्रॉन जॉब्स को / var / स्पूल / cron / crontabs में स्टोर किया जाता है (सभी डिस्ट्रोस आइ नो में सामान्य स्थान)। BTW, आप कुछ इस तरह का उपयोग करके बैश में क्रॉन टैब बना सकते हैं:

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

यह क्रोन कार्य के साथ एक अस्थायी फ़ाइल बनाएगा, फिर क्रॉस्टैब का उपयोग करके इसे प्रोग्राम करेगा। अंतिम पंक्ति अस्थायी फ़ाइल निकालें।


cronडेमॉन सामान्य रूप से एक कंटेनर में नहीं चलता है।
मैट

@BhargavNanekalva को विशेष रूप से एक कंटेनर में सेटअप करने की आवश्यकता होती है जिसे यह उत्तर संबोधित नहीं करता है।
मैट

@ मैट, क्या आप कृपया बता सकते हैं कि कंटेनर में इसे कैसे निर्दिष्ट किया जाना चाहिए? । मैं crontab -l और कमांड दिखाया गया है - kagda.ru/i/6d014816d43_29-06-2017-11:38:59_6d01.png लेकिन अभी भी नहीं चला है
Tebe

@ Копать_Шо_я_нашел आपको crondकंटेनर में चल रही सेवा के अलावा, सामान्य रूप से s6 जैसे सेवा प्रबंधक के साथ चलना होगा। शायद यह पूछें कि एक उचित उत्तर पाने के लिए एक प्रश्न के रूप में
मैट

1

रूट ट्रिम तक सीमित रखने वाली कुछ ट्रिम किए गए चित्रों को चलाने के दौरान, मुझे अपने उपयोगकर्ता को sudoers में जोड़ना होगा और इसे चलाना होगा 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

शायद जो किसी की मदद करे


मेरा मानना ​​है कि नोड छवि नोड उपयोगकर्ता का उपयोग करती है; तो शायद आपको उस उपयोगकर्ता के लिए अनुमतियाँ जोड़ने की आवश्यकता है
bozdoz

1

तो, मेरी समस्या वही थी। फिक्स में कमांड सेक्शन को बदलना था docker-compose.yml

से

आदेश: crontab / etc / crontab और& tail -f / etc / crontab

सेवा

आदेश: crontab / etc / crontab

आदेश: पूंछ -f / etc / crontab

समस्या आदेशों के बीच था '&&'। इसे हटाने के बाद, यह सब ठीक था।


-1

मैंने अब तक का सबसे मजबूत तरीका एक स्वतंत्र क्रोन कंटेनर चलाया है - डॉक क्लाइंट स्थापित करें और डॉक माउंट को बांधें ताकि आप होस्ट पर डॉक सर्वर से बात कर सकें।

तब बस प्रत्येक cron जॉब और / etc / crontab उत्पन्न करने के लिए एक एंट्रीपॉइंट स्क्रिप्ट के लिए env var का उपयोग करें

यहां एक छवि है जो मैंने इस सिद्धांत का उपयोग करके बनाई है और पिछले 3-4 वर्षों से उत्पादन में इसका उपयोग कर रहा हूं।

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


उत्तर स्व-निहित होना चाहिए और बाहरी संसाधनों के लिए लिंक नहीं होना चाहिए
निकोलस बोलियान

-2

कार्यों को शेड्यूल करने के लिए घड़ी की मणि का उपयोग करने का प्रयास करें। इस लिंक में दिए गए चरणों का पालन करें।

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

आप नीचे के रूप में lib / clock.rb फ़ाइल के अंदर रेक कार्य को कॉल कर सकते हैं।

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

डॉकटर-कम्पोज़ फ़ाइल में एक अलग कंटेनर बनाएँ और कंटेनर के अंदर नीचे कमांड चलाएँ।

command: bundle exec clockwork lib/clock.rb

1
शेड्यूलिंग के लिए कुछ अन्य टूल का उपयोग करने का अच्छा विचार है। हालाँकि, यह प्रश्न विशेष रूप से क्रोन के लिए पूछा गया है, इसलिए मेरा सुझाव इस प्रश्न पर टिप्पणी के रूप में बेहतर होगा।
रिचर्ड कीफर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.