How to run a cron job inside a docker container?
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?
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.
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 email@example.com 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_scriptCron 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
tailmay 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
stderrwhich are located respectively in
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.
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
docker-compose up, and see it working. Here is the Tasker repo with the full documentation:
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.