How to run cron job in docker container?
Asked Answered
O

3

10

I have a python script that populates Postgres database in AWS.

I am able to run it manually and it is loading data into database without any issues. I want to run it once for every 5 minutes inside a docker container.

So I included it in docker image to run. But I'm not sure why it's not running. I can't see anything appended to /var/log/cron.log file. Can someone help me figure out why it's not running?

I am able to copy the script to image during docker build and able to run it manually. The DB is being populated and I'm getting the expected output.

The script is in current directory which will be copied to /code/ folder

Here is my code:

Dockerfile:

FROM python:3
RUN apt-get -y update && apt-get -y upgrade
RUN apt-get install -y cron
RUN apt-get install -y postgresql-client
RUN touch /var/log/cron.log
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD . /code/
COPY crontab /etc/cron.d/cjob
RUN chmod 0644 /etc/cron.d/cjob
CMD cron && tail -f /var/log/cron.log

crontab:

*/5 * * * * python3 /code/populatePDBbackground.py >> /var/log/cron.log
# Empty line
Ox answered 11/3, 2019 at 6:36 Comment(8)
Possible duplicate of How to run a cron job inside a docker container?Frendel
I saw that question too. But it didn't help me out.Ox
Do you mean adding && tail -f /var/log/cron.log to your CMD cron not work?Frendel
No I didn't add the tail -f part. That is just for displaying the output of the file in docker container logs. We can get to see the content whenever we need using cat /var/log/cron.log . Correct me if I'm wrong. Is it mandatory to add tail ?Ox
that is not only for displaying the file in docker logs. docker need a foreground process. tail -f will follow the log file and stay in front. cron -f has the same effect.Frendel
yes. It didn't work even if I include tail -f /var/log/cron.logOx
Then I don't think it's a docker or cron issue. Have you confirmed that your script run correctly inside your container, cause that your Dockerfile does not include any command for installing dependencies, and which python package you're using for postgre is not clear.Frendel
I forgot to set the permissions properly. So chmod 0644 /etc/cron.d/cjob helped me outApraxia
M
23

Crontab requires additional field: user, who runs the command:

* * * * * root python3 /code/populatePDBbackground.py >> /var/log/cron.log
# Empty line

The Dockerfile is:

FROM python:3
RUN apt-get -y update && apt-get -y upgrade
RUN apt-get install -y cron postgresql-client
RUN touch /var/log/cron.log
RUN mkdir /code
WORKDIR /code
ADD . /code/
COPY crontab /etc/cron.d/cjob
RUN chmod 0644 /etc/cron.d/cjob
ENV PYTHONUNBUFFERED 1
CMD cron -f

Test python script populatePDBbackground.py is:

from datetime import datetime

print('Script has been started at {}'.format(datetime.now()))

And finally we get:

$ docker run -d b3fa191e8822
b8e768b4159637673f3dc4d1d91557b374670f4a46c921e0b02ea7028f40e105

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
b8e768b41596        b3fa191e8822        "/bin/sh -c 'cron -f'"   4 seconds ago       Up 3 seconds                            cocky_beaver

$ docker exec -ti b8e768b41596 bash
root@b8e768b41596:/code# tail -f /var/log/cron.log
Script has been started at 2019-03-13 00:06:01.095013
Script has been started at 2019-03-13 00:07:01.253030
Script has been started at 2019-03-13 00:08:01.273926
Marxmarxian answered 13/3, 2019 at 0:13 Comment(1)
thanks for this - I have been struggling with this for absolutely ages. it was the missing "root" as the user in the cron command - after that - everything worked.Sapling
E
1

Using traditional cron implementations under docker is tricky. Consider using supercronic:

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:

*/5 * * * * date
$ docker-compose up

More alternatives can be found in my other answer.

Exterminatory answered 5/2, 2023 at 17:39 Comment(2)
Would you mind elaborating why using standard cron is tricky?Pacifica
@Pacifica Traditionally cron reports failures by mail. Making the results available in docker logs is either impossible or hard, depending on the implementation.Exterminatory
C
0

This might not be directly related, but I was getting stuck with my cronjob running in a docker container. I tried the accepted answer with no luck. I finally discovered that the editor I was using to edit the Crontab file (Notepad++) was set to Windows line-endings (CR LF). Once I changed this to Unix line endings (LF) my cronjob ran successfully in my docker container.

Caviar answered 25/5, 2022 at 5:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.