Docker 컨테이너에서 정기적으로 작업을 실행하는 방법은 크게 두 가지가 있다.
docker exec 명령어 실행컨테이너가 외부 환경에 의존하지 않도록 하기 위해 두 번째 방식을 선택하여 구현해보았다.
다음 Dockerfile을 사용하여 cron을 설치하고 원하는 작업을 등록할 수 있다.
FROM ubuntu:24.04
RUN apt update && apt install -y cron &&\
(crontab -l 2>/dev/null; echo "0 * * * * /usr/bin/node /app/test.js") | crontab -
CMD ["sh", "-c", "printenv > /etc/environment && cron -f"]
apt install cron으로 cron 패키지 설치crontab -l 2>/dev/null을 사용해 기존 cron job을 가져옴2>/dev/null로 기존 job이 없을 경우 에러 메시지 출력 방지echo 명령어로 원하는 cron job 추가2>&1을 사용해 stderr을 stdout으로 리다이렉트하여 로그에 저장 가능cron -f 명령으로 cron을 foreground에 실행printenv > /etc/environment 으로 cron에서 명령 실행시 환경변수를 읽을 수 읽도록 설정docker-compose.yml에서 build-time 환경 변수를 설정하고, Dockerfile에서 이를 cron job에 적용할 수 있다.
docker-compose.ymlservices:
s-name:
build:
context: .
args:
YOUR_ENV_NAME1: 0 * * * *
YOUR_ENV_NAME2: ${env2}
dockerfile: Dockerfile
DockerfileFROM ubuntu:24.04
ARG YOUR_ENV_NAME1
ARG YOUR_ENV_NAME2
RUN apt update && apt install -y cron &&\
(crontab -l 2>/dev/null; echo "$YOUR_ENV_NAME1 /usr/bin/node /app/test1.js") | crontab - &&\
(crontab -l 2>/dev/null; echo "$YOUR_ENV_NAME2 /usr/bin/node /app/test2.js >> /app/uploader.log 2>&1") | crontab -
CMD ["sh", "-c", "printenv > /etc/environment && cron -f"]
docker-compose.yml에서 build-args를 사용해 환경 변수 전달.env 파일을 사용하는 경우, ${} 문법으로 변수를 참조 가능Dockerfile에서 ARG를 사용하여 환경 변수 선언$YOUR_ENV_NAME1처럼 환경 변수를 cron job 내에서 활용 가능https://wbarillon.medium.com/the-proper-and-easiest-way-to-set-cron-jobs-docker-version-1ef213578ad
해당 블로그에서 직접/var/spool/cron/에 있는 crontab 파일을 수정하는게 잘못된 방법이라고 함
crontab -u <username> /path/to/<file>으로 파일에 있는 cron job을 사용하라고 설명
나는 파일보다 직접 Dockerfile에 echo로 작성하도록 수정했음