0

On an ubuntu machine, I have a crontab that I am setting up with a Dockerfile:

...

RUN apt-get update && apt-get install -y cron

...

ADD crontab /etc/cron.d/crontab

RUN chmod 0644 /etc/cron.d/crontab

RUN systemctl enable cron

RUN touch /etc/cron.d/crontab

crontab:

15 17 * * * root /home/misc/runSomething.sh

It is not firing on schedule after the container is created, however if I manually edit the file with vi to test it, it works afterwards. Its not until it gets edited that it seems to be picked up. Does anyone have an idea regarding how to fix this?

Note that the ownership, etc doesn't see to be changing as a result of the edit:

root@machine:/home/gradle/src# ls -la /etc/cron.d
...
-rw-r--r-- 1 root root  50 Feb  3 14:55 crontab
...
root@machine:/home/gradle/src# vi /etc/cron.d/crontab
...
root@machine:/home/gradle/src# ls -la /etc/cron.d
...
-rw-r--r-- 1 root root  51 Feb  3 15:42 crontab

chrismead
  • 2,163
  • 3
  • 24
  • 36
  • Running `systemctl enable cron` in a Dockerfile typically won't accomplish anything useful (because `systemd` is probably not configured to start when the container starts). Can you show us your complete Dockerfile? – larsks Feb 03 '21 at 17:51
  • Thanks, @larsks... I have removed it and retested with the fix I will describe in an answer below and it is working. Essentially, the rest of the dockerfile was little other than apt-get calls and cert installation – chrismead Feb 03 '21 at 19:07

2 Answers2

0

A common best practice is to have 1 process per your container. It's much easier to organize a graceful shutdown of the container in case of errors, etc. for the single process within the container.

In case if you are adding the cron you'll have at least 2 processes, therefore:

  1. Do you really need a cron process inside of your app? For example, you can access your container on regular basis from outside using docker exec -it <yourcontainer> <required-command>
  2. Make sure that cron process is started with your app during startup, thus you may use something like
    ENTRYPOINT cron && yourapp
    CMD cron && yourapp
    

As I understood RUN command just modifies the filesystem layer, however, it doesn't start the background processes and so on.

lazylead
  • 1,453
  • 1
  • 14
  • 26
  • Since a common best practice is to have 1 process per container, it's usually better to do something like `CMD cron -f` to run a foreground cron process as the only process in its container, or to `docker run your-image cron -f` to specify an alternate command at startup time. – David Maze Feb 03 '21 at 18:19
  • Agreed. I do have cron && gradle bootrun as my command and I know its not best practice. It is only temporary, though. I am simply externalizing some functionality that was handled in a thread using @Scheduled in a Spring Boot app. I will be taking cron out and having another container make these calls soonish, but just wanted a workaround in the meantime. – chrismead Feb 03 '21 at 19:13
0

I don't know how to make files in /etc/cron.d work properly with docker, but I did find a workaround that I will share for others. I will leave my answer as unaccepted in case someone does know how to use /etc/cron.d files with docker.

I noticed in this post How to run a cron job inside a docker container this line:

... 
the files under /etc/cron.d/ are read and interpreted by cron as soon as edited
...

This made me think what I was up against was intended functionality.

I then modified my search accordingly and found this: How to run a cron job inside a docker container

So I modified my dockerfile to set up the crontab like this:

ADD crontab /home/gradle/src/crontab

RUN /usr/bin/crontab /home/gradle/src/crontab

This is easier and works. Note that as @larsks mentioned "systemctl enable cron" was not needed.

I agree with @DavidMaze and @lazyhead that I shouldn't be doing "cron && gradle bootrun" as my command but it is just a temporary situation. cron will eventually come out the command for this container.

chrismead
  • 2,163
  • 3
  • 24
  • 36