I am trying to run a cronjob inside a docker container that invokes a shell script.
Yesterday I have been searching all over the web and stack overflow, but I could not really find a solution that works.
How can I do this?
EDIT:
I've created a (commented) github repository with a working docker cron container that invokes a shell script at given interval.
One way to create scheduled tasks for your containers is by using the host's crontab. Since the definition of each cron job allows you to execute commands, you can use Docker Engine in the same way you would the command line.
Using the Host's CrontabMake sure cron is installed and then edit the system's crontab as normal. Every five minutes, your system's cron installation will create a new Docker container using your app's image. Docker will execute the /example-scheduled-task.sh script within the container.
You can copy your crontab into an image, in order for the container launched from said image to run the job.
See "Run a cron job with Docker" from Julien Boulay in his Ekito/docker-cron
:
Let’s create a new file called "
hello-cron
" to describe our job.
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1 # An empty line is required at the end of this file for a valid cron file.
If you are wondering what is 2>&1, Ayman Hourieh explains.
The following Dockerfile describes all the steps to build your image
FROM ubuntu:latest MAINTAINER [email protected] RUN apt-get update && apt-get -y install cron # Copy hello-cron file to the cron.d directory COPY hello-cron /etc/cron.d/hello-cron # Give execution rights on the cron job RUN chmod 0644 /etc/cron.d/hello-cron # Apply cron job RUN crontab /etc/cron.d/hello-cron # Create the log file to be able to run tail RUN touch /var/log/cron.log # Run the command on container startup CMD cron && tail -f /var/log/cron.log
(see Gaafar's comment and How do I make apt-get
install less noisy?:apt-get -y install -qq --force-yes cron
can work too)
As noted by Nathan Lloyd in the comments:
Quick note about a gotcha:
If you're adding a script file and telling cron to run it, remember toRUN chmod 0744 /the_script
Cron fails silently if you forget.
OR, make sure your job itself redirect directly to stdout/stderr instead of a log file, as described in hugoShaka's answer:
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
Replace the last Dockerfile line with
CMD ["cron", "-f"]
See also (about cron -f
, which is to say cron "foreground") "docker ubuntu cron -f
is not working"
Build and run it:
sudo docker build --rm -t ekito/cron-example . sudo docker run -t -i ekito/cron-example
Be patient, wait for 2 minutes and your commandline should display:
Hello world Hello world
Eric adds in the comments:
Do note that
tail
may not display the correct file if it is created during image build.
If that is the case, you need to create or touch the file during container runtime in order for tail to pick up the correct file.
See "Output of tail -f
at the end of a docker CMD
is not showing".
See more in "Running Cron in Docker" (Apr. 2021) from Jason Kulatunga, as he commented below
See Jason's image AnalogJ/docker-cron
based on:
Dockerfile installing cronie
/crond
, depending on distribution.
an entrypoint initializing /etc/environment
and then calling
cron -f -l 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With