docker-compose not printing stdout in Python app

Solution 1:

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.

Solution 2:

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.

Solution 3:

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.