Running a Cron Job in Docker Container

protecting sensitive data in docker
Reading Time: 3 minutes

Setting up a cron job within a docker container might not sound new to many of us. But depending upon the base image that we use to build the docker image we might end up struggling with different issues.

Cron Job integration with docker

In this blog, I will walk you through the different challenges that I dealt with while setting up a cron using bash in a docker container.

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 .
But what if Docker container runs with a command? The default command will be ignored, and the cron will not start in that case.
Also, what if you have other jobs as well to start once on the docker startup? And some other job that you would want to run periodically in the same container? Moreover, how about using System’s environment variable in the cron job?
Following are my findings to all the questions above.

Setup a cron in parallel to a one-time job.

Create a script file, say run.sh, with the job that is supposed to run periodically.

#!/bin/bash
timestamp=`date +%Y/%m/%d-%H:%M:%S`
echo "System path is $PATH at $timestamp"
view raw run.sh hosted with ❤ by GitHub

Save and exit.

Use Entrypoint instead of CMD

If you have multiple jobs to kick in during docker containerization, use the entrypoint file to run them all.

Entrypoint file is a script file that comes into action when a docker run command is issued. So, all the steps that we want to run can be put in this script file.

For instance, we have 2 jobs to run:

Run once job: echo “Docker container has been started”

Run periodic job: run.sh

Create entrypoint.sh

#!/bin/bash
# Start the run once job.
echo "Docker container has been started"
# Setup a cron schedule
echo "* * * * * /run.sh >> /var/log/cron.log 2>&1
# This extra line makes it a valid cron" > scheduler.txt
crontab scheduler.txt
cron -f
view raw entrypoint.sh hosted with ❤ by GitHub

Let’s understand the crontab that has been setup in the file

“* * * * *” : Cron schedule; the job must run every minute. You can update the schedule based on your requirement.

/run.sh: path to the script file which is to be run periodically

/var/log/cron.log: The filename to save the output of the scheduled cron job.

2>&1: The error logs(if any) also will be redirected to the same output file used above.

Note: Do not forget to add an extra new line, as it makes it a valid cron.

Scheduler.txt: the complete cron setup will be redirected to a file.

Using System/User specific environment variables in cron

My actual cron job was expecting most of the arguments as the environment variables passed to the docker run command. But, with bash, I was not able to use any of the environment variables that belongs to the system or the docker container.

Then, this came up as a walkaround to this problem:

  1. Add the following line in the entrypoint.sh
    declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env
  2. Update the cron setup and specify-
    SHELL=/bin/bash
    BASH_ENV=/container.env

At last, your entrypoint.sh should look like

#!/bin/bash
# Start the run once job.
echo "Docker container has been started"
declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env
# Setup a cron schedule
echo "SHELL=/bin/bash
BASH_ENV=/container.env
* * * * * /run.sh >> /var/log/cron.log 2>&1
# This extra line makes it a valid cron" > scheduler.txt
crontab scheduler.txt
cron -f
view raw entrypoint.sh hosted with ❤ by GitHub

Last but not the least: Create a Dockerfile

FROM ubuntu:16.04
MAINTAINER Neha Bhardwaj
# Install cron
RUN apt-get update && apt-get install -y cron
# Add files
ADD run.sh /run.sh
ADD entrypoint.sh /entrypoint.sh
RUN chmod +x /run.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh
view raw Dockerfile hosted with ❤ by GitHub

That’s it. Build and Run the Docker image!

You can get the complete code on github https://github.com/nehabhardwaj01/docker-cron. Follow the README.md to test the docker image.

For more in-depth detail about Docker and its components, take a look at Azmat Hasan’s article

Feel free to share your queries or thoughts in the comments section.
Happy reading!!

References
Image Source

Written by 

Neha is a Senior Software Consultant with an experience of more than 3 years. She is a Big data enthusiast and knows various programming languages including Scala and Java. She is always eager to learn new and advance concepts to expand her horizons and apply them in the project development.