8

I want to do some simple logging for my server which is a small Flask app running in a Docker container.

Here is the Dockerfile

# Dockerfile
FROM dreen/flask
MAINTAINER dreen
WORKDIR /srv

# Get source
RUN mkdir -p /srv
COPY perfektimprezy.tar.gz /srv/perfektimprezy.tar.gz
RUN tar x -f perfektimprezy.tar.gz
RUN rm perfektimprezy.tar.gz

# Run server
EXPOSE 80
CMD ["python", "index.py", "1>server.log", "2>server.log"]

As you can see on the last line I redirect stderr and stdout to a file. Now I run this container and shell into it

docker run -d -p 80:80 perfektimprezy
docker exec -it "... id of container ..." bash

And observe the following things:

The server is running and the website working

There is no /srv/server.log

ps aux | grep python yields:

root         1  1.6  3.2  54172 16240 ?        Ss   13:43   0:00 python index.py 1>server.log 2>server.log
root        12  1.9  3.3 130388 16740 ?        Sl   13:43   0:00 /usr/bin/python index.py 1>server.log 2>server.log
root        32  0.0  0.0   8860   388 ?        R+   13:43   0:00 grep --color=auto python

But there are no logs... HOWEVER, if I docker attach to the container I can see the app generating output in the console.

How do I properly redirect stdout/err to a file when using Docker?

4 Answers 4

5

I'd like to question your use-case. Why do you need to redirect stderr/stdout to a log file in the container? Merged stderr and stdout are available outside the container using "docker logs", and they can be redirected to a file (outside of the container.) More details can be found here

4
  • youre right, it seems i can even do docker logs ID > stdout.log 2>stdout.log but i still cant see an exception... im starting to think it might be dying without an error
    – Dreen
    Commented Jan 22, 2016 at 10:33
  • 1
    Here's a use case: you're running the container on Docker Cloud (where you can't just redirect the log output to a file on the (remote and not easily accessible) node. You run a lot of different headless containers and you want to collect the respective outputs (possibly gigabytes of data) a few hours later. Commented Apr 5, 2016 at 21:10
  • @hheimbuerger "Why do you need to redirect stderr/stdout to a log file in the container?" Even with your use case description, I would question the use of logging INSIDE a container. If you need log/event messages from headless containers, I think it would be easier to use tools that enable those files/messages to be viewed/stored outside of the container. Perhaps using a logging driver that meets your needs might be a better choice than logging inside of a container.
    – John
    Commented Nov 3, 2017 at 2:57
  • ` docker events & echo copy paste an event id docker logs <<event-id>> ` Commented Jul 2, 2019 at 19:09
2

Here's some info on a related use case: You want to redirect the output inside the container, which is running on Docker Cloud.

In my case, I'm executing a long-running data analysis script (Java) on Docker Cloud. Each container is supposed to write its own results file. I'm using the java:8-jre image and overwrite the 'Run command' with the following line:

bash -c "java -jar /code/analyzer.jar > /data/results-$RANDOM.txt"

By using bash's $RANDOM variable, I can scale up the number of containers in Docker Cloud as much as I want, while still collecting the results individually.

2

You are looking for tee

LOGFILE="logthis.txt";
IMG_alpine="alpine:3.5";

docker run --rm \
--name alpine-hello \
--hostname alpine-hello \
"$IMG_alpine" \
uname -a | tee -a $LOGFILE

cat logthis.txt
Linux alpine-hello 4.8.14-docker-2 #1 SMP Tue Jan 10 15:35:02 UTC 2017 x86_64 Linux
0
1

To use docker run in a shell pipeline or under shell redirection, making run accept stdin and output to stdout and stderr appropriately, use this incantation:

docker run -i --log-driver=none -a stdin -a stdout -a stderr ...

e.g. to run the alpine image and execute the UNIX command cat in the contained environment:

echo "This was piped into docker" |
  docker run -i --log-driver=none -a stdin -a stdout -a stderr \
    alpine cat - |
  xargs echo This is coming out of docker: 

emits:

This is coming out of docker: This was piped into docker

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .