How to run a cron job inside a docker container?

前端 未结 20 1572
無奈伤痛
無奈伤痛 2020-11-22 05:36

I am trying to run a cronjob inside a docker container that invokes a shell script.

Yesterday I have been searching all over the web and stack overflow, but I could

20条回答
  •  醉梦人生
    2020-11-22 06:16

    Setup a cron in parallel to a one-time job

    Create a script file, say run.sh, with the job that is supposed to run periodically.

    #!/bin/bash
    timestamp=`date +%Y/%m/%d-%H:%M:%S`
    echo "System path is $PATH at $timestamp"
    

    Save and exit.

    Use Entrypoint instead of CMD

    f you have multiple jobs to kick in during docker containerization, use the entrypoint file to run them all.

    Entrypoint file is a script file that comes into action when a docker run command is issued. So, all the steps that we want to run can be put in this script file.

    For instance, we have 2 jobs to run:

    Run once job: echo “Docker container has been started”

    Run periodic job: run.sh

    Create entrypoint.sh

    #!/bin/bash
    
    # Start the run once job.
    echo "Docker container has been started"
    
    # Setup a cron schedule
    echo "* * * * * /run.sh >> /var/log/cron.log 2>&1
    # This extra line makes it a valid cron" > scheduler.txt
    
    crontab scheduler.txt
    cron -f
    

    Let’s understand the crontab that has been set up in the file

    * * * * *: Cron schedule; the job must run every minute. You can update the schedule based on your requirement.

    /run.sh: The path to the script file which is to be run periodically

    /var/log/cron.log: The filename to save the output of the scheduled cron job.

    2>&1: The error logs(if any) also will be redirected to the same output file used above.

    Note: Do not forget to add an extra new line, as it makes it a valid cron. Scheduler.txt: the complete cron setup will be redirected to a file.

    Using System/User specific environment variables in cron

    My actual cron job was expecting most of the arguments as the environment variables passed to the docker run command. But, with bash, I was not able to use any of the environment variables that belongs to the system or the docker container.

    Then, this came up as a walkaround to this problem:

    1. Add the following line in the entrypoint.sh
    declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env
    
    1. Update the cron setup and specify-
    SHELL=/bin/bash
    BASH_ENV=/container.env
    

    At last, your entrypoint.sh should look like

    #!/bin/bash
    
    # Start the run once job.
    echo "Docker container has been started"
    
    declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env
    
    # Setup a cron schedule
    echo "SHELL=/bin/bash
    BASH_ENV=/container.env
    * * * * * /run.sh >> /var/log/cron.log 2>&1
    # This extra line makes it a valid cron" > scheduler.txt
    
    crontab scheduler.txt
    cron -f
    

    Last but not the least: Create a Dockerfile

    FROM ubuntu:16.04
    MAINTAINER Himanshu Gupta
    
    # Install cron
    RUN apt-get update && apt-get install -y cron
    
    # Add files
    ADD run.sh /run.sh
    ADD entrypoint.sh /entrypoint.sh
    
    RUN chmod +x /run.sh /entrypoint.sh
    
    ENTRYPOINT /entrypoint.sh
    

    That’s it. Build and Run the Docker image!

提交回复
热议问题