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?
When you specify a JSON list as CMD
in a Dockerfile
, it will not be executed in a shell, so the usual shell functions, like stdout and stderr redirection, won't work.
From the documentation:
The exec form is parsed as a JSON array, which means that you must use double-quotes (
"
) around words not single-quotes ('
).Unlike the shell form, the exec form does not invoke a command shell. This means that normal shell processing does not happen. For example,
CMD [ "echo", "$HOME" ]
will not do variable substitution on$HOME
. If you want shell processing then either use the shell form or execute a shell directly, for example:CMD [ "sh", "-c", "echo", "$HOME" ]
.
What your command actually does is executing your index.py
script and passing the strings "1>server.log"
and "2>server.log"
as command-line arguments into that python script.
Use one of the following instead (both should work):
CMD "python index.py > server.log 2>&1"
CMD ["/bin/sh", "-c", "python index.py > server.log 2>&1"]