Làm thế nào để chạy một công việc cron bên trong một container docker?


275

Tôi đang cố gắng chạy một cronjob bên trong một container docker gọi ra một kịch bản shell.

Hôm qua tôi đã tìm kiếm trên tất cả các trang web và ngăn xếp tràn, nhưng tôi thực sự không thể tìm thấy một giải pháp hoạt động.
Tôi có thể làm cái này như thế nào?

BIÊN TẬP:

Tôi đã tạo một kho lưu trữ github (đã nhận xét) với bộ chứa cron docker hoạt động để gọi tập lệnh shell trong khoảng thời gian nhất định.

Câu trả lời:


364

Bạn có thể sao chép crontab của bạn vào một hình ảnh, để container được khởi chạy từ hình ảnh đã nói để chạy công việc.

Xem " Chạy một công việc định kỳ với Docker " từ Julien Boulay trong Ekito/docker-cron:

Hãy tạo một tệp mới gọi là " hello-cron" để mô tả công việc của chúng tôi.

* * * * * 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 sau đây mô tả tất cả các bước để xây dựng hình ảnh của bạn

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

(xem bình luận của GaafarLàm cách nào để cài đặt ít ồn hơn ? : cũng có thể hoạt động)apt-get
apt-get -y install -qq --force-yes cron

Theo ghi nhận của Nathan Lloyd trong các bình luận :

Ghi chú nhanh về một gotcha:
Nếu bạn đang thêm tệp tập lệnh và yêu cầu cron chạy nó, hãy nhớ Cron thất bại trong âm thầm nếu bạn quên .
RUN chmod 0744 /the_script


HOẶC, đảm bảo rằng công việc của bạn tự chuyển hướng trực tiếp đến thiết bị xuất chuẩn / stderr thay vì tệp nhật ký, như được mô tả trong câu trả lời của hugoShaka :

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

Thay thế dòng Dockerfile cuối cùng bằng

CMD ["cron", "-f"]

Xem thêm (về cron -f, nghĩa là cron "foreground") " docker ubfox cron -fkhông hoạt động "


Xây dựng và chạy nó:

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

Hãy kiên nhẫn, đợi trong 2 phút và dòng lệnh của bạn sẽ hiển thị:

Hello world
Hello world

Eric thêm vào trong các ý kiến :

Lưu ý rằng tailcó thể không hiển thị tệp chính xác nếu nó được tạo trong quá trình xây dựng hình ảnh.
Nếu đó là trường hợp, bạn cần tạo hoặc chạm vào tệp trong thời gian chạy bộ chứa để đuôi để chọn đúng tệp.

Xem " Đầu ra tail -fở cuối docker CMDkhông hiển thị ".


1
Tôi đã có đầu tiên để cài đặt cron, vì nó không được bao gồm. Nhưng bằng cách thêm nó vào Dockerfile, nó hoạt động. Cảm ơn! RUN apt-get update && apt-get install cron
C Heyer

2
có lẽ bạn nên thêm -yvào để cài đặt cron để tránh thoát
docker build

1
@Gaafar Đúng rồi! Tôi đã bao gồm nhận xét của bạn trong câu trả lời để dễ nhìn hơn và thêm một tùy chọn khác.
VonC

6
Liệu giải pháp này vẫn hoạt động? Khi tôi làm theo các hướng dẫn được đưa ra, khi tôi đăng nhập vào vùng chứa dưới dạng root và gõ crontab -l, tôi nhận được Không cài đặt crontab cho root , màn hình của tôi vẫn trống. Tuy nhiên, khi tôi kiểm tra '/etc/cron.d/', tôi thấy crontab fiel ở đó (và thậm chí đáng ngạc nhiên hơn), khi tôi kiểm tra /var/log/cron.log, tôi thấy rằng tập lệnh đang chạy (nội dung tệp đang được thêm vào Hello World). Tôi đang kéo hình ảnh này trong Dockerfile của mình : FROM phusion/baseimage:0.10.0. Bất kỳ ý tưởng về sự khác biệt trong hành vi?
Homunculus Reticulli

11
Kể từ năm 2018, phương pháp này không còn hiệu quả; có ai có thể lấy cronjob của họ để làm việc với Ubuntu làm hình ảnh cơ bản không? Tôi không quan tâm đến hình ảnh Alps đi kèm với cron chạy ra khỏi hộp
bồ nông

145

Các giải pháp được thông qua có thể nguy hiểm trong một môi trường sản xuất .

Trong docker, bạn chỉ nên thực hiện một quy trình cho mỗi container bởi vì nếu bạn không, quá trình rẽ nhánh và đi nền không được giám sát và có thể dừng lại mà bạn không biết.

Khi bạn sử dụng CMD cron && tail -f /var/log/cron.logquy trình cron về cơ bản ngã ba để thực thi crontrong nền, quy trình chính sẽ thoát và cho phép bạn thực hiện tailfở phía trước. Quá trình cron nền có thể dừng hoặc thất bại mà bạn không nhận thấy, container của bạn sẽ vẫn chạy một cách im lặng và công cụ điều phối của bạn sẽ không khởi động lại nó.

Bạn có thể tránh điều đó bằng cách chuyển hướng trực tiếp đầu ra lệnh của cron vào docker của bạn stdoutstderrđược đặt tương ứng trong /proc/1/fd/1/proc/1/fd/2.

Sử dụng chuyển hướng shell cơ bản, bạn có thể muốn làm một cái gì đó như thế này:

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

Và CMD của bạn sẽ là: CMD ["cron", "-f"]


14
Nice: cron -flà cho "cron foreground". Tôi đã bao gồm câu trả lời của bạn trong tôi ở trên, để dễ nhìn hơn. +1
VonC

Giả sử chương trình của tôi không xuất ra bất cứ thứ gì. Tôi vẫn có thể sử dụng phương pháp này và chắc chắn rằng quá trình của tôi sẽ không dừng lại ở chế độ nền?
Arcsector

1
@Arcsector phương pháp này tránh đặt một quá trình trong nền, đó là lý do tại sao nó không thất bại âm thầm. Có một quá trình nền trong một container docker là không đơn giản. Nếu bạn muốn có một quy trình chạy nền, bạn có thể muốn sử dụng quy trình init để theo dõi nhiều quy trình bạn chạy trong vùng chứa. Một cách khác là bắt đầu quá trình vào một container khác bên cạnh cái chính gọi là 'sidecar'. Cách tốt nhất thường là tránh nhiều quá trình trong container.
hugoShaka

Đẹp và sạch sẽ ! Thích nó :)
AmaelH

1
Đây là một giải pháp tốt và hoạt động tốt cho chúng tôi ngoài một vấn đề. Khi container nhận được tín hiệu SIGTERM, nó dường như không đợi quá trình theo lịch trình kết thúc và tắt máy một cách duyên dáng, thay vào đó, nó đang giết chết quá trình có thể gây ra sự cố.
James Hulse

106

Đối với những người muốn sử dụng một hình ảnh đơn giản và nhẹ:

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

Trong đó cronjobs là tệp chứa cronjobs của bạn, ở dạng này:

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

10
Đơn giản, ánh sáng và tiêu chuẩn dựa trên hình ảnh. Đây phải là câu trả lời được chấp nhận. Đồng thời sử dụng > /proc/1/fd/1 2> /proc/1/fd/2chuyển hướng để truy cập đầu ra cronjobs trực tiếp từ nhật ký docker.
HenriTel

2
Đối với những người không sử dụng alpine: crond hỗ trợ -d 8tham số không phải là cron tiêu chuẩn, đó là lệnh crond từ busybox. Ví dụ từ Ubuntu, bạn có thể chạy nó dưới dạng busybox crond -f -d 8. Đối với các phiên bản cũ hơn bạn phải sử dụng -L /dev/stdout/.
Trendfischer

Đối với nhu cầu của tôi - mô phỏng một bộ cài đặt sản xuất các công việc định kỳ chạy độc lập nơi tôi cần xem những gì đang xảy ra - điều này thật tuyệt.
Thorbjørn Ravn Andersen

2
Tôi sẽ cho +100 này nếu tôi có thể. Đây là cách tốt nhất để chạy các công việc định kỳ trong môi trường Docker.
Jitsusama

1
Nếu bạn không muốn xây dựng một hình ảnh mới mỗi khi bạn thay đổi công việc định kỳ (hoặc nếu bạn cần nhiều), bạn chỉ có thể chạy Alpine và sử dụng âm lượng để đặt cron. Tôi đã thử nghiệm nó bằng cách sử dụng như sau : docker run -v ${PWD}/cronjobs:/etc/crontabs/root alpine:3.6 crond -f -d 8. @Groostav bạn có thể sử dụng một thứ tương tự trong Docker Compose.
nhị nguyên_

38

Những gì @VonC đã đề xuất là tốt nhưng tôi thích thực hiện tất cả cấu hình công việc định kỳ trong một dòng. Điều này sẽ tránh các vấn đề đa nền tảng như vị trí cronjob và bạn không cần một tệp cron riêng.

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

Sau khi chạy bộ chứa docker của bạn, bạn có thể chắc chắn rằng dịch vụ cron có hoạt động không:

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

Nếu bạn muốn có ENTRYPOINT thay vì CMD, thì bạn có thể thay thế CMD ở trên bằng

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

1
Thú vị thay thế. +1
VonC

2
RUN apt-get update && apt-get -y install cronhoặc nếu không nó sẽ không thể tìm thấy góicron
alphabetasoup

2
Cảm ơn Youness, bạn đã cho tôi ý tưởng thực hiện những điều sau, hoạt động trong trường hợp của tôi khi mỗi cron được chỉ định trong một tệp khác nhau: RUN cat $APP_HOME/crons/* | crontab Giống như một bùa mê :)
marcostvz

thêm cronvào một tập lệnh nhập cảnh có vẻ như là tùy chọn tốt nhất: ENTRYPOINT ["entrypoint.sh"]
bozdoz

20

Có một cách khác để làm điều đó, đó là sử dụng Tasker , một trình chạy tác vụ có hỗ trợ cron (bộ lập lịch).

Tại sao ? Đôi khi để chạy một công việc định kỳ, bạn phải trộn, hình ảnh cơ sở của bạn (python, java, nodejs, ruby) với crond. Điều đó có nghĩa là một hình ảnh khác để duy trì. Tác nhân tránh điều đó bằng cách tách rời crond và bạn chứa. Bạn chỉ có thể tập trung vào hình ảnh mà bạn muốn thực hiện các lệnh của mình và định cấu hình Tác vụ để sử dụng nó.

Đây là một docker-compose.ymltập tin, sẽ chạy một số nhiệm vụ cho bạn

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

Có 3 nhiệm vụ ở đó, tất cả chúng sẽ chạy mỗi phút ( every: minute) và mỗi tác vụ sẽ thực thi scriptmã, bên trong hình ảnh được xác định trong imagephần.

Chỉ cần chạy docker-compose up, và thấy nó hoạt động. Dưới đây là repo tác vụ với tài liệu đầy đủ:

http://github.com/opsxcq/tasker


Dockerception (chạy container docker từ container khác) là một thực tiễn xấu và nên được giới hạn để tích hợp liên tục. Một cách giải quyết sẽ là sử dụng docker exectrên các container được chỉ định.
HenriTel

1
Tác vụ không sử dụng docker trong docker (Dind / Dockerception), lưu ý rằng được chuyển qua socket docker dưới dạng ánh xạ, tất cả các container được sinh ra đều được sinh ra trong daemon mà tasker chạy. Và nếu bạn không muốn chạy tasker bên trong docker, bạn có thể triển khai nó như bất kỳ ứng dụng nào khác.
OPSXCQ

1
Tôi không nhận được những lợi thế của việc sử dụng tasker. Có vẻ như tôi thực sự quá mức khi sử dụng java và sh *** chỉ để chạy một công việc định kỳ.
Karl Adler

Trộn cron và hình ảnh cơ sở mà bạn cần (ví dụ python / nút) tạo ra một phụ thuộc bổ sung cần được duy trì và triển khai, trong trường hợp này, tất cả các công việc đều có chung một container, điều đó có nghĩa là bạn phải lo lắng về việc dọn dẹp mọi thứ sau mọi công việc đều chạy Các công việc chạy trên tasker là idempotent, vì vậy bạn có ít điều phải lo lắng hơn.
OPSXCQ

13

Câu trả lời của VonC khá kỹ lưỡng. Ngoài ra, tôi muốn thêm một điều đã giúp tôi. Nếu bạn chỉ muốn chạy một công việc định kỳ mà không theo đuôi một tập tin, bạn sẽ bị loại bỏ && tail -f /var/log/cron.logkhỏi lệnh cron.

Tuy nhiên, điều này sẽ khiến bộ chứa Docker thoát ra ngay sau khi chạy vì khi lệnh cron hoàn thành, Docker nghĩ rằng lệnh cuối cùng đã thoát và do đó sẽ giết chết container. Điều này có thể tránh được bằng cách chạy cron ở nền trước thông qua cron -f.


9

Mặc dù điều này nhằm mục đích chạy các công việc bên cạnh một quy trình đang chạy trong một container thông qua execgiao diện của Docker , nhưng điều này có thể khiến bạn quan tâm.

Tôi đã viết một daemon quan sát các container và lên lịch các công việc, được xác định trong siêu dữ liệu của chúng, trên chúng. Thí dụ:

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

'Cổ điển', cấu hình giống như cron cũng có thể.

Dưới đây là các tài liệu , đây là kho lưu trữ hình ảnh .


Cảm ơn bạn. Câu trả lời này là đúng nhất cho môi trường Docker container. Không có bất kỳ thay đổi nào trong hình ảnh Docker, chỉ thêm container đặc biệt để thực thi các tác vụ, nó hoạt động như lệnh docker exec <container_name> <some_command>theo lịch trình.
PRIHLOP

Đây là câu trả lời "hoàn thành công việc" đơn giản nhất.
Ibrahim Awad

9

Tôi đã tạo một hình ảnh Docker dựa trên các câu trả lời khác, có thể được sử dụng như

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

trong đó /path/to/cron: đường dẫn tuyệt đối đến tệp crontab hoặc bạn có thể sử dụng nó làm cơ sở trong Dockerfile:

FROM gaafar/cron

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

# Add your commands here

Để tham khảo, hình ảnh ở đây .


Hình ảnh thú vị. +1
VonC

5

Khi bạn triển khai container của mình trên một máy chủ khác, chỉ cần lưu ý rằng nó sẽ không tự động bắt đầu bất kỳ quy trình nào. Bạn cần đảm bảo rằng dịch vụ 'cron' đang chạy bên trong container của bạn. Trong trường hợp của chúng tôi, tôi đang sử dụng Giám sát với các dịch vụ khác để bắt đầu dịch vụ định kỳ.

[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

Tôi gặp lỗi trong giám sát.log rằng dịch vụ cron đã dừng nhiều lần và chuyển sang trạng thái FATAL. Tuy nhiên, cron dường như đang chạy trong top và thực hiện cronjobs bình thường. Cảm ơn vì điều đó!
lephleg

Vâng, điều tương tự cũng xảy ra với tôi, nhưng nó hoạt động như bình thường, vì vậy không cần phải bận tâm.
Sagar Ghuge

5

Xác định cronjob trong một thùng chứa chuyên dụng chạy lệnh thông qua docker exec đến dịch vụ của bạn.

Đây là sự gắn kết cao hơn và tập lệnh đang chạy sẽ có quyền truy cập vào các biến môi trường mà bạn đã xác định cho dịch vụ của mình.

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

Tôi đã không thể làm điều này để làm việc bằng cách sử dụng docker swarm. Bắt myservice unknownlỗi.
Mark Grimes

Nên có một cảnh báo về tác động an ninh cao gắn một ổ cắm Docker có: lvh.io/posts/...
thường

4

Nếu bạn đang sử dụng docker cho windows, hãy nhớ rằng bạn phải thay đổi định dạng kết thúc dòng của mình từ CRLF sang LF (nghĩa là từ dos sang unix) nếu bạn có ý định nhập tệp crontab từ windows vào thùng chứa ub Ubuntu của bạn. Nếu không, công việc định kỳ của bạn sẽ không hoạt động. Đây là một ví dụ hoạt động:

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

Điều này thực sự khiến tôi mất hàng giờ để tìm ra, vì việc gỡ lỗi các công việc định kỳ trong các container docker là một công việc tẻ nhạt. Hy vọng nó sẽ giúp bất cứ ai khác ngoài đó không thể làm cho mã của họ hoạt động!


3

Từ các ví dụ trên tôi đã tạo ra sự kết hợp này:

Hình ảnh & Chỉnh sửa bằng cách sử dụng Crontab trong Nano (Tôi ghét 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

Thiết lập cron song song với công việc một lần

Tạo một tệp script, giả sử run.sh, với công việc được cho là chạy định kỳ.

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

Lưu và thoát.

Sử dụng Entrypoint thay vì CMD

Nếu bạn có nhiều công việc để khởi động trong quá trình chứa docker, hãy sử dụng tệp entrypoint để chạy tất cả.

Tệp nhập điểm là một tệp kịch bản có hiệu lực khi lệnh chạy docker được ban hành. Vì vậy, tất cả các bước mà chúng tôi muốn chạy có thể được đặt trong tệp tập lệnh này.

Chẳng hạn, chúng tôi có 2 công việc để chạy:

Chạy một lần công việc : echo container Docker container đã được khởi động

Chạy công việc định kỳ : run.sh

Tạo 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

Hãy hiểu crontab đã được thiết lập trong tệp

* * * * *: Lịch trình cron; công việc phải chạy mỗi phút. Bạn có thể cập nhật lịch trình dựa trên yêu cầu của bạn.

/run.sh: Đường dẫn đến tệp script sẽ được chạy định kỳ

/var/log/cron.log: Tên tệp để lưu đầu ra của công việc định kỳ theo lịch trình.

2>&1: Nhật ký lỗi (nếu có) cũng sẽ được chuyển hướng đến cùng một tệp đầu ra được sử dụng ở trên.

Lưu ý : Đừng quên thêm một dòng mới, vì nó làm cho nó trở thành một cron hợp lệ. Scheduler.txt: thiết lập cron hoàn chỉnh sẽ được chuyển hướng đến một tệp.

Sử dụng các biến môi trường cụ thể của Hệ thống / Người dùng trong cron

Công việc định kỳ thực tế của tôi đã mong đợi hầu hết các đối số khi các biến môi trường được truyền cho lệnh chạy docker. Nhưng, với bash, tôi không thể sử dụng bất kỳ biến môi trường nào thuộc về hệ thống hoặc bộ chứa docker.

Sau đó, đây là một giải pháp cho vấn đề này:

  1. Thêm dòng sau vào entrypoint.sh
declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env
  1. Cập nhật thiết lập cron và chỉ định-
SHELL=/bin/bash
BASH_ENV=/container.env

Cuối cùng, bạn entrypoint.shsẽ trông giống như

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

Cuối cùng nhưng không kém phần quan trọng: Tạo 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

Đó là nó. Xây dựng và chạy hình ảnh Docker!


1
@himanshuIIITian Tôi đã thử điều này, vấn đề là kịch bản của "chạy một lần công việc" sẽ không bao giờ quay trở lại và ngô cũng không quay trở lại nên ... điều này không hiệu quả với tôi, có ý tưởng nào không? cảm ơn
Doron Levi

@DoronLevi - bạn có thể vui lòng chia sẻ một số nhật ký để xem xét vấn đề không? Hoặc bạn có thể kiểm tra toàn bộ mã từ đây - github.com/nehabhardwaj01/docker-cron
himanshuIIITian

Cảm ơn vì bạn đã phản hồi. Tôi rất vui vì câu trả lời là hữu ích.
himanshuIIITian

1

Các công việc cron được lưu trữ trong / var / spool / cron / crontabs (Vị trí phổ biến trong tất cả các bản phân phối tôi biết). BTW, Bạn có thể tạo tab cron trong bash bằng cách sử dụng cái gì đó như thế:

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

Điều này sẽ tạo một tệp tạm thời với tác vụ cron, sau đó lập trình nó bằng crontab. Dòng cuối cùng loại bỏ tập tin tạm thời.


Các crondaemon thường không chạy trong một container.
Matt

@BhargavNanekalva nó cần được thiết lập cụ thể trong một thùng chứa mà câu trả lời này không giải quyết.
Matt

@Matt, bạn có thể vui lòng chỉ ra chính xác nó nên được chỉ định như thế nào trong container không? . Tôi làm crontab -l và lệnh được hiển thị - kagda.ru/i/6d014816d43_29-06-2017-11:38:59_6d01.png nhưng vẫn không chạy
Tebe

@ Toàn crondbộ dịch vụ bạn phải chạy cùng với dịch vụ bạn đang chạy trong container, thông thường với trình quản lý dịch vụ như s6. Có thể hỏi đó như một câu hỏi để có câu trả lời thích hợp
Matt

1

Khi chạy trên một số hình ảnh được cắt bớt hạn chế quyền truy cập root, tôi đã phải thêm người dùng của mình vào sudoers và chạy như 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

Có lẽ điều đó giúp được ai đó


Tôi tin rằng hình ảnh nút sử dụng người dùng nút; vì vậy có lẽ bạn cần thêm quyền cho người dùng đó
bozdoz

1

Vì vậy, vấn đề của tôi là như vậy. Cách khắc phục là thay đổi phần lệnh trong docker-compose.yml.

Từ

lệnh: crontab / etc / crontab && tail -f / etc / crontab

Đến

lệnh: crontab / etc / crontab

lệnh: đuôi -f / etc / crontab

Các vấn đề là '&&' giữa các lệnh. Sau khi xóa điều này, tất cả đều ổn.


-1

Cách mạnh mẽ nhất mà tôi tìm thấy cho đến nay là chạy một bộ chứa cron độc lập - cài đặt máy khách docker và liên kết gắn kết docker sock để bạn có thể nói chuyện với máy chủ docker trên máy chủ.

Sau đó, chỉ cần sử dụng vv env cho mỗi công việc định kỳ và tập lệnh nhập điểm để tạo / etc / crontab

Đây là một hình ảnh mà tôi đã tạo ra bằng cách sử dụng nguyên tắc này và sử dụng nó trong sản xuất trong 3-4 năm qua.

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


Câu trả lời nên được khép kín và không liên kết với các nguồn lực bên ngoài
Nicolas Bouliane

-2

Hãy thử sử dụng đá quý đồng hồ để lên lịch các nhiệm vụ. Thực hiện theo các bước được cung cấp trong liên kết này.

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

Bạn có thể gọi tác vụ cào trong tệp lib / clock.rb như bên dưới.

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

Tạo một thùng chứa riêng trong tệp soạn thảo docker và chạy lệnh bên dưới bên trong thùng chứa.

command: bundle exec clockwork lib/clock.rb

1
Ý tưởng tuyệt vời để sử dụng một số công cụ khác để lập kế hoạch. Tuy nhiên, câu hỏi này được hỏi cụ thể cho cron, vì vậy đề xuất của bạn sẽ tốt hơn khi bình luận cho câu hỏi theo ý kiến ​​của tôi.
Richard Kiefer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.