Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

cron - Trying to run a simple docker container with a crontab and a simple python script

So I am pretty new into creating containers and I have the simple Dockerfile where I would like to run a simple python script every minute:

FROM python:3.8-buster
RUN apt-get update && apt-get install -y cron
COPY my_python /bin/my_python
COPY root /var/spool/cron/crontabs/root
RUN chmod +x /bin/my_python
CMD cron -l 2 -f

where my_python:

print("hi world!!")

and root:

* * * * * python3 /bin/my_python

then I just create the image and the container:

 docker image build -t python-test
 docker container run -it --name python-test python-test

I was supposed to see every minute a print with the hi world, however when running the container ( after the image build) no logs seem to appear.

What am i doing wrong?

question from:https://stackoverflow.com/questions/65871983/trying-to-run-a-simple-docker-container-with-a-crontab-and-a-simple-python-scrip

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

First, I believe you want -L 2 rather than -l 2 in your cron command line; see the man page for details.

The cron daemon logs to syslog, so if something isn't work as intended, it's a good idea to arrange to receive those messages. The busybox tool provides a simple syslog daemon that can log to an in-memory buffer and a tool for reading those logs, so I modified your Dockerfile to look like this:

FROM python:3.8-buster
RUN apt-get update && apt-get install -y cron busybox
COPY my_python /bin/my_python
COPY root /var/spool/cron/crontabs/root
RUN chmod +x /bin/my_python
CMD busybox syslogd -C; cron -L 2 -f

After starting this, I docker exec'd into the container and ran busybox logread and found:

Jan 24 16:50:45 7f516db86417 cron.info cron[4]: (CRON) INFO (pidfile fd = 3)
Jan 24 16:50:45 7f516db86417 cron.info cron[4]: (root) INSECURE MODE (mode 0600 expected) (crontabs/root)
Jan 24 16:50:45 7f516db86417 cron.info cron[4]: (CRON) INFO (Running @reboot jobs)

So there's your problem: the permissions on the root crontab are incorrect. There are two ways to fix this problem:

  1. We could explicitly chmod the file when we copy it into place, or
  2. We can use the crontab command to install the file, which takes care of that for us

I like option 2 because it means we don't need to know the specifics of what cron expects in terms of permissions. That gets us:

FROM python:3.8-buster
RUN apt-get update && apt-get install -y cron busybox
COPY my_python /bin/my_python
COPY root /tmp/root.crontab
RUN crontab /tmp/root.crontab
RUN chmod +x /bin/my_python
CMD busybox syslogd -C; cron -L 2 -f

With that change, we can confirm that the cron job is now running as expected:

Jan 24 16:59:50 8aa688ad31cc syslog.info syslogd started: BusyBox v1.30.1
Jan 24 16:59:50 8aa688ad31cc cron.info cron[4]: (CRON) INFO (pidfile fd = 3)
Jan 24 16:59:50 8aa688ad31cc cron.info cron[4]: (CRON) INFO (Running @reboot jobs)
Jan 24 17:00:01 8aa688ad31cc authpriv.err CRON[7]: pam_env(cron:session): Unable to open env file: /etc/default/locale: No such file or directory
Jan 24 17:00:01 8aa688ad31cc authpriv.info CRON[7]: pam_unix(cron:session): session opened for user root by (uid=0)
Jan 24 17:00:02 8aa688ad31cc cron.info CRON[7]: (root) END (python3 /bin/my_python)
Jan 24 17:00:02 8aa688ad31cc authpriv.info CRON[7]: pam_unix(cron:session): session closed for user root

But...there's still no output from the container! If you read through that man page, you'll find this:

cron then wakes up every minute, examining all stored crontabs, checking each command to see if it should be run in the current minute. When executing commands, any output is mailed to the owner of the crontab (or to the user named in the MAILTO environment variable in the crontab, if such exists)...

In other words, cron collects the output from programs and attempts to mail to the user who owns the cron job. If you want to see the output from the cron job on the console, you will need to explicitly redirect stdout, like this:

* * * * * python3 /bin/my_python > /dev/console

With this change in place, running the image results in the message...

hi world!

...printing to the console once a minute.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...