I tried to run a cron job inside a docker container but nothing works for me.
My container has only cron.daily and cron.weekly files.
crontab,cron.d,cron.hourly are absent in my container.
crontab -e is also not working.
My container runs with /bin/bash.
Asked
Active
Viewed 6.9k times
55
Jonas
- 109,920
- 93
- 295
- 369
Manoj Kalluri
- 1,304
- 2
- 14
- 25
4 Answers
148
Here is how I run one of my cron containers.
Dockerfile:
FROM alpine:3.3
ADD crontab.txt /crontab.txt
ADD script.sh /script.sh
COPY entry.sh /entry.sh
RUN chmod 755 /script.sh /entry.sh
RUN /usr/bin/crontab /crontab.txt
CMD ["/entry.sh"]
crontab.txt
*/30 * * * * /script.sh >> /var/log/script.log
entry.sh
#!/bin/sh
# start cron
/usr/sbin/crond -f -l 8
script.sh
#!/bin/sh
# code goes here.
echo "This is a script, run by cron!"
Build like so
docker build -t mycron .
Run like so
docker run -d mycron
Add your own scripts and edit the crontab.txt and just build the image and run. Since it is based on alpine, the image is super small.
Ken Cochrane
- 72,249
- 9
- 48
- 58
-
1This is great. One problem I'm having is that after docker run ... I'm not able to stop the container running using ctrl-c? Even after I close the terminal, when I do docker ps I can see that the container is still up. Does anyone have the same problem? – ztech Apr 23 '18 at 18:19
-
@ztech did you try doing "docker stop
"? – Ken Cochrane Apr 24 '18 at 18:31 -
Yeah I had to use docker kill
. In retrospect it is most likely not a docker issue and some side effect of the scripts I was running using the crontab. I made a little different configuration of my scripts now and think this is a non-issue. – ztech Apr 24 '18 at 19:38 -
3Please add `RUN apk add --update apk-cron && rm -rf /var/cache/apk/*` to the answer for a full example. There are so many ways to add cron to alpine listed out there, and this one is the one that works with your example. – Fmstrat May 29 '18 at 15:05
-
3Hi, why there are 2 ADD and 1 COPY?, base on what I read seem like 3 COPY or 3 ADD would work fine(in this case). am I right? – NamNamNam Jan 26 '19 at 05:53
-
It's good to know that if you're just adding files to an image and changing entrypoint/command, it can all be done with configuration at container creation without building a new image. – Phil Jun 17 '19 at 07:45
-
It'd be nice if you didn't have to create a full container just for a simple cronjob. What would be a good way to *add a cronjob to a pre-existing container* instead of creating a new/separate container? – code_dredd Jun 19 '19 at 19:34
-
4`crond -f -l 8`, What does the 8 mean? According to man, the log level is with a capital `L`. – jcarlosweb Mar 19 '21 at 11:10
-
@jcarlisweb different versions of CRON have different flags. Some use upper case L for log file and lower case l for log level. See http://man.gnu.org.ua/manpage/?8+crond as an example. Pick what works for your version of CRON – Ken Cochrane Mar 20 '21 at 12:16
-
1I don't see crond running in the container as default. I had to exec and run crond which actually triggered the cron job. Is there something I'm missing here ? – Avi Apr 14 '21 at 23:12
11
crond works well with tiny on Alpine
RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/usr/sbin/crond", "-f"]
but should not be run as container main process (PID 1) because of zombie reaping problem and issues with signal handling. See this Docker PR and this blog post for details.
Jarek Przygódzki
- 4,114
- 2
- 29
- 40
5
@ken-cochrane's solution is probably the best, however, there is also a way to do it without needing to create extra files.
To do it without extra files:
The way to go is to set the cron within your entrypoint.sh file.
Dockerfile
...
# Your Dockerfile above
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh
echo "* * * * * echo 'I love running my crons'" >> /etc/crontabs/root
crond -l 2 -f > /dev/stdout 2> /dev/stderr &
# You can put the rest of your entrypoint.sh below this line
...
JesusIniesta
- 7,548
- 1
- 26
- 20
-
If you are using alpine linux without bash, don´t forget to add the following to the beggining of the sh file: `#!/bin/ash` – Daniel Miranda May 08 '22 at 04:15
-1
Here is good explanation of cron problems inside docker container:
Docker file example:
FROM alpine
# Copy script which should be run
COPY ./myawesomescript /usr/local/bin/myawesomescript
# Run the cron every minute
RUN echo '* * * * * /usr/local/bin/myawesomescript' > /etc/crontabs/root
CMD ['crond', '-l 2', '-f']
Janis Karklins
- 425
- 1
- 6
- 17
-
This approach doesn't work, as far as I'm concerned. I've tried a few variants too, and it seems like in the final container, changes made to `/etc/crontabs/root` aren't there. – JesusIniesta Aug 01 '21 at 17:35