Running Cron Tasks on Docker

Sometimes there cases when you just need to run a simple cron task. It is very important do not break stable things that you already have. So, let’s try to run a cronjob in a separate Docker container.

For this case, I have prepared an example how I run a simple MongoDB database backup task.

So, we need to install MongoDB Community Edition tools that we will help to make the backups or run any other tasks.

# Install required gnupg package
RUN apt-get update && apt-get -y install gnupg

# Install required ca-certificates to prevent the error in the certificate verification
RUN apt-get -y install ca-certificates && update-ca-certificates

# Import the public key used by the package management system
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4

# Create a list file for MongoDB
RUN echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list

# Reload local package database
RUN apt-get update

# Install the MongoDB packages
RUN apt-get -y install mongodb-org-tools

After that, we just need to set up a cron task and run the cron.

# Install Cron
RUN apt-get -y install cron

# Making the crontab file based on env vars and put to the cron directory
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

# Run the command on container startup
CMD ["cron", "-f"]

For this case, I have prepared an entry point script that will generate a crontab based on some environment variables.

#!/bin/sh
set -e

if ( [ -z "${MONGODB_USERNAME}" ] || [ -z "${MONGODB_PASSWORD}" ] );
then
  echo "$CRON_EXPRESSION \
  /usr/bin/mongodump \
  --host $MONGODB_HOST \
  --port $MONGODB_PORT \
  --db $MONGODB_DATABASE \
  --gzip \
  --archive=$DESTINATION_PATH/"'$(date +"\%m_\%d_\%Y-\%H:\%M")'".gz \
  > /proc/1/fd/1 2>/proc/1/fd/2" > crontab
else
  echo "$CRON_EXPRESSION \
  /usr/bin/mongodump \
  --host $MONGODB_HOST \
  --port $MONGODB_PORT \
  --db $MONGODB_DATABASE \
  --username $MONGODB_USERNAME \
  --password $MONGODB_PASSWORD \
  --authenticationDatabase $MONGODB_AUTH_DATABASE \
  --gzip \
  --archive=$DESTINATION_PATH/"'$(date +"\%m_\%d_\%Y-\%H:\%M")'".gz \
  > /proc/1/fd/1 2>/proc/1/fd/2" > crontab
fi

mv crontab /etc/cron.d/crontab

chmod 0644 /etc/cron.d/crontab

/usr/bin/crontab /etc/cron.d/crontab

exec "[email protected]"

Let’s check the results.

docker-compose build
docker-compose up -d

# for testing I run the cron task every minute, so just wait a minute
...

docker logs mongo-cron-backup

MongoDB Cron Backup Task Results

This solution based on a simple dockerized cron solution that I have made before. In some cases, you may use Alpine or Ubuntu version.

Also, check the https://crontab.guru to find more crontab expressions.