why Cronjob in docker container not working - docker

I created a Docker image with Dockerfile for executing a script like get_date.sh on the container but it's not working.
get_date.sh contains:
date
date +"%FORMAT"
var=$(date)
var=`date`
echo "$var">>/var/log/tito_time.log
Dockerfile:
FROM ubuntu:latest
MAINTAINER docker#ekito.fr
RUN apt-get update && apt-get install -y cron && apt-get install nano
COPY get_date.sh /etc/cron.d/get_date.sh
RUN chmod 0644 /etc/cron.d/get_date.sh
RUN crontab -l | { cat; echo "* * * * * bash /etc/cron.d/get_date.sh"; } | crontab -
CMD cron
The image is created correctly. Running crontab -l in a container shell gives me:
root#92ce260aeb21:/# crontab -l
* * * * * bash /etc/cron.d/get_date.sh
crontab doesn't execute get_date.sh on the container.

Related

crontab non executed in docker

I need to execute crontab inside docker container, so I created the following dockerfile:
FROM openjdk:11-oraclelinux8
RUN mkdir -p /opt/my-user/
RUN mkdir -p /opt/my-user/joblogs
RUN groupadd my-user && adduser my-user -g my-user
RUN chown -R my-user:my-user /opt/my-user/
RUN microdnf install yum
RUN yum -y update
RUN yum -y install cronie
RUN yum -y install vi
RUN yum -y install telnet
COPY talend /opt/my-user/
COPY entrypoint.sh /opt/my-user/
RUN chmod +x /opt/my-user/entrypoint.sh
RUN chmod +x /opt/my-user/ETLJob/ETLJob_run.sh
RUN chown -R my-user:my-user /opt/my-user/
RUN echo "*/2 * * * * /bin/sh /opt/my-user/ETLJob/ETLJob_run.sh >> /opt/my-user/joblogs/job.log 2>&1" >> /etc/cron.d/my-user-job
RUN chmod 0644 /etc/cron.d/my-user-job
RUN crontab -u my-user /etc/cron.d/my-user-job
RUN chmod u+s /usr/sbin/crond
USER my-user:my-user
ENTRYPOINT [ "/opt/my-user/entrypoint.sh" ]
My entrypoint.sh file is the following one:
#!/bin/bash
echo "Start cron"
crontab /etc/cron.d/diomedee-job
echo "cron started"
# Run forever
tail -f /dev/null
So far so good, the container is created successfully and when I go inside the container and I type crontab -l I see the crontab... but it is never executed
I can't figure out what I'm missing; any research I made didn't give me any clue
May you give me any tip?
Docker containers usually only host a single process. In your case, the tail process. The cron daemon isn't running.
Your comment 'cron started' seems to indicate that running crontab starts the daemon, but it doesn't.
Replace your tail -f /dev/null command with crond -f to run the cron daemon in the foreground and it should work.

How should I use libfaketime and cron in a Docker container?

I would like to set a Docker container up, which
fakes a chosen date with libfaketime;
runs a cron job with that fake time.
My attempt can be found at https://gitlab.com/gablab/proto_docker_cron_libfaketime. The most relevant lines are probably
# Dockerfile
CMD cron && tail -f /var/log/cron.log
# crontab_for_container
* * * * * for i in 1 2 3; do echo $i; flock -n /.flock_reprio /myscript.sh >> /var/log/cron.log 2>&1; sleep 10; done
More details
Running the script directly
docker-compose exec myservice bash
and then bash /myscript.sh gives the wanted date. Same for docker-compose exec myservice date.
Dockerfile
FROM debian:buster AS base
RUN set -ex; \
apt-get update;
ADD ./myscript.sh /myscript.sh
RUN apt install -y cron
COPY ./crontab_for_container /etc/cron.d/crontab_for_container
RUN chmod 0644 /etc/cron.d/crontab_for_container
RUN crontab /etc/cron.d/crontab_for_container
RUN touch /var/log/cron.log
CMD cron && tail -f /var/log/cron.log
from base as builder
# faketime
RUN apt-get update && apt-get install -y make gcc git
# Get the sources and checkout at stable release 0.98
# see https://github.com/wolfcw/libfaketime/releases
RUN git clone https://github.com/wolfcw/libfaketime.git && \
cd libfaketime && \
git checkout dc2ae5eef31c7a64ce3a976487d8e57d50b8d594 && \
make
from base as runtime
COPY --from=builder /libfaketime/src/libfaketime.so.1 /usr/local/lib
ENV LD_PRELOAD=/usr/local/lib/libfaketime.so.1
ARG FAKETIME_ARG="0d"
ENV FAKETIME=$FAKETIME_ARG
A quick, dirty fix that works is to hard-code into the crontab file the variables to be passed to the job:
# crontab
* * * * * for i in 1 2 3; do echo $i; LD_PRELOAD=/usr/local/lib/libfaketime.so.1 FAKETIME=FAKETIME_PLACEHOLDER TEST=ABCD flock -n /.flock_reprio /myscript.sh >> /var/log/cron.log 2>&1; sleep 10; done
# Dockerfile
RUN sed --in-place -e s/FAKETIME_PLACEHOLDER/"\"$FAKETIME_ARG\""/ /etc/cron.d/crontab_for_container
(note that the quotes \" are needed because the date could be provided as "#2020-02-02 10:00:00").

Why isn't my Docker container running my cron script, but it does when I do service cron restart?

Cron isn't a running process when I go into my container, but when go into the container and bash service cron restart it starts running, I can't figure out why this isn't working with the service cron restart but not without it?
Dockerfile
FROM ubuntu:bionic
RUN apt-get update && apt-get -y install \
cron \
nano \
psmisc \
wget
COPY hello-cron /etc/cron.d/hello-cron
# Give execution rights on the cron job
RUN chmod +x /etc/cron.d/hello-cron
# Apply cron job
RUN crontab /etc/cron.d/hello-cron
# Create the log file to be able to run tail
CMD ["cron", "-f"]
my hello-cron script
* * * * * echo "Hello world" > /usr/src/helloworldcron.log 2>&1

How to execute cron job as non-root user under Ubuntu inside Docker

This is the Dockerfile of an image I'm trying to create. The non-root user is simulating the host user on the local machine.
FROM ubuntu:bionic
RUN apt-get -yqq update && apt-get -yqq install cron passwd openssl strace
RUN groupadd -g 1000 hostuser && useradd -l -u 1000 -m -s /bin/bash -p $(openssl passwd -1 test1) -g hostuser hostuser
COPY hello-cron /etc/cron.d/hello-cron
RUN sudo chmod 0644 /etc/cron.d/hello-cron
COPY hello-cron-root /etc/cron.d/hello-cron-root
RUN sudo chmod 0644 /etc/cron.d/hello-cron-root
RUN touch /var/log/cron.log
COPY cron.allow /etc/cron.allow
#CMD /usr/sbin/cron -L 15 && tail -f /var/log/cron.log
CMD strace /usr/sbin/cron -f -L 15
This is the file hello-cron:
* * * * * hostuser echo "Hello World" >> /var/log/cron.log 2>&1
This is the file hello-cron-root:
* * * * * root echo "Hello World Root" >> /var/log/cron.log 2>&1
This is the file cron.allow:
hostuser
When I build and execute the image ONLY the job executed under root gives some output. strace did not help much. Any ideas?
Unfortunately I can't use Alpine or something else. I need to make this work using Ubuntu Bionic.
So far this is the only thing that works in this setup:
FROM ubuntu:bionic
RUN apt-get -yqq update && apt-get -yqq install cron passwd openssl sudo
RUN groupadd -g 1000 hostuser && useradd -l -u 1000 -m -s /bin/bash -p $(openssl passwd -1 test1) -g hostuser hostuser
COPY hello-cron-root /etc/cron.d/hello-cron-root
RUN sudo chmod 0644 /etc/cron.d/hello-cron-root
RUN touch /var/log/cron.log
COPY cron.allow /etc/cron.allow
COPY hostuser-run /usr/local/bin/hostuser-run
RUN chmod +x /usr/local/bin/hostuser-run
CMD /usr/sbin/cron -L 15 && tail -f /var/log/cron.log
This is hostuser-run:
#!/usr/bin/env bash
sudo -H -s -u 'hostuser' echo "We are running as $USER"
This is the file hello-cron-root:
* * * * * root /usr/local/bin/hostuser-run >> /var/log/cron.log 2>&1
To summarize - given that only root cron jobs are working under docker to execute stuff under different user use helper script with sudo -u.

How to run cron job in docker container?

I have a python script that populates Postgres database in AWS.
I am able to run it manually and it is loading data into database without any issues. I want to run it once for every 5 minutes inside a docker container.
So I included it in docker image to run. But I'm not sure why it's not running. I can't see anything appended to /var/log/cron.log file. Can someone help me figure out why it's not running?
I am able to copy the script to image during docker build and able to run it manually. The DB is being populated and I'm getting the expected output.
The script is in current directory which will be copied to /code/ folder
Here is my code:
Dockerfile:
FROM python:3
RUN apt-get -y update && apt-get -y upgrade
RUN apt-get install -y cron
RUN apt-get install -y postgresql-client
RUN touch /var/log/cron.log
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD . /code/
COPY crontab /etc/cron.d/cjob
RUN chmod 0644 /etc/cron.d/cjob
CMD cron && tail -f /var/log/cron.log
crontab:
*/5 * * * * python3 /code/populatePDBbackground.py >> /var/log/cron.log
# Empty line
Crontab requires additional field: user, who runs the command:
* * * * * root python3 /code/populatePDBbackground.py >> /var/log/cron.log
# Empty line
The Dockerfile is:
FROM python:3
RUN apt-get -y update && apt-get -y upgrade
RUN apt-get install -y cron postgresql-client
RUN touch /var/log/cron.log
RUN mkdir /code
WORKDIR /code
ADD . /code/
COPY crontab /etc/cron.d/cjob
RUN chmod 0644 /etc/cron.d/cjob
ENV PYTHONUNBUFFERED 1
CMD cron -f
Test python script populatePDBbackground.py is:
from datetime import datetime
print('Script has been started at {}'.format(datetime.now()))
And finally we get:
$ docker run -d b3fa191e8822
b8e768b4159637673f3dc4d1d91557b374670f4a46c921e0b02ea7028f40e105
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8e768b41596 b3fa191e8822 "/bin/sh -c 'cron -f'" 4 seconds ago Up 3 seconds cocky_beaver
$ docker exec -ti b8e768b41596 bash
root#b8e768b41596:/code# tail -f /var/log/cron.log
Script has been started at 2019-03-13 00:06:01.095013
Script has been started at 2019-03-13 00:07:01.253030
Script has been started at 2019-03-13 00:08:01.273926
This might not be directly related, but I was getting stuck with my cronjob running in a docker container. I tried the accepted answer with no luck. I finally discovered that the editor I was using to edit the Crontab file (Notepad++) was set to Windows line-endings (CR LF). Once I changed this to Unix line endings (LF) my cronjob ran successfully in my docker container.
Using traditional cron implementations under docker is tricky. Consider using supercronic:
docker-compose.yml:
services:
supercronic:
build: .
command: supercronic crontab
Dockerfile:
FROM alpine:3.17
RUN set -x \
&& apk add --no-cache supercronic shadow \
&& useradd -m app
USER app
COPY crontab .
crontab:
*/5 * * * * date
$ docker-compose up
More alternatives can be found in my other answer.

Resources