简体   繁体   中英

How to run a cron job inside a docker container

I tried to run a cron job inside a docker container but nothing works for me.
My container has only cron.daily and cron.weekly files.
crontab,cron.d,cron.hourly are absent in my container.
crontab -e is also not working.
My container runs with /bin/bash .

Here is how I run one of my cron containers.

Dockerfile:

FROM alpine:3.3

ADD crontab.txt /crontab.txt
ADD script.sh /script.sh
COPY entry.sh /entry.sh
RUN chmod 755 /script.sh /entry.sh
RUN /usr/bin/crontab /crontab.txt

CMD ["/entry.sh"]

crontab.txt

*/30 * * * * /script.sh >> /var/log/script.log

entry.sh

#!/bin/sh

# start cron
/usr/sbin/crond -f -l 8

script.sh

#!/bin/sh

# code goes here.
echo "This is a script, run by cron!"

Build like so

docker build -t mycron .

Run like so

docker run -d mycron

Add your own scripts and edit the crontab.txt and just build the image and run. Since it is based on alpine, the image is super small.

thanks for this template.

I only wonder about one line in entry.sh

/usr/sbin/crond -f -L 8

crond -help yields:

Usage: crond -fbS -l N -d N -L LOGFILE -c DIR

        -f      Foreground
        -b      Background (default)
        -S      Log to syslog (default)
        -l N    Set log level. Most verbose:0, default:8
        -d N    Set log level, log to stderr
        -L FILE Log to FILE
        -c DIR  Cron dir. Default:/var/spool/cron/crontabs

so maybe you wanted to rather put the small l

/usr/sbin/crond -f -l 8

istead of the big 'L'

/usr/sbin/crond -f -L 8

to set the log level to default, because specifying an logfile called 8 does not seem to be intended.

crond works well with tiny on Alpine

RUN apk add --no-cache tini

ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/usr/sbin/crond", "-f"]

but should not be run as container main process (PID 1) because of zombie reaping problem and issues with signal handling. See this Docker PR and this blog post for details.

@ken-cochrane's solution is probably the best, however, there is also a way to do it without needing to create extra files.

To do it without extra files:

The way to go is to set the cron within your entrypoint.sh file.

Dockerfile


...

# Your Dockerfile above


COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

entrypoint.sh


echo "* * * * * echo 'I love running my crons'" >> /etc/crontabs/root
crond -l 2 -f > /dev/stdout 2> /dev/stderr &

# You can put the rest of your entrypoint.sh below this line

...

FROM alpine:latest

RUN touch crontab.tmp \
    && echo '* * * * * echo "123"' > crontab.tmp \
    && crontab crontab.tmp \
    && rm -rf crontab.tmp

CMD ["/usr/sbin/crond", "-f", "-d", "0"]

ref:https://gist.github.com/mhubig/a01276e17496e9fd6648cf426d9ceeec

Here is good explanation of cron problems inside docker container:

Docker file example:

FROM alpine

# Copy script which should be run
COPY ./myawesomescript /usr/local/bin/myawesomescript
# Run the cron every minute
RUN echo '*  *  *  *  *    /usr/local/bin/myawesomescript' > /etc/crontabs/root

CMD ['crond', '-l 2', '-f']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM