도커 컨테이너 내에서 크론 작업을 실행하는 방법은 무엇입니까?


275

쉘 스크립트를 호출하는 도커 컨테이너 내에서 cronjob을 실행하려고합니다.

어제 웹과 스택 오버플로를 검색했지만 실제로 작동하는 솔루션을 찾을 수 없었습니다.
어떻게해야합니까?

편집하다:

주어진 간격마다 쉘 스크립트를 호출하는 작동하는 docker cron 컨테이너로 주석 처리 된 github 저장소 를 만들었습니다 .

답변:


365

해당 이미지에서 시작된 컨테이너가 작업을 실행하기 위해 crontab을 이미지로 복사 할 수 있습니다.

자세한 내용은 " 부두 노동자와 cron 작업을 실행 에서" 줄리앙 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

( Gaafar 의 의견 과 설치를 덜 시끄럽게 만드는 방법을apt-get 참조하십시오 : :
apt-get -y install -qq --force-yes cron작동 가능)

댓글 에서 Nathan Lloyd 가 지적한 바와 같이 :

문제에 대한 빠른 참고 사항 :
스크립트 파일을 추가하고 cron에이를 실행하도록 지시하는 경우, 잊어 버린 경우 Cron이 자동으로 실패 한다는 것을 기억하십시오 .
RUN chmod 0744 /the_script


또는 hugoShaka 의 답변에 설명 된대로 작업 자체가 로그 파일 대신 stdout / stderr로 직접 리디렉션되도록하십시오 .

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

마지막 Dockerfile 줄을

CMD ["cron", "-f"]

(에 대한 참조 cron -f크론 "전경"라고하는 것입니다있는) " 우분투는 고정 표시기 cron -f작동하지 않습니다 "


빌드하고 실행하십시오.

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

인내심을 갖고 2 분 동안 기다리면 명령 행이 표시되어야합니다.

Hello world
Hello world

에릭 은 주석에 다음을 추가합니다 .

참고 수행 tail이 이미지 빌드하는 동안 생성 된 경우 올바른 파일을 표시하지 않을 수 있습니다.
이 경우 테일이 올바른 파일을 선택하도록 컨테이너 런타임 동안 파일을 작성하거나 터치해야합니다.

" 도커 끝에 출력이 표시되지 않음tail -fCMD "을 참조하십시오.


1
cron이 포함되어 있지 않기 때문에 먼저 cron을 설치해야했습니다. 그러나 이것을 Dockerfile에 추가하면 작동합니다. 감사! RUN apt-get update && apt-get install cron
— C Heyer

2
당신은 아마 추가해야합니다 -y않도록 고정 표시기 빌드 종료에 크론을 설치하기
— gafi

1
@Gaafar 맞아! 더 많은 가시성을 위해 답변에 귀하의 의견을 포함시키고 다른 옵션을 추가했습니다.
— VonC

6
이 솔루션은 여전히 ​​작동합니까? 주어진 지침을 따르면 root 및 type으로 컨테이너에 로그인하면 root에 설치된 crontabcrontab -l 이 없습니다 라는 메시지가 표시되고 화면에 아무 것도 표시되지 않습니다. 그러나 '/etc/cron.d/'를 확인하면 crontab 파일이 있고 (더 놀랍게도) 확인 /var/log/cron.log하면 스크립트가 실행되고 있음을 알 수 있습니다 (파일 내용에 추가됨 Hello World). Dockerfile에서이 이미지를 가져옵니다 FROM phusion/baseimage:0.10.0. 행동 불일치에 대한 아이디어가 있습니까?
— Homunculus Reticulli

11
2018 년 현재이 방식은 더 이상 작동하지 않습니다. 누구든지 cronjob을 기본 이미지로 Ubuntu와 함께 사용할 수 있습니까? 나는 상자에서 나오는 cron과 함께 제공되는 알파인 이미지에 관심이 없다
— 펠리컨

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
— VonC

내 프로그램이 아무것도 출력하지 않는다고 가정 해 봅시다. 여전히이 방법을 사용할 수 있으며 백그라운드에서 프로세스가 중지되지 않을 수 있습니까?
— Arcsector

1
@Arcsector이 방법은 백그라운드에서 프로세스를 넣지 않기 때문에 자동으로 실패하지 않습니다. 도커 컨테이너에 백그라운드 프로세스가있는 것은 간단하지 않습니다. 백그라운드 프로세스를 실행하려면 init 프로세스를 사용하여 컨테이너에서 실행하는 여러 프로세스를 모니터링 할 수 있습니다. 또 다른 방법은 '사이드카'라는 기본 컨테이너 옆에있는 다른 컨테이너로 프로세스를 시작하는 것입니다. 가장 좋은 방법은 종종 컨테이너에서 여러 프로세스를 피하는 것입니다.
— hugoShaka

좋고 깨끗합니다! 그것을 사랑 :)
— AmaelH

1
이것은 좋은 해결책이며 한 가지 문제를 제외하고는 우리에게 잘 작동합니다. 컨테이너가 SIGTERM 신호를 수신하면 예약 된 프로세스가 완료 될 때까지 기다리지 않고 정상적으로 종료되는 것처럼 보이지 않고 대신 프로세스를 종료하여 문제를 일으킬 수 있습니다.
— James Hulse

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 는 다음 형식의 cronjob을 포함하는 파일입니다.

* * * * * 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리디렉션을 사용하여 docker logs에서 직접 cronjobs 출력에 액세스하십시오.
— HenriTel

2
알파인을 사용하지 않는 사람들의 경우 : -d 8매개 변수를 지원하는 크론은 표준 크론이 아니며 busybox의 크론 드 명령입니다. 예를 들어 우분투에서 이것을 다음과 같이 실행할 수 있습니다 busybox crond -f -d 8. 이전 버전의 경우을 사용해야 -L /dev/stdout/합니다.
— Trendfischer

2
가능하면이 +100을 줄 것입니다. 이것이 Docker 환경에서 cron 작업을 실행하는 가장 좋은 방법입니다.
— Jitsusama

1
cron 작업을 변경할 때마다 (또는 여러 개가 필요한 경우) 새 이미지를 작성하지 않으려면 Alpine을 실행하고 볼륨을 사용하여 cron을 설정하면됩니다. 다음을 사용하여 테스트했습니다 docker run -v ${PWD}/cronjobs:/etc/crontabs/root alpine:3.6 crond -f -d 8. @Groostav 당신은 Docker Compose에서 비슷한 것을 사용할 수 있습니다.
— duality_

1
CMD ["crond"또는 CMD ["cron"?
— codesmith

38

@VonC가 제안한 것은 좋지만 모든 cron 작업 구성을 한 줄로 수행하는 것을 선호합니다. 이것은 cronjob 위치와 같은 플랫폼 간 문제를 피하고 별도의 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

도커 컨테이너를 실행 한 후 다음을 수행하여 cron 서비스가 작동하는지 확인할 수 있습니다.

# 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
— VonC

2
RUN apt-get update && apt-get -y install cron그렇지 않으면 패키지를 찾을 수 없습니다cron
— alphabetasoup

2
감사합니다 Youness, 당신은 나에게 각 크론이 다른 파일에 지정되어 내 경우에는 일 다음을 수행의 아이디어를 주었다 RUN cat $APP_HOME/crons/* | crontab 매력 :)처럼
— marcostvz

cron진입 점 스크립트에 추가 하는 것이 가장 좋은 옵션 인 것 같습니다. ENTRYPOINT [ "entrypoint.sh"]
— bozdoz

20

cron (스케줄러)을 지원하는 작업 러너 인 Tasker 를 사용하는 것이 다른 방법 입니다.

왜 ? 때로는 cron 작업을 실행하려면 기본 이미지 (python, java, nodejs, ruby)를 크론과 혼합해야합니다. 그것은 유지해야 할 또 다른 이미지를 의미합니다. Tasker는 크론과 컨테이너를 분리하여이를 피합니다. 명령을 실행하려는 이미지에 초점을 맞추고이를 사용하도록 Tasker를 구성 할 수 있습니다.

여기 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 개의 작업이 있으며, 모든 작업은 1 분마다 실행되며 ( every: minute) 섹션에 script정의 된 이미지 내에서 각각의 코드 를 실행합니다 image.

그냥 실행 docker-compose up하고 작동하는지 확인하십시오. 다음은 전체 설명서가 포함 된 Tasker 저장소입니다.

http://github.com/opsxcq/tasker


Dockerception (다른 컨테이너에서 docker 컨테이너를 실행)은 나쁜 습관이며 지속적인 통합으로 제한되어야합니다. 해결 방법은 docker exec지정된 컨테이너 에서 사용 하는 것 입니다.
— HenriTel

1
Tasker는 docker (Dind / Dockerception)에서 docker를 사용하지 않습니다. docker 소켓을 매핑으로 전달하고 생성 된 모든 컨테이너가 tasker가 실행하는 데몬에 생성됩니다. 그리고 docker 내에서 tasker를 실행하지 않으려면 다른 응용 프로그램으로 배포하면됩니다.
— OPSXCQ

1
나는 tasker를 사용하는 이점을 얻지 못합니다. cron 작업을 실행하기 위해 java와 sh ***를 사용하는 것은 정말 과도합니다.
— Karl Adler

cron과 필요한 기본 이미지를 혼합하면 (예 : Python / 노드) 유지 관리 및 배포해야하는 추가 종속성이 생성됩니다.이 시나리오에서는 모든 작업이 동일한 컨테이너를 공유하므로 이후에 모든 항목을 정리할 필요가 없습니다. 모든 작업이 실행됩니다. tasker에서 실행중인 작업은 dem 등이므로 걱정할 사항이 적습니다.
— OPSXCQ

13

VonC의 답변은 매우 철저합니다. 또한 저에게 도움이 된 한 가지를 추가하고 싶습니다. 파일을 미행하지 않고 cron 작업을 실행 && tail -f /var/log/cron.log하려면 cron 명령에서 cron을 제거하려는 유혹을 받습니다.

그러나 cron 명령이 완료되면 Docker는 마지막 명령이 종료되었다고 생각하여 컨테이너를 종료하기 때문에 Docker 컨테이너가 실행 직후 종료됩니다. 이를 통해 포 그라운드에서 cron을 실행하면 피할 수 있습니다 cron -f.


9

Docker 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 컨테이너 환경에 가장 적합합니다. Docker 이미지는 변경되지 않으며 작업 실행을 위해 특수 컨테이너 만 추가 docker exec <container_name> <some_command>하며 일정 별 명령처럼 작동합니다 .
— PRIHLOP

이것은 가장 깨끗하고 가장 간단한 "작업을 완료하십시오"답변입니다.
— 이브라힘 아 와드

9

다른 답변을 기반으로 Docker 이미지를 만들었습니다.

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

여기서 /path/to/cron: crontab 파일의 절대 경로이거나 Dockerfile에서 기본으로 사용할 수 있습니다.

FROM gaafar/cron

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

# Add your commands here

참고로 이미지 는 여기에 있습니다 .


재미있는 이미지. +1
— VonC

5

다른 호스트에 컨테이너를 배포 할 때 프로세스가 자동으로 시작되지 않습니다. 컨테이너 내에서 'cron'서비스가 실행 중인지 확인해야합니다. 우리의 경우 Cron 서비스를 시작하기 위해 다른 서비스와 함께 Supervisord를 사용하고 있습니다.

[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

cron 서비스가 여러 번 중지되어 FATAL 상태로 전환되었다는 supervisor.log 오류가 발생합니다. 그러나 크론은 정상에서 실행되고 크론 작업을 정상적으로 실행하는 것으로 보입니다. 감사합니다!
— lephleg

예, 나에게도 같은 일이 일어 났지만 정상적으로 작동하므로 귀찮게 할 필요가 없습니다.
— Sagar Ghuge

5

docker exec를 통해 서비스에 명령을 실행하는 전용 컨테이너에 cronjob을 정의하십시오.

응집력이 높으며 실행중인 스크립트는 서비스에 대해 정의한 환경 변수에 액세스 할 수 있습니다.

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

도커 떼를 사용 하여이 작업을 수행 할 수 없었습니다. 가져 오기 myservice unknown오류를.
— Mark Grimes

도커 소켓을 마운트 할 때 높은 보안 영향에 대한 경고가 있어야합니다. lvh.io/posts/…
— 캐주얼

4

windows 용 docker를 사용하는 경우 crontab 파일을 Windows에서 우분투 컨테이너로 가져 오려면 줄 끝 형식을 CRLF에서 LF로 변경해야합니다 (즉, dos에서 unix로)해야합니다. 그렇지 않으면 cron-job이 작동하지 않습니다. 다음은 실제 예입니다.

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

docker 컨테이너에서 cron 작업을 디버깅하는 것은 지루한 작업이므로 실제로 알아내는 데 몇 시간이 걸렸습니다. 코드가 작동하지 않는 다른 사람을 도울 수 있기를 바랍니다.


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 대신 진입 점 사용

도커 컨테이너화 중에 여러 작업을 시작하려면 시작점 파일을 사용하여 모두 실행하십시오.

진입 점 파일은 docker run 명령이 실행될 때 작동하는 스크립트 파일입니다. 따라서 실행하려는 모든 단계를이 스크립트 파일에 넣을 수 있습니다.

예를 들어, 두 가지 작업을 실행해야합니다.

한 번 작업 실행 : echo "Docker 컨테이너가 시작되었습니다"

정기적 인 작업 실행 : run.sh

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

파일에 설정된 crontab을 이해합시다

* * * * *: Cron 스케줄; 작업은 1 분마다 실행해야합니다. 요구 사항에 따라 일정을 업데이트 할 수 있습니다.

/run.sh: 정기적으로 실행되는 스크립트 파일의 경로

/var/log/cron.log: 스케줄 된 cron 작업의 출력을 저장하기위한 파일 이름입니다.

2>&1: 오류 로그 (있는 경우)도 위에서 사용한 것과 동일한 출력 파일로 리디렉션됩니다.

참고 : 유효한 cron으로 만들기 때문에 새 줄을 추가하는 것을 잊지 마십시오. Scheduler.txt: 전체 cron 설정이 파일로 리디렉션됩니다.

cron에서 시스템 / 사용자 특정 환경 변수 사용

내 실제 크론 작업은 환경 변수가 docker run 명령에 전달 될 때 대부분의 인수를 기대했습니다. 그러나 bash를 사용하면 시스템 또는 도커 컨테이너에 속한 환경 변수를 사용할 수 없었습니다.

그런 다음이 문제에 대한 해결책으로 나타났습니다.

  1. entrypoint.sh에 다음 줄을 추가하십시오.
declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env
  1. cron 설정을 업데이트하고
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

마지막은 아니지만 : 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

그게 다야. Docker 이미지를 빌드하고 실행하십시오!


1
@himanshuIIITian 나는 이것을 시도했다. 문제는 "한 번 작업 실행"의 스크립트가 절대로 돌아 오지 않으며 또한 옥수수 -f가 돌아 오지 않는다는 것입니다 ...이 아이디어는 저에게 효과적이지 않습니다. 감사합니다
— Doron Levi

@DoronLevi-문제를 조사하기 위해 로그를 공유 할 수 있습니까? 또는 여기에서 전체 코드를 확인할 수 있습니다 -github.com/nehabhardwaj01/docker-cron
— himanshuIIITian

피드백 감사드립니다. 답변이 도움이되었다 니 다행입니다.
— himanshuIIITian

1

Cron 작업은 / var / spool / cron / crontabs (알고있는 모든 배포판의 공통 위치)에 저장됩니다. BTW, bash에서 다음과 같은 것을 사용하여 cron 탭을 만들 수 있습니다.

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

cron 작업으로 임시 파일을 만든 다음 crontab을 사용하여 프로그래밍합니다. 마지막 줄은 임시 파일을 제거합니다.


cron데몬은 일반적으로 컨테이너에서 실행되지 않습니다.
— Matt

@BhargavNanekalva이 답변이 해결하지 못하는 컨테이너에 구체적으로 설정해야합니다.
— Matt

@Matt, 컨테이너에 정확히 어떻게 지정해야하는지 알려주시겠습니까? . crontab -l을 수행하고 명령이 표시됩니다 -kagda.ru/i/6d014816d43_29-06-2017-11:38:59_6d01.png 여전히 실행되지 않습니다
— Tebe

@ Копать_Шо_я_нашел crond컨테이너에서 실행중인 서비스 외에 일반적으로 s6와 같은 서비스 관리자를 사용하여 실행해야합니다. 아마 정답을 얻기위한 질문으로 물어보십시오
— Matt

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

명령 : tail -f / etc / crontab

문제는 명령 사이에 '&&'이었다. 이것을 삭제 한 후 모두 괜찮 았습니다.


-1

내가 지금까지 찾은 가장 강력한 방법은 독립적 인 cron 컨테이너를 실행하는 것입니다-docker 클라이언트를 설치하고 docker sock를 바인드 마운트하여 호스트의 docker 서버와 통신 할 수 있습니다.

그런 다음 각 cron 작업 및 시작점 스크립트에 대해 env vars를 사용하여 / etc / crontab을 생성하십시오.

이 원리를 사용하여 지난 3-4 년 동안 프로덕션에서 사용하여 만든 이미지는 다음과 같습니다.

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


답변은 독립적이어야하며 외부 리소스와 연결되어서는 안됩니다.
— Nicolas Bouliane

-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

docker-compose 파일에 별도의 컨테이너를 만들고 컨테이너 내부에서 아래 명령을 실행하십시오.

command: bundle exec clockwork lib/clock.rb

1
일정에 다른 도구를 사용하는 것이 좋습니다. 그러나이 질문은 cron을 위해 특별히 요청되었으므로 내 의견으로는 질문에 대한 의견으로 제안하는 것이 좋습니다.
— Richard Kiefer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.