How to run a cron job inside a docker container?

docker cron best practice
docker-compose cron
docker run cron in background
cron job to restart docker container
cron not running in docker container
docker cron image
django crontab docker
docker php-cron

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.


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.

The following Dockerfile describes all the steps to build your image

FROM ubuntu:latest
MAINTAINER docker@ekito.fr

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 to RUN 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".

Running a Cron Job in Docker Container, In this blog, we'll see how to set up a cron in Docker container using bash. Also, we will explore how to use Environment variables in this setup. FROM ubuntu:latest # Install cron RUN apt-get -y install cron # Create the log file to be able to run tail RUN touch /var/log/cron.log # Setup cron job RUN (crontab -l ; echo "* * * * * echo "Hello world" >> /var/log/cron.log") | crontab # Run the command on container startup CMD cron && tail -f /var/log/cron.log After running your docker container, you can make sure if cron service is working by:


The adopted solution may be dangerous in a production environment.

In docker you should only execute one process per container because if you don't, the process that forked and went background is not monitored and may stop without you knowing it.

When you use CMD cron && tail -f /var/log/cron.log the cron process basically fork in order to execute cron in background, the main process exits and let you execute tailf in foreground. The background cron process could stop or fail you won't notice, your container will still run silently and your orchestration tool will not restart it.

You can avoid such a thing by redirecting directly the cron's commands output into your docker stdout and stderr which are located respectively in /proc/1/fd/1 and /proc/1/fd/2.

Using basic shell redirects you may want to do something like this :

* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2

And your CMD will be : CMD ["cron", "-f"]

How to Run Cron Jobs inside Docker Containers, You are way better off running Docker cron jobs from your host system, not from inside your Docker containers. Your Docker containers should  FROM ubuntu:latest # Install cron RUN apt-get -y install cron # Create the log file to be able to run tail RUN touch /var/log/cron.log # Setup cron job RUN (crontab -l ; echo "* * * * * echo "Hello world" >> /var/log/cron.log") | crontab # Run the command on container startup CMD cron && tail -f /var/log/cron.log.


For those who wants to use a simple and lightweight image:

FROM alpine:3.6

# copy crontabs for root user
COPY config/cronjobs /etc/crontabs/root

# start crond with log level 8 in foreground, output to stderr
CMD ["crond", "-f", "-d", "8"]

Where cronjobs is the file that contains your cronjobs, in this form:

* * * * * echo "hello stackoverflow" >> /test_file 2>&1
# remember to end this file with an empty new line

How to run a cron job inside a Docker container, I would like to give an example of how I created a cron job so that you can implement your own. To run cron container first create the following  How to run a cron job inside a docker container? My container have only cron.daily and cron.weekly file and crontab,cron.d, cron.hourly are absent in my container My container runs with /bin/bash.Any help?


What @VonC has suggested is nice but I prefer doing all cron job configuration in one line. This would avoid cross platform issues like cronjob location and you don't need a separate cron file.

FROM ubuntu:latest

# Install cron
RUN apt-get -y install cron

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

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

# Run the command on container startup
CMD cron && tail -f /var/log/cron.log

After running your docker container, you can make sure if cron service is working by:

# To check if the job is scheduled
docker exec -ti <your-container-id> bash -c "crontab -l"
# To check if the cron service is running
docker exec -ti <your-container-id> bash -c "pgrep cron"

If you prefer to have ENTRYPOINT instead of CMD, then you can substitute the CMD above with

ENTRYPOINT cron start && tail -f /var/log/cron.log

Docker Tip #40: Running Cron Jobs on the Host vs. in a Container , We have a couple of options here to run an automated task on a schedule: Use the Docker host's version of cron; Create a new container and run  Run the cron jobs directly on the host machine From any host machine that is running a Docker container, you can get terminal access into the running container. It's comparable to getting an ssh connection going to a remote server. For example, if my Docker container is called app_container_1:


There is another way to do it, is to use Tasker, a task runner that has cron (a scheduler) support.

Why ? Sometimes to run a cron job, you have to mix, your base image (python, java, nodejs, ruby) with the crond. That means another image to maintain. Tasker avoid that by decoupling the crond and you container. You can just focus on the image that you want to execute your commands, and configure Tasker to use it.

Here an docker-compose.yml file, that will run some tasks for you

version: "2"

services:
    tasker:
        image: strm/tasker
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
        environment:
            configuration: |
                logging:
                    level:
                        ROOT: WARN
                        org.springframework.web: WARN
                        sh.strm: DEBUG
                schedule:
                    - every: minute
                      task: hello
                    - every: minute
                      task: helloFromPython
                    - every: minute
                      task: helloFromNode
                tasks:
                    docker:
                        - name: hello
                          image: debian:jessie
                          script:
                              - echo Hello world from Tasker
                        - name: helloFromPython
                          image: python:3-slim
                          script:
                              - python -c 'print("Hello world from python")'
                        - name: helloFromNode
                          image: node:8
                          script:
                              - node -e 'console.log("Hello from node")'

There are 3 tasks there, all of them will run every minute (every: minute), and each of them will execute the script code, inside the image defined in image section.

Just run docker-compose up, and see it working. Here is the Tasker repo with the full documentation:

http://github.com/opsxcq/tasker

How do I run a cron job inside a docker container, Running a cron job from inside a container is not recommended. A better option is to run it from the host itself. answered May 7, 2019  The procedure consists in building an image that contains cron and that runs the cron daemon in foreground. If we want to use the standard pattern of configuring the application that runs in a container with environment variables, and assuming that the "application" is the job that is periodically run by cron, we need to launch cron with a script that collects required environment variables and places them in /etc/crontab, to be made available to the job.


Ekito/docker-cron: An example of running cron job in a , An example of running cron job in a docker container - Ekito/docker-cron. You are way better off running Docker cron jobs from your host system, not from inside your Docker containers. Your Docker containers should only have one concern only, and not be saddled with the


Definitive guide on how to setup up and running cron jobs in docker , Running cron jobs in docker containers will lead you to some very common problems, and sometimes without any errors or logs. Let's see all  Recently I came across a scenario where the requirement was to set up a cron job within a docker container. While surfing for the relevant content across the internet, all I could find was to run one liner echo commands within docker using the command CMD cron -f .


willfarrell/crontab, Run command on a instances of a scaled container using project . Ability to trigger scripts in other containers on completion cron job using trigger . That is all for our Dockerfile. Now we need to create a directory services.d in the same directory as the Dockefile. Inside the services.d directory, create two directories named cron and nginx. Inside them, create a file named run and finish. This is how the entire thing looks like.