drud.is

Docker scheduling made simple

I have a utility which I want to run within Docker periodically. The Docker container’s sole purpose is to run this utility, providing a controlled environment along with the necessary dependencies. The utility can be a shell script, python, a pre-compiled binary… anything.

The natural solution is to schedule a periodic docker run execution through crontab. I don’t like it for a few reasons:

Another obvious approach is to write a script like this,

#!/bin/sh
while true; do
    /my_script.sh
    sleep 900
done

but maybe we can avoid it.

I came up with a different idea. We can just use this entrypoint for the container:

watch -n 900 flock -n /tmp/my_script -c /my_script.sh

Let’s dissect what this entrypoint does:

If overlapping executions are not a concern, you can simply use watch -n 900 /my_script.sh.

Compared with the cons I had lined out:

My Dockerfiles look something like this:

FROM alpine:3.20
# 'watch' and 'flock' are already included in the base image, no need to install them
# build my_program
ENTRYPOINT ["watch", "-n", "900", "flock", "-n", "/tmp/my_program", "-c", "./my_program"]

Tip: I run a few like these and I name all these containers keep_{action}ing. It makes it easy to understand what they do and it’s a way to distinguish them at first glance from other fundamentally different containers I run.