Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write docker cron logs to stdout/stderr

I have docker where cron is ran using CMD ["cron","-f"] command. This writes the output to the cron log file.

Is there any way to redirect these logs to the console.

My Base Image looks like

FROM ubuntu:latest
RUN ls

RUN apt-get update
RUN apt install -y software-properties-common
RUN add-apt-repository -y ppa:openjdk-r/ppa
RUN apt-get update
RUN apt-get install -y openjdk-12-jre

RUN apt-get -y install cron wget unzip



RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list \
    && apt-get update -qqy \
    && apt-get -qqy install google-chrome-stable \
    && rm /etc/apt/sources.list.d/google-chrome.list \
    && rm -rf /var/lib/apt/lists/* /var/cache/apt/* \
    && sed -i 's/"$HERE\/chrome"/"$HERE\/chrome" --no-sandbox/g' /opt/google/chrome/google-chrome


ARG CHROME_DRIVER_VERSION=76.0.3809.68
RUN wget --no-verbose -O /tmp/chromedriver_linux64.zip https://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip \
    && rm -rf /opt/chromedriver \
    && unzip /tmp/chromedriver_linux64.zip -d /opt \
    && rm /tmp/chromedriver_linux64.zip \
    && mv /opt/chromedriver /opt/chromedriver-$CHROME_DRIVER_VERSION \
    && chmod 755 /opt/chromedriver-$CHROME_DRIVER_VERSION \
    && ln -fs /opt/chromedriver-$CHROME_DRIVER_VERSION /usr/bin/chromedriver

COPY tests-cron /etc/cron.d/tests-cron
RUN chmod 0644 /etc/cron.d/tests-cron
WORKDIR /etc/cron.d
RUN ls
RUN crontab /etc/cron.d/tests-cron

RUN touch /var/log/cron.log



WORKDIR /app
RUN mkdir pricetest

COPY --from=maven-container /app/ pricetest/
RUN cp /usr/bin/chromedriver ./pricetest

WORKDIR /app/pricetest
ENV SHELL=/bin/bash

CMD ["cron", "-f"]

PS: I am still work in progress on this project. So I havent optimized the docker build.

And the cronfile ( tests-cron ) I am contains

* * * * * root echo "Hello world"

Base image used: ubuntu:latest

like image 491
Asnim P Ansari Avatar asked Aug 03 '19 03:08

Asnim P Ansari


People also ask

Does docker logs show stderr?

By default, docker logs shows the command's STDOUT and STDERR .

What is the docker command for container logs?

First of all, to list all running containers, use the docker ps command. Then, with the docker logs command you can list the logs for a particular container. Most of the time you'll end up tailing these logs in real time, or checking the last few logs lines.

Does cron work in docker?

One way to create scheduled tasks for your containers is by using the host's crontab. Since the definition of each cron job allows you to execute commands, you can use Docker Engine in the same way you would the command line.

Is there a log for cron?

Most versions of cron will log when jobs run and whether there are any errors with your crontab. They do not log cron job output or exit statuses. (For that, use Cronitor).

How to read Docker logs from Docker containers?

a simple docker logs will read the logs, instead of reading the log file in the container some tools leverages the docker logs to collect and aggregate into a logging system (e.g. ELK) If the application is running as PID 1, we can create a symbolic link to /dev/stdout from the log files that the application is writing to.

How do I set up a cron job in dockerfile?

In your Dockerfile, apt-get -y install cron Use apk or whatever if you are running on alpine or another distribution Set the command or entrypoint in your Dockerfile to run cron 9n the foreground Copy the crontab with your jobs in it into /etc/crontab. Each job should redirect it's stdout and stderr to fh 1 of PID 1 (the crontab process).

How do I run a docker job on a regular basis?

This works because docker always treats the stdout from process 1 as the docker log stream. ... to run a single job on a regular basis is to use date and sleep. This makes for a simpler container (no need for cron) if you only need a command or commands to run at a single interval (say, every morning at 3:00AM).

Why does echo redirect to stderr in Docker?

This line also redirects stderr, although that is not really necessary in the case of a simple echo. This works because docker always treats the stdout from process 1 as the docker log stream. ... to run a single job on a regular basis is to use date and sleep.


1 Answers

Yes, there is a way to redirect logs to console, All you need to change the entry point of your Dockerfile. Here is the working example base on alpine which runs a cronjob every minute with output.

Alpine image

CMD flags

-f  Foreground
-L FILE Log to FILE

Dockerfile

FROM alpine:latest
RUN echo "* * * * * echo hello" | crontab - 
CMD ["crond","-f", "-L", "/dev/stdout"]

enter image description here

Another thing, Please always share your base image so it's easy to understand the context of the issue.

Ubuntu image

The workaround in ubuntu is to replace the CMD a bit, but I will not recommend this approach as the cron as cron will not be the parent process of container. You can read more about this approach here and here

If you want to optimization then use alpine the future image of docker container and here is the difference in the size of these two image.

Alpine is just 5MB where Ubuntu is 91MB

enter image description here

Here is the working example of cron with output using base image Ubuntu

FROM ubuntu:latest
RUN apt-get update &&  apt-get -y install cron
RUN touch /var/log/cron.log
RUN (crontab -l ; echo "* * * * * echo "Hello world" >> /var/log/cron.log") | crontab
CMD cron && tail -f /var/log/cron.log
like image 82
Adiii Avatar answered Oct 18 '22 20:10

Adiii