도커 컨테이너 내에서 cron 작업을 실행하는 방법은 무엇입니까?
셸 스크립트를 호출하는 도커 컨테이너 내에서 cronjob을 실행하려고 합니다.
어제 저는 웹사이트 전체를 검색하고 스택 오버플로를 했지만, 제대로 작동하는 솔루션을 찾을 수 없었습니다.
어떻게 해야 하나요?
당신은 당신의 사할수다를 할 수 .crontab
해당 이미지에서 시작된 컨테이너가 작업을 실행하기 위해 이미지로 이동합니다.
중요: 도커-크론 문제 3에서 언급한 바와 같이, CRLF가 아닌 LF를 사용합니다.cron
java.
Julien Boulay의 "Run cron job with Docker"를 참조하십시오.
을▁called▁""▁a▁file▁new▁let니합성'"라는 새로운 파일을 봅시다.
hello-cron
우리의 직업을 묘사하기 위해.
# must be ended with a new line "LF" (Unix) and not "CRLF" (Windows)
* * * * * 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.
여러분이 궁금면다하지인이 ,2>&1
아이만 휴리가 설명합니다.
다음 도커 파일은 이미지를 빌드하는 모든 단계를 설명합니다.
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 -y install -qq --force-yes cron
작동할 수도 있음
갓챠에 대한 간단한 메모:
에는 "cron"을 기억하십시오.
RUN chmod 0744 /the_script
Cron은 잊어버리면 자동으로 실패합니다.
또는 hugoShaka의 답변에 설명된 대로 작업 자체를 로그 파일이 아닌 stdout/stderr로 직접 리디렉션하십시오.
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
마지막 도커 파일 줄 바꾸기
CMD ["cron", "-f"]
그러나 태스크를 비루트로 실행하려는 경우에는 작동하지 않습니다.
항목: (정보)cron -f
즉, cron "forground") "unbutu가 작동하지 않습니다."
빌드 및 실행:
sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example
인내심을 갖고 2분 동안 기다린 후 명령줄에 다음과 같은 내용이 표시됩니다.
Hello world
Hello world
로 참은 다음과 같습니다.
tail
이미지 빌드 중에 올바른 파일이 생성되면 해당 파일이 표시되지 않을 수 있습니다.
그런 경우, 테일이 올바른 파일을 선택하려면 컨테이너 런타임 중에 파일을 만들거나 터치해야 합니다.
"도커 끝의 출력이 표시되지 않습니다."를 참조하십시오.
제이슨 쿨라퉁가의 "런닝 크론 인 도커"(2021년 4월)에서 더 자세히 보기.
다음을 기반으로 한 Jason의 이미지 보기:
파일 중
cronie
/crond
분포에 따라초화하진점입을
/etc/environment
그리고 나서 부르는 것.cron -f -l 2
허용된 답변은 프로덕션 환경에서 위험할 수 있습니다.
도커에서는 컨테이너당 하나의 프로세스만 실행해야 합니다. 그렇지 않으면 포크되고 백그라운드로 이동한 프로세스가 모니터링되지 않고 사용자 모르게 중지될 수 있기 때문입니다.
를 할 때CMD cron && tail -f /var/log/cron.log
를 실행하기 fork를 .cron
▁in▁exits▁execute▁you다▁the니있▁process▁let▁main▁and습▁back수ground,를 실행할 수 있습니다.tailf
例에:할 수 가 여전히 가 다시.백그라운드 크론 프로세스가 중지되거나 실패할 수 있으며, 컨테이너는 여전히 자동으로 실행되고 오케스트레이션 도구가 다시 시작하지 않습니다.
cron으로 리디렉션하면 수 .
stdout
그리고.stderr
은 각각 위는치각의에 ./proc/1/fd/1
그리고./proc/1/fd/2
.
기본 셸 리디렉션을 사용하여 다음과 같은 작업을 수행할 수 있습니다.
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
는 다음과 CMD ["cron", "-f"]
그러나 태스크를 비루트로 실행하려는 경우에는 작동하지 않습니다.
간단하고 가벼운 이미지를 사용하려는 사용자:
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
하지만 보아하니 당신은 보지 못할 것입니다.hello stackoverflow
docker logs
.
@VonC가 제안한 것은 좋지만 나는 모든 cron 작업 구성을 한 줄로 하는 것을 선호합니다.이렇게 하면 cron 작업 위치와 같은 플랫폼 간 문제를 피할 수 있으며 별도의 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
그러나: 죽으면 용기가 계속 실행됩니다.
다른 방법으로는 cron(스케줄러)을 지원하는 태스크 실행기인 태스커를 사용하는 것이 있습니다.
왜냐고요? 때때로 cron 작업을 실행하려면 기본 이미지(파이톤, 자바, 노드js, 루비)를 cron과 혼합해야 합니다.그것은 유지해야 할 또 다른 이미지를 의미합니다.태스커는 크론드와 사용자 컨테이너를 분리하여 이를 방지합니다.명령을 실행할 이미지에 초점을 맞추고 이를 사용하도록 태스커를 구성하면 됩니다.
에 기여가 .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's 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
'Classic', cron과 같은 구성도 가능합니다.
윈도우용 도커를 사용하는 경우 crontab 파일을 윈도우에서 unbuntu 컨테이너로 가져오려면 CRLF에서 LF(즉, dos에서 unix)로 줄바꿈 형식을 변경해야 합니다.그렇지 않으면 cron 작업이 작동하지 않습니다.다음은 작동하는 예입니다.
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
도커 컨테이너에서 cron 작업을 디버깅하는 것은 지루한 작업이기 때문에 이것을 알아내는 데 실제로 몇 시간이 걸렸습니다.코드가 작동하지 않는 다른 사람들에게 도움이 되기를 바랍니다!
그러나: 죽으면 용기가 계속 실행됩니다.
VonC의 대답은 꽤 철저합니다.추가로 저에게 도움이 된 한 가지를 추가하고 싶습니다.파일을 미행하지 않고 cron 작업을 실행하려는 경우 해당 작업을 제거할 수 있습니다.&& tail -f /var/log/cron.log
.cron 파일 이름입니다.
그러나 cron 명령이 완료되면 Docker는 마지막 명령이 종료되었다고 생각하므로 Docker 컨테이너가 실행된 직후에 종료됩니다.이 문제는 다음을 통해 포그라운드에서 cron을 실행하면 피할 수 있습니다.cron -f
.
불행하게도, 위의 답변들 중 어떤 것도 저에게 효과가 없었습니다. 비록 모든 답변들이 해결책으로 이어지고 결국 제 해결책으로 이어지지만, 누군가에게 도움이 된다면 여기에 그 토막글이 있습니다.감사해요.
이 문제는 bash 파일로 해결할 수 있습니다. Docker의 계층화된 아키텍처로 인해 cron 서비스가 RUN/CMD/ENTRYPOINT 명령으로 시작되지 않습니다.
cron 및 기타 서비스를 시작할 bash 파일을 추가하기만 하면 됩니다(필요한 경우).
도커 파일
FROM gradle:6.5.1-jdk11 AS build
# apt
RUN apt-get update
RUN apt-get -y install cron
# Setup cron to run every minute to print (you can add/update your cron here)
RUN touch /var/log/cron-1.log
RUN (crontab -l ; echo "* * * * * echo testing cron.... >> /var/log/cron-1.log 2>&1") | crontab
# entrypoint.sh
RUN chmod +x entrypoint.sh
CMD ["bash","entrypoint.sh"]
entrypoint.sh
#!/bin/sh
service cron start & tail -f /var/log/cron-2.log
cron과 함께 해당 합니다.&
다음과 같은 명령을 할 수 있습니다./opt/wildfly/bin/standalone.sh & service cron start & tail -f /var/log/cron-2.log
일단 당신이 그곳의 도커 컨테이너에 들어가면 당신은 그것을 볼 수 있습니다.testing cron....
됩니다./var/log/cron-1.log
하지만, 죽으면, 용기는 계속 작동합니다.
다른 답변을 바탕으로 도커 이미지를 만들었는데, 다음과 같이 사용할 수 있습니다.
docker run -v "/path/to/cron:/etc/cron.d/crontab" gaafar/cron
/path/to/cron
파일의 파일의 할 수 . crontab 파일 crontab 파일의 Docker 파일 이름은 Docker 파일 이름입니다.
FROM gaafar/cron
# COPY crontab file in the cron directory
COPY crontab /etc/cron.d/crontab
# Add your commands here
참고로, 이미지는 여기 있습니다.
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"
가장 작은 이미지 중 하나이기 때문에 저는 busybox를 사용하기로 결정했습니다.
crond는 포그라운드(-f)에서 실행되고, 로깅은 stderr(-d)로 전송되며, 로그 수준을 변경하도록 선택하지 않았습니다. crontab 파일이 기본 경로: /var/spool/cron/crontabs로 복사됩니다.
FROM busybox:1.33.1
# Usage: crond [-fbS] [-l N] [-d N] [-L LOGFILE] [-c DIR]
#
# -f Foreground
# -b Background (default)
# -S Log to syslog (default)
# -l N Set log level. Most verbose 0, default 8
# -d N Set log level, log to stderr
# -L FILE Log to FILE
# -c DIR Cron dir. Default:/var/spool/cron/crontabs
COPY crontab /var/spool/cron/crontabs/root
CMD [ "crond", "-f", "-d" ]
그나작의에출볼서없다니습수력은러업다에서 볼 수 .docker logs
.
다른 호스트에 컨테이너를 배포할 때는 프로세스가 자동으로 시작되지 않습니다.'cron' 서비스가 컨테이너 안에서 실행되고 있는지 확인해야 합니다.우리의 경우, 저는 다른 서비스와 함께 Supervisord를 사용하여 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
위의 예에서 저는 다음과 같은 조합을 만들었습니다.
나노에서 크론탭을 사용한 알파인 이미지 & 편집 (나는 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
일회성 작업과 병렬로 cron 설정
정기적으로 실행되어야 하는 작업을 포함하는 스크립트 파일(예: run.sh )을 생성합니다.
#!/bin/bash
timestamp=`date +%Y/%m/%d-%H:%M:%S`
echo "System path is $PATH at $timestamp"
저장하고 종료합니다.
CMD 대신 Entrypoint 사용
도커 컨테이너화 중에 시작할 여러 작업이 있는 경우 진입점 파일을 사용하여 모든 작업을 실행합니다.
진입점 파일은 도커 실행 명령이 실행될 때 실행되는 스크립트 파일입니다.따라서 실행하려는 모든 단계를 이 스크립트 파일에 넣을 수 있습니다.
예를 들어 다음과 같은 두 가지 작업을 실행해야 합니다.
한 번 실행 작업: "도커 컨테이너가 시작되었습니다"라는 에코가 표시됩니다.
정기 작업 실행: 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에 대해 설명하겠습니다.
* * * * *
크론 예약. 매 분마다 작업을 실행해야 합니다.요구 사항에 따라 일정을 업데이트할 수 있습니다.
/run.sh
입니다.
/var/log/cron.log
예약된 cron 작업의 출력을 저장할 파일 이름입니다.
2>&1
오류 로그(있는 경우)도 위에서 사용한 것과 동일한 출력 파일로 리디렉션됩니다.
참고: 새 줄을 추가하는 것을 잊지 마십시오. 새 줄은 유효한 cron이 됩니다.Scheduler.txt
전체 cron 설정이 파일로 리디렉션됩니다.
cron에서 시스템/사용자 관련 환경 변수 사용
실제 cron 작업은 환경 변수가 docker run 명령으로 전달될 때 대부분의 인수를 예상했습니다.하지만 bash로 인해 시스템 또는 도커 컨테이너에 속하는 환경 변수를 사용할 수 없었습니다.
그런 다음 이 문제에 대한 해결책으로 제시되었습니다.
- entrypoint.sh 에 다음 행을 추가합니다.
declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env
- 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
마지막이지만 중요한 것은:도커 파일 만들기
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-compose
기반 솔루션:
cron:
image: alpine:3.10
command: crond -f -d 8
depends_on:
- servicename
volumes:
- './conf/cron:/etc/crontabs/root:z'
restart: unless-stopped
은 cron 항이 라인은에 ../conf/cron
java.
참고: 이 기능은 에 없는 명령을 실행하지 않습니다.alpine
이미지
또한 작업의 출력이 다음에 나타나지 않습니다.docker logs
.
이 질문은 답이 많지만, 어떤 것은 복잡하고 또 다른 것은 단점이 있습니다.저는 문제점을 설명하고 해결책을 전달하려고 노력합니다.
cron-entrypoint.sh
:
#!/bin/bash
# copy machine environment variables to cron environment
printenv | cat - /etc/crontab > temp && mv temp /etc/crontab
## validate cron file
crontab /etc/crontab
# cron service with SIGTERM support
service cron start
trap "service cron stop; exit" SIGINT SIGTERM
# just dump your logs to std output
tail -f \
/app/storage/logs/laravel.log \
/var/log/cron.log \
& wait $!
해결된 문제
- 환경 변수는 cron 환경에서 사용할 수 없습니다(예: 환경 변수 또는 kubernetes 암호).
- crontab 파일이 유효하지 않을 때 중지
- 시스템이 SIGTERM 신호를 수신할 때 cron 작업을 정상적으로 중지
문맥상, 나는 라라벨 앱으로 쿠베르네테스의 이전 스크립트를 사용합니다.
다한직업다의있가다습니지고을존성양양과한▁and▁with다▁multiple.zsh
그리고.curl
이것은 다른 답변의 모범 사례를 결합하는 동시에 좋은 접근 방식입니다.파일: 이렇게 .+x
에 대한 실행 myScript.sh
그것은 새로운 환경에서 놓치기 쉽습니다.
cron.dockerfile
FROM ubuntu:latest
# Install dependencies
RUN apt-get update && apt-get -y install \
cron \
zsh \
curl;
# Setup multiple jobs with zsh and redirect outputs to docker logs
RUN (echo "\
* * * * * zsh -c 'echo "Hello World"' 1> /proc/1/fd/1 2>/proc/1/fd/2 \n\
* * * * * zsh /myScript.sh 1> /proc/1/fd/1 2>/proc/1/fd/2 \n\
") | crontab
# Run cron in forground, so docker knows the task is running
CMD ["cron", "-f"]
도커 구성과 통합하면 다음과 같습니다.
docker-compose.yml
services:
cron:
build:
context: .
dockerfile: ./cron.dockerfile
volumes:
- ./myScript.sh:/myScript.sh
다음을 수행해야 합니다.docker compose build cron
의 할 때cron.dockerfile
다음과 같이 변경됩니다.myScript.sh
컴포지트에 장착된 상태로 바로 반영됩니다.
이 대사는 제가 사전 테스트 작업을 수행하는 데 도움이 되었습니다.
ADD mycron/root /etc/cron.d/root
RUN chmod 0644 /etc/cron.d/root
RUN crontab /etc/cron.d/root
RUN touch /var/log/cron.log
CMD ( cron -f -l 8 & ) && apache2-foreground # <-- run cron
--> 내 프로젝트는 내부에서 실행됩니다: FROM php:7.2-apache
그러나: 죽으면 용기가 계속 실행됩니다.
나는 가끔 그것을 찾으려고 노력했습니다.docker
한 -친숙한cron
했을 때그리고 마지막으로 시도했을 때, 저는 커플을 찾았습니다.
타고docker
제 "은 -친한제말은," "의근산과다볼수있다습니서음에은물출제▁-▁"▁-▁of▁be다있니▁can▁in▁seen습output친▁i"에서 볼 수 있습니다.docker logs
속임수를 쓸 필요가 없습니다."
제가 지금 가장 기대되는 것은.crontab 파일을 제공할 수 있습니다. 모든 동안docker
붙임성 있는사용 방법:
docker-compose.yml
:
services:
supercronic:
build: .
command: supercronic crontab
Dockerfile
:
FROM alpine:3.17
RUN set -x \
&& apk add --no-cache supercronic shadow \
&& useradd -m app
USER app
COPY crontab .
crontab
:
* * * * * date
조금 더 많은 정보가 있는 요지.
또 다른 좋은 점은 YAML을 사용한다는 것입니다.
ofelia
사용할 수 있지만 개별 컨테이너에서 작업을 실행하는 데 중점을 두는 것 같습니다.이것은 아마도 단점은 아닐 것입니다. 하지만 제가 왜 그렇게 하고 싶은지는 잘 모르겠습니다.
그리고 많은 전통적인 것들이 있습니다.cron
구현: , , . 하지만 "작업의 출력을 쉽게 볼 수 있는 방법이 없습니다."
그래서 저의 문제도 마찬가지였습니다. 사항은 수정사의섹변것경이다니습었는하션을령의 이었습니다.docker-compose.yml
.
부터
명령: crontab /etc/crontab && tail -f /etc/crontab
로.
명령: crontab /etc/crontab
명령: tail -f /etc/crontab
문제는 명령 사이의 '&&'이었습니다.이것을 삭제한 후에는 문제가 없었습니다.
수신 시 cron 작업을 정상적으로 중지하는 데 집중SIGTERM
또는SIGQUIT
호예신(중: 실행중)를 실행할 때)docker stop
).
그건 너무 쉽지 않아요.기본적으로 cron 프로세스는 실행 중인 cron 작업에 주의하지 않고 종료되었습니다.저는 파보르스크의 대답을 자세히 설명하고 있습니다.
Dockerfile
:
FROM ubuntu:latest
RUN apt-get update \
&& apt-get -y install cron procps \
&& rm -rf /var/lib/apt/lists/*
# Copy cronjobs file to the cron.d directory
COPY cronjobs /etc/cron.d/cronjobs
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/cronjobs
# similarly prepare the default cronjob scripts
COPY run_cronjob.sh /root/run_cronjob.sh
RUN chmod +x /root/run_cronjob.sh
COPY run_cronjob_without_log.sh /root/run_cronjob_without_log.sh
RUN chmod +x /root/run_cronjob_without_log.sh
# Apply cron job
RUN crontab /etc/cron.d/cronjobs
# to gain access to environment variables, we need this additional entrypoint script
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# optionally, change received signal from SIGTERM TO SIGQUIT
#STOPSIGNAL SIGQUIT
# Run the command on container startup
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh
:
#!/bin/bash
# make global environment variables available within crond, too
printenv | grep -v "no_proxy" >> /etc/environment
# SIGQUIT/SIGTERM-handler
term_handler() {
echo 'stopping cron'
service cron stop
echo 'stopped'
echo 'waiting'
x=$(($(ps u -C run_cronjob.sh | wc -l)-1))
xold=0
while [ "$x" -gt 0 ]
do
if [ "$x" != "$xold" ]; then
echo "Waiting for $x running cronjob(s):"
ps u -C run_cronjob.sh
xold=$x
sleep 1
fi
x=$(($(ps u -C run_cronjob.sh | wc -l)-1))
done
echo 'done waiting'
exit 143; # 128 + 15 -- SIGTERM
}
# cron service with SIGTERM and SIGQUIT support
service cron start
trap "term_handler" QUIT TERM
# endless loop
while true
do
tail -f /dev/null & wait ${!}
done
cronjobs
* * * * * ./run_cronjob.sh cron1
*/2 * * * * ./run_cronjob.sh cron2
*/3 * * * * ./run_cronjob.sh cron3
을 모두 cron으로 합니다.run_cronjob.sh
가 정상적으로할 수 .이렇게 하면 종료가 정상적으로 대기할 임의 코드를 실행할 수 있습니다.
run_cronjobs.sh
를 깨끗하게 유지하기 선택적 job"이라는 단어가 있습니다.)
#!/bin/bash
DIR_INCL="${BASH_SOURCE%/*}"
if [[ ! -d "$DIR_INCL" ]]; then DIR_INCL="$PWD"; fi
cd "$DIR_INCL"
# redirect all cronjob output to docker
./run_cronjob_without_log.sh "$@" > /proc/1/fd/1 2>/proc/1/fd/2
run_cronjob_without_log.sh
your_actual_cronjob_src()
때, 받을를그때를 받습니다.SIGKILL
컨테이너는 여전히 즉시 종료됩니다.그런 식으로 다음과 같은 명령을 사용할 수 있습니다.docker-compose stop -t 60 cron-container
정상적으로 동안 초과 됩니다. .cron 작업은 60초 동안 종료됩니다.
'cron' 자체가 UID 0을 요청하므로 모든 응답에는 컨테이너 내부의 루트 액세스가 필요합니다. 루트 액세스(예: sudo 경유)를 요청하는 것은 도커 모범 사례에 위배됩니다.예약된 작업을 관리하기 위해 https://github.com/gjcarneiro/yacron 을 사용했습니다.
액세스를 때하고 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
누군가에게 도움이 될 수도 있습니다.
그러나: 죽으면 용기가 계속 실행됩니다.
이 이미지를 사용할 수 있는 답변 목록에 추가하면 됩니다. https://hub.docker.com/repository/docker/cronit/simple-cron
다음과 같이 사용하여 cron 작업을 시작하는 기준으로 사용합니다.
FROM cronit/simple-cron # Inherit from the base image
#Set up all your dependencies
COPY jobs.cron ./ # Copy your local config
분명히, cron을 (루트 사용자 아래에서) 다른 프로세스와 함께 컨테이너 내부의 프로세스로 실행할 수 있습니다.ENTRYPOINT
에 있는 (Docker 문일파)start.sh
을 process cron start
자세한 내용은 여기에 있습니다.
#!/bin/bash
# copy environment variables for local use
env >> etc/environment
# start cron service
service cron start
# start other service
service other start
#...
이미지에 데몬이 없는 경우(따라서 짧은 실행 스크립트 또는 프로세스만 해당), 단순히 cron 정보와 스케줄러 자체로 LABEL을 정의하여 외부에서 cron을 시작하는 것도 고려할 수 있습니다.이렇게 하면 기본 컨테이너 상태가 "종료"가 됩니다.스크립트가 여러 개인 경우 병렬 실행 cron 인스턴스가 여러 개인 경우보다 시스템의 설치 공간이 줄어들 수 있습니다.
참조: https://github.com/JaciBrunning/docker-cron-label
도커-구성 예제.음:
version: '3.8'
# Example application of the cron image
services:
cron:
image: jaci/cron-label:latest
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "/etc/localtime:/etc/localtime:ro"
hello:
image: hello-world
restart: "no"
labels:
- "cron.schedule=* * * * * "
저는 제가 더 유연하다고 생각한 다른 제안들 중 일부의 전형적인 것에 대한 수정을 공유하고 싶었습니다.환경 변수를 사용하여 cron 시간을 변경할 수 있도록 설정하고 싶었지만 cron-f로 호출하기 전에 entrypoint.sh 내에서 실행되는 스크립트를 추가했습니다.
*updatecron.sh*
#!/bin/sh
#remove old cron files
rm -rf /etc/cron.*/*
#create a new formatted cron definition
echo "$crondef [appname] >/proc/1/fd/1 2>/proc/1/fd/2" >> /etc/cron.d/restart-cron
echo \ >> /etc/cron.d/restart-cron
chmod 0644 /etc/cron.d/restart-cron
crontab /etc/cron.d/restart-cron
그러면 기존 cron 파일이 제거되고 crondef의 ENV 변수를 사용하여 새 cron 파일이 생성된 다음 로드됩니다.
Our's는 cron 작업으로 실행되는 nodejs 응용 프로그램이었으며 환경 변수에도 의존했습니다.
아래의 해결책이 우리에게 효과가 있었습니다.
도커 파일:
# syntax=docker/dockerfile:1
FROM node:12.18.1
ENV NODE_ENV=production
COPY ["startup.sh", "./"]
# Removed steps to build the node js application
#--------------- Setup cron ------------------
# Install Cron
RUN apt-get update
RUN apt-get -y install cron
# Run every day at 1AM
#/proc/1/fd/1 2>/proc/1/fd/2 is used to redirect cron logs to standard output and standard error
RUN (crontab -l ; echo "0 1 * * * /usr/local/bin/node /app/dist/index.js > /proc/1/fd/1 2>/proc/1/fd/2") | crontab
#--------------- Start Cron ------------------
# Grant execution rights
RUN chmod 755 startup.sh
CMD ["./startup.sh"]
시작합니다.sh:
!/bin/bash
echo "Copying env variables to /etc/environment so that it is available for cron jobs"
printenv >> /etc/environment
echo "Starting cron"
cron -f
간단한 php-fpm 이미지를 사용하려는 사람들:
FROM php:7.4-fpm
RUN apt-get update \
&& apt-get install -y cron\
...
# Copy your cronjob file
COPY /cron/cronjob /etc/cron.d/crontab
COPY /cron/log /var/log
# owner can read and write into the crontab, group and others can read it
RUN chmod 0644 /etc/cron.d/crontab
# running our crontab using the binary from the package we installed
RUN /usr/bin/crontab /etc/cron.d/crontab
CMD cron && docker-php-entrypoint php-fpm
파일:docker-compose.yml 파일에서 하려면 이 .&& docker-php-entrypoint php-fpm
그렇지 않으면 nginx 이미지에 의한 502 불량 게이트웨이 문제(업스트림에 연결하는 동안 111: 연결이 거부됨)라는 오류가 발생했습니다.
이것이 누군가에게 도움이 되기를 바랍니다.
언급URL : https://stackoverflow.com/questions/37458287/how-to-run-a-cron-job-inside-a-docker-container
'sourcecode' 카테고리의 다른 글
Simple Spring @CreatedDate 주석이 작동하지 않습니다. (0) | 2023.08.01 |
---|---|
네트 처리 방법::jquery agax에서 ERR_CONNECTION_REFUSED가 발생했습니다. (0) | 2023.08.01 |
JTDS를 사용하여 Spring Boot에서 HikariCP 구성 (0) | 2023.08.01 |
jQuery 요소 내에서 마우스 위치 가져오기 (0) | 2023.08.01 |
indexPath별로 적합한 ViewCell을 얻으려면 어떻게 해야 합니까? (0) | 2023.08.01 |