Kevin Keane
Kevin Keane

Reputation: 1658

Cron containers for docker - how do they actually work?

I have been using docker for a couple of months now, and am working on dockerizing various different server images. One consistent issue is that many servers need to run cron jobs. There is a lot of discussion about that online (including on Stackoverflow), but I don't completely understand the mechanics of it.

Currently, I am using the host's cron and docker exec into each container to run a script. I created a convention about the script's name and location; all my containers have the same script. This avoids having the host's cron depending on the containers.

Basically, once a minute, the host's cron does this:

for each container
   docker exec -it <containername> /cronscript/minute-script

That works, but makes the containers depend on the host.

What I would like to do is create a cron container that kicks off a script within each of the other containers - but I am not aware of an equivalent to "docker exec" that works from one container to the other.

The specific situations I have right now are running a backup in a MySQL container, and running the cron jobs Moodle requires to be run every minute. Eventually, there will be additional things I need to do via cron. Moodle uses command-line PHP scripts.

What is the "proper" dockerized way to kick off a script from one container in another container?

Update: maybe it helps to mention my specific use cases, although there will be more as time goes on.

Currently, cron needs to do the following:

Upvotes: 10

Views: 4816

Answers (1)

Tomasz Jakub Rup
Tomasz Jakub Rup

Reputation: 10680

My solution is:

  • install crond inside container
  • install Your soft
  • run cron as a daemon
  • run Your soft

Part of my Dockerfile

FROM debian:jessie

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY .crontab /usr/src/app

# Set timezone
RUN echo "Europe/Warsaw" > /etc/timezone \
    && dpkg-reconfigure --frontend noninteractive tzdata

# Cron, mail
RUN set -x \
    && apt-get update \
    && apt-get install -y cron rsyslog mailutils --no-install-recommends \
    && rm -rf /var/lib/apt/lists/*

CMD rsyslogd && env > /tmp/crontab && cat .crontab >> /tmp/crontab && crontab /tmp/crontab && cron -f

Description

  1. Set timezone, because cron need this to proper run tasks
  2. Install cron package - package with cron daemon
  3. Install rsyslog package to log cron task output
  4. Install mailutils package if You want to send e-mails from cron tasks
  5. Run rsyslogd
  6. Copy ENV variables to tmp file, because cron run tasks with minimal ENV and You tasks may need access to containers ENV variables
  7. Append Your .crontab file (with Your tasks) to tmp file
  8. Set root crontab from tmp file
  9. Run cron daemon

I use this in my containers and work very well.

one-process-per-container

If You like this paradigm, then make one Dockerfile per cron task. e.g.

  • Dockerfile - main program
  • Dockerfile_cron_task_1 - cron task 1
  • Dockerfile_cron_task_1 - cron task 2

and build all containers:

docker build -f Dockerfile_cron_task_1 ...

Upvotes: 12

Related Questions