Parth Shah
Parth Shah

Reputation: 874

cronjob is not running in Docker container throw Dockerfile

I have an issue when I run docker container the cronjob services are running but the cronjob is not executed as per schedule, I want to achieve is without attaching a volume

Dockerfile

FROM node:8.9.1         
RUN apt update && apt-get install -y cron vim
RUN mkdir app
WORKDIR /srv/image-server/current/
COPY . .
RUN  npm i 
RUN  cd /tmp && touch abc && mkdir test
ENTRYPOINT  sh start.sh

and also share the start.sh

#!/bin/sh
set -e
/etc/init.d/cron start
echo "* * * * * rm -rf /tmp/*" >> /var/spool/cron/crontabs/root
echo "#" >> /var/spool/cron/crontabs/root
/etc/init.d/cron status
node server.js

Upvotes: 3

Views: 1274

Answers (3)

Dhaval Shah
Dhaval Shah

Reputation: 143

It seems the log file is not getting created, try to make an empty log file first and re run it

try this dockerfile i have tested it with and crons are running succesfully.

FROM node:8.9.1         
RUN apt update 
RUN apt-get install cron vim -y
RUN mkdir app && touch /var/log/mylog.log
WORKDIR /srv/image-server/current/
COPY ./cronjob /etc/cron.d/container_cronjob
COPY . /srv/image-server/current/
RUN  npm i 
RUN chmod 644 /etc/cron.d/container_cronjob
RUN chmod 777 start.sh
CMD cron && node server.js

i have stored the crons in crontab

* 0 * * * root /srv/image-server/current/start.sh >> /var/log/cron.log 2>&1

here is start.sh file content

rm -rf /tmp/*

Upvotes: 3

anemyte
anemyte

Reputation: 20236

There is a peculiar line at the top of a working user crontab:

head -n1 /var/spool/cron/crontabs/root
# DO NOT EDIT THIS FILE - edit the master and reinstall.

Therefore it's best to follow the advice if you lack the desire to fight unexpected problems. Especially since there are several ways you can get the job done:

  1. Write the job in /etc/cron.d/somefile:
# The syntax for this file is slightly different
# It requires you to write which user should run the job
#     m h dom mon dow user  command
echo "* * *   *   *   root  rm -rf /tmp/*" > /etc/cron.d/somejob
  1. Write the jobs into a text file, then import with crontab:
echo "* * * * * rm -rf /tmp/*" > /tmp/crontab.txt
crontab /tmp/crontab.txt
# or, to import for specific user:
# crontab -u $USERNAME /tmp/crontab.txt
rm /tmp/crontab.txt

Also, I'd like to add that hardcoding cronjobs into a Dockerfile is rather annoying when it comes to changes. You'd have to rebuild the image to implement changes and push the new image to nodes. God save you from making a mistake here or you'd have to repeat that from the beginning. Because of that I started to write cron jobs into environment variables (docker-compose syntax):

services:
  example:
    environment:
      CRON_USER: john  # <- they will have the crontab, root if undeclared
      CRONTAB: |
        # Now you can work with it like with a normal crontab

        PATH=/usr/bin:/bin
        FOO=bar
        * * * * * echo "I'm doing something useful" > /proc/1/fd/1

And this little piece of code does the conversion from an environment variable to a crontab:

if [ -n "$CRONTAB" ]; then # e.g. if non-zero length
    echo "$CRONTAB" > /tmp/crontab.txt

    if [ -n "$CRON_USER" ]; then
        echo "Setting up crontab for user '$CRON_USER'..."
        crontab -u "$CRON_USER" /tmp/crontab.txt
    else
        echo "Setting up crontab for root..."
        crontab /tmp/crontab.txt
    fi

    rm /tmp/crontab.txt
fi

Upvotes: 1

Saeed
Saeed

Reputation: 4125

It seems the image node:8.9.1 does not have crontab installed.

Change your Dockerfile to below:

FROM node:8.9.1         
RUN apt update && apt-get install -y cron vim
RUN mkdir app
WORKDIR /srv/image-server/current/
COPY . .
RUN chmod +x start.sh
RUN  npm i 
RUN  cd /tmp && touch abc && mkdir test
ENTRYPOINT  sh start.sh

Now your file and cronjobs should work when you rebuild the image and run it again.

Upvotes: 1

Related Questions