Crontab in docker container
Few days ago i was struggling with similar problem and here are few notes based on what i have learnt first:
To be able to run a container like a service, somewhere (in cmd or entrypoint) must be a foreground program running. For your case it would be
nginx -g daemon off;
(from nginx image).Also if there is an entrypoint and a cmd, they are launched in the way that the cmd is passed to the entrypoint as the argument (just like
./entrypoint.sh [cmd]
)There is no point of having
RUN /etc/init.d/cron start
since after the image is built, it will be terminated anyway.
And to the solution: It was using entrypoint.sh similar to this one (in my case django/gunicorn/cron):
#!/bin/bash
set -e # exit on any error
if [ "$1" = './gunicorn.sh' ]; then # './gunicorn.sh' is default command
cron # this runs cron as daemon
crontab -u django /app/crontab # this applies a crontab from a file
exec su django -c "$@" # this actually runs the default command as different user (you can just use exec "$@" if you dont need to run it as different user)
fi
exec "$@" # this runs any other cmd without starting cron (e.g. docker run -ti myimage /bin/bash)
Related videos on Youtube
Kevin
Updated on September 18, 2022Comments
-
Kevin over 1 year
Hi I'm trying to run a cron job in a docker container. So I have added that in my
Dockerfile
My
Dockerfile
FROM nginx:stable RUN apt-get update -y && apt-get upgrade -y && apt-get install -y \ vim \ git \ curl \ wget \ certbot \ cron COPY cron/crontab /etc/crontab RUN chmod 0644 /etc/cron.d/crontab RUN /etc/init.d/cron start
My
crontab
file# /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file # and files in /etc/cron.d. These files also have username fields, # that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command */1 * * * * root echo "test" >>~/readme
But it does not work.
I have to run the command
/etc/init.d/cron start
manually in my nginx container if I want it to work.So I have added an entrypoint in my
Dockerfile
, so this command can be executed when the container start.# ENTRYPOINT ADD entrypoint.sh /entrypoint.sh RUN chmod 777 /entrypoint.sh
My
entrypoint.sh
#!/usr/bin/env bash /etc/init.d/cron start
My
docker-compose
entrypoint: /entrypoint.sh
But I have this error:
OCI runtime exec failed: exec failed: container_linux.go:296: starting container process caused "process_linux.go:86: executing setns process caused \"exit status 21\"": unknown
Did I miss something?
PS: I have followed this tutorial
-
jordanm about 6 yearsThat guide is really wrong. Starting a service at build time makes no sense. Someone points that out in the article comments and the author just responds with "Did you read the start of the article?" which is a recommendation of not actually using the tutorial....
-
jordanm about 6 yearsJust use something like this image: hub.docker.com/r/hamiltont/docker-cron
-
-
Alessio about 6 yearsNote: it's a fairly common recommendation to run cron jobs on the docker host instead of inside each container. I prefer not to do that, I prefer containers to be entirely self-contained and not require any special configuration on the host. IMO requiring special per-container configuration defeats a large part of the automation and ephemeral re-usability benefits provided by containerising tasks.
-
Kevin about 6 yearsI have already done
apt-get install cron
. I'm usingFROM nginx:stable
... When I exec in my container and doservice cron start
it works perfectly. But I need the cron service to start automatically when the container is created. But it does not work -
Alessio about 6 yearswhat's
nginx:stable
based on? where did it come from? github.com/nginxinc/docker-nginx ? (there are alpine and debian stretch based versions there). somewhere else? -
Kevin about 6 yearsIt's the official stable version of nginx on docker hub, github.com/nginxinc/docker-nginx/blob/… .
-
Alessio about 6 yearsOK, according to the Dockerfile, that's based on Debian stretch. It already has
CMD ["nginx", "-g", "daemon off;"]
and I can't recall if you can run multiple commands withCMD
or not. Maybe try something likeCMD ["cron;", "nginx", "-g", "daemon off;"]
. If that doesn't work, create a script that runscron
and thennginx -g daemon off
, COPY it to your container,RUN chmod +x path/to/your/script
, and addCMD /path/to/your/script
. -
Kevin about 6 yearsIt does not work. My container does not strat. When I'm checking my nginx container logs, I have this message:
Starting periodic command scheduler: cron
. I have try your 2 solutions -
Zach Smith about 5 yearsI have the case where a process creates a large number of temporary files. These files need to be kept for a week or so, so I would like a cronjob running inside the container to delete them these files if the container isn't recreated during that time. Is this a good use case for a cron job inside a docker container?