How to run a cron job inside a docker container
LinuxDockerCronLinux Problem Overview
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
.
Linux Solutions
Solution 1 - Linux
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.
Solution 2 - Linux
crond works well with [tiny][1] 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][2] and [this blog post][3] for details.
[1]: https://github.com/krallin/tini "tiny" [2]: https://github.com/moby/moby/pull/26061 "Add init process for zombie fighting and signal handling #26061" [3]: https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/ "Docker and the PID 1 zombie reaping problem"
Solution 3 - Linux
@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
...
Solution 4 - Linux
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']