89

When using a print() statement in a Python app running inside a Docker container that's managed by Docker Compose, only sys.stderr output is logged. Vanilla print() statements aren't seen, so this:

print("Hello? Anyone there?")

... never shows up in the regular logs:

enter image description here

(You can see other logs explicitly printed by other libs in my app, but none of my own calls.)

How can I avoid my print() calls being ignored?

3 Answers 3

126

By default, Python buffers output to sys.stdout.

There are a few options:

1. Call an explicit flush

Refactor the original print statement to include a flush=True keyword, like:

print("Hello? Anyone there?", flush=True)

Note: This will cause the entire buffer to flush, not just the same print call. So if there are 'bare' print function calls elsewhere (i.e. without flush=True) that weren't explicitly unbuffered, these will always be flushed too.

You could achieve the same thing with:

import sys
sys.stdout.flush()

This option is useful if you want the most control of when the flushing will occur.

2. Unbuffer the entire app via the PYTHONUNBUFFERED env var

Drop the following into the environment section of your docker-compose.yml file:

PYTHONUNBUFFERED: 1

This will cause all output to stdout to be flushed immediately.

3. Run python with -u

Like option #2 above, this will cause Python to run 'unbuffered' across the full execution lifetime of your app. Just run with python -u <entrypoint.py> - no need for the environment variable.

Sign up to request clarification or add additional context in comments.

6 Comments

Only flush=True works. Windows 10, docker-desktop, Python 3.7
Running an ap in docker had the impression the app was not running... Upon reviewing the other server logs, we saw connections coming... So the problem was mostly the buffer... This is awesome! Thank you!
for the second solution, seems to be, that docker changed the syntax for environment variables. ``` - PYTHONUNBUFFERED=1``` worked for me
It still works. I'm using docker desktop for mac and Python 3.10. Btw, it saved me hours of debugging, thank you
Setting PYTHONUNBUFFERED=1 in docker-compose.yml still works
|
38

Simple, if you add the option -u in the line of the Dockerfile it will print your logs:

CMD ["python", "-u", "my_python_script.py"]

No need of changing an environment variable or change all the prints statements of your program.

4 Comments

-y is an invalid flag. -u is the correct one (I'l add that to my answer above.)
does not work Python 3.7, windows 10, docker-desktop
this solution worked fine for me for FROM python:alpine3.17
The -u flag worked for me on docker-compose on macOS. Surprisingly the stdout.flush() approach did not work.
6

Using pytest, the solution for me was to add the -s option.

For example, in my scenario where I also needed verbose mode on, I had to put pytest -sv.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.