Run a cron job with Docker

| 37 Comments | 2 minutes read

ContainersAt ekito, we adopted Docker as lightweight virtualization solution to deploy our internal servers, as well as deliver “ready to run” applications to our customers.

Bert has already published an excellent article on Docker, one year ago. Since then, we continued to experiment on this topic and I would like to present a very simple (but not trivial) use case:
run a cron job in a docker container.

The source code is available on github.

Install docker

Depending on your platform, you can find the complete documentation on the docker website.

The cron job

We will create a cron job that will display “Hello world”, every minute, in the console

Let’s create a new file called “crontab” to describe our job.

* * * * * root 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.

This job will echo “Hello world”, every minutes, and redirect the output in the file /var/log/cron.log

Important remarks:

  • a blank line is required at the end of this file!
  • the job is run by the “root” user as it is the only user that will exist in the container

The docker image

The following DockerFile describes all the steps to build your image

FROM ubuntu:latest
# Add crontab file in the cron directory
ADD crontab /etc/cron.d/hello-cron
# Give execution rights on the cron job
RUN chmod 0644 /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

Then you can build the image with

sudo docker build --rm -t ekito/cron-example .

And run it:

sudo docker run -t -i ekito/cron-example

Be patient, wait for 2 minutes and your commandline should display:

Hello world
Hello world

Now you can create you own script to backup you data, check your system status, or whatever you want !

Julien Boulay Author: Julien Boulay

Eclectic developer & architect
Activist for usability, performance and interoperability of systems.

My favorite quote : "The best feature is the one we don't need to develop !"

My hashtags : #windchill #java #talend #nodejs #angularjs #oss #docker

Like it?  Share  it!

Share Button


  1. Pingback: Run cron in centOS as user process, not daemon | DL-UAT

  2. Pingback: Run cron in centOS as user process, not daemon | You need? We have! Everything

  3. To use this in production, you probably want cron to run in the forground like this:

    CMD [“cron”, “-f”]

  4. Um… this doesn’t work. I waited for 5 minutes and nothing is displayed. How can I debug this?

    • Julien Boulay

      Hi Austin,

      Thanks for your interest on this post.

      To debug this, you can enter the container : while the docker container is running in one terminal, open a new terminal and type :
      `sudo docker exec -it your_container_name /bin/bash`

      Then you should see something like :

      You are now connected inside the container. You can edit the cron configuration, restart the service and check the logs.

      Exemple : check if your cron process is running :
      `ps -ef |grep cron`
      There should be one process like
      `root 1 0 0 20:38 ? 00:00:00 /bin/sh -c cron && tail -f /var/log/cron.log`

      Please give me your feedback if I miss something in this post.

    • try putting

      RUN /usr/bin/crontab /etc/cron.d/hello-cron

  5. Nice article! Thx

  6. Nice article but the use case is quite dummy. Would be much better to have an example of cron job executed for a different container than cron container.

    • Julien Boulay

      Hi jangorecki,

      Thanks for your comment. You’re right, it is a very simple use case. But usually, it is recommended to execute only one process by container. We could imagine run a cron in one container, that will access a shared volume…
      The idea was to keep the article as simple as possible to illustrate the usage and debugging of a cron.

  7. Hi,

    I try to get it working on a centos 7 httpd container. The daemon crond doesn’t start. Is someone have successfully startup cron in a container that already run another daemon (like httpd) ?

    I tried with RUN/CMD crond before the startup CMD for httpd, but it’s not working. I suppose that it is not possible to start multiple daemon in the same container ? if I just try to start the crond daemon without httpd, it works.

  8. Thanks for this, however, you should be aware that cron can’t access any environment variables you pass into the container… making life pretty difficult if you’re running commands for an app that may require stuff.

  9. Nice article!. Thanks. Specially the commented line help me a lot
    # An empty line is required at the end of this file for a valid cron file.

  10. Pingback: 使用Docker Compose管理Docker容器 | 勇气

  11. do you know as run the cron in another’s containers simultaneously? For example, if i have three containers, configure crontab for all. I’m trying, but not work, the cron, only run in one container. I using the next method:

    crontab -e

    and put: */2 * * * * export PATH=”/root/driver:$PATH” && cd /root/file && /usr/bin/ruby /root/file/file.rb


  12. Hi Julien!

    It’s worth noting, that:

    1. It would be better to mount the ‘crontab’ file straight from your project directory, to keep it up to date on every container startup.

    2. You should rather mount a separate volume for logs from the host machine, to keep your logs outside the container OR create fifo file for logs.

    • Julien Boulay

      Hi Dimitri,

      Thank you very much for your remarks. You are right, it would be much better to mount external file systems to control crontab and logs files.
      I will test it and update my post soon with external directories.

  13. I created a similar image but all bases on env vars , no config files to mount.

    let me know what you think

  14. Thank you for this article Julien. Cannot get it to work with a container using python:2.7 image. I see the cron -f process running, and my cron job is in the /etc/cron.d/hello-cron, but I’m getting no cron jobs auto firing after 5 minutes of waiting.

    Any help would be appreciated as I’ve been messing with this for too many hours.

    • Julien Boulay

      Hi Eric,

      Thanks for your comment.
      Don’t you miss to add a blank line to the end of the cron file ?
      What is the OS of your base image ? Ubuntu, CentOS, … ?
      Could you please give me more details about your implementation, or push a sample of the project on a github repo ?

  15. Pingback: Gestione multidominio con Docker - Ajenti-V - Letsencrypt » m4-Web

  16. For those having trouble, I solved issues (below). I assume you’re using “FROM ubuntu:latest” for the current LTS. I suspect some things changed in the base image since the time this was written.

    (Use whatever you want of course, but I strongly suggest deferring experimentation with non-Ubuntu base… get the basics working first)

    Problem: missing ‘crontab’ file
    “`Step 6/7 : RUN /usr/bin/crontab /etc/cron.d/hello-cron
    —> Running in 19b11a035f00
    /bin/sh: 1: /usr/bin/crontab: not found“`

    Solution: add:
    “`RUN apt-get update && apt-get install -y cron“`

    “`# /bin/sh: 1: root: not found“`

    Solution: remove ‘root’ from column 6 of the cron file. The command will be implicitly run as root and column 6 should contain the command.

    Problem: nothing output
    Also add:
    RUN /usr/bin/crontab /etc/cron.d/hello-cron
    (leave in the CMD cron && tail -f /var/log/cron.log)

    Other suggestions:
    If you’re having trouble differentiating images and instances because you are new, edit the cron file to say “Hello world2” etc., because nothing’s worse than making changes and not seeing them work as expected because the wrong thing is executed.. 🙂

    • Hello,

      I seems to be one of those having troubles and need help since after many and many tries I am unable to have the cronjob running correctly..


      FROM ubuntu:latest

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

      # Create the log file to be able to run tail
      RUN touch /var/log/cron.log

      # Add crontab file in the cron directory
      ADD crontab /etc/cron.d/hello-cron

      # Give execution rights on the cron job
      RUN chmod 0644 /etc/cron.d/hello-cron

      RUN /usr/bin/crontab /etc/cron.d/hello-cron

      # Setup cron job
      #RUN (crontab -l ; echo “* * * * * echo “Hello world” >> /var/log/cron.log”) | crontab

      # Run the command on container startup
      #CMD [“cron”, “-f”]
      CMD cron && tail -f /var/log/cron.log

      crontab file
      * * * * * root echo Hello worldxxxxxx >> /var/log/cron.log 2>&1
      # empty line

      I log in the container and drun the following commands to check things:

      ps -ef |grep cron
      root 1 0 0 13:37 ? 00:00:00 /bin/sh -c cron && tail -f /var/log/cron.log
      root 6 1 0 13:37 ? 00:00:00 cron
      root 7 1 0 13:37 ? 00:00:00 tail -f /var/log/cron.log
      root 17 8 0 13:37 ? 00:00:00 grep –color=auto cron

      bash -c “crontab -l”
      * * * * * root echo Hello worldxxxxxx >> /var/log/cron.log 2>&1

      bash -c “pgrep cron”

      I wait to see if “Hello worldxxxxxx” start to display but it doesn’t; if I do
      cat /var/log/cron.log nothing output because file is 0 bytes

      Thanks in advance for any possible suggestion

      • Julien Boulay

        Hi Emi,

        Did you try to clone the github repository and run the given example ?
        I just did it to verify that `ubuntu:latest` didn’t change the behaviour of the container and it works for me.

        • Salut Julien,

          thank you for your kind reply

          I have tried one more time and can confirm that cloning from the git repo is working fine as you stated!

          I am going to review what mistake I’ve done trying to implement it with other containers in docker-compose and with a replica of your Dockerfile

          Perhaps I was checking in the wrong place to see the Hello World print out..

          Thank you again

  17. Pingback: Docker and Time based Jobs – Phil Schatzmann Consulting

  18. Pingback: SummerEye part11 -cron設定- | fukuの犬小屋

What do  You  think? Write a comment!

Leave a Reply

Required fields are marked *.

CommentLuv badge