Python
Docker
Debugging
Containerization
Logging

Why doesn't Python app print anything when run in a detached docker container?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When a Python app runs in a detached Docker container, it is common to see no logs even though the process is still running. In most cases the app is printing, but output is buffered or sent to a destination you are not reading. Fixing this requires understanding container stdout behavior and Python buffering rules.

Why Output Seems Missing in Detached Mode

Detached mode with docker run -d starts the container in the background. You no longer see an attached terminal stream, so output must be read with docker logs.

bash
docker run -d --name demo python:3.12-slim python app.py
docker logs -f demo

If docker logs still appears empty, buffering is often the cause. Python may delay flushing stdout, especially when it is not writing to an interactive terminal.

Force Unbuffered Python Output

Use either the -u switch or PYTHONUNBUFFERED=1.

dockerfile
1FROM python:3.12-slim
2WORKDIR /app
3COPY app.py .
4ENV PYTHONUNBUFFERED=1
5CMD ["python", "-u", "app.py"]

And in Python, flush explicit print calls for long loops.

python
1import time
2
3for i in range(5):
4    print(f"tick {i}", flush=True)
5    time.sleep(1)

This ensures logs show up immediately.

Prefer Structured Logging Over Print

print works, but the logging module gives levels, timestamps, and reliable stream targets.

python
1import logging
2import sys
3import time
4
5logging.basicConfig(
6    level=logging.INFO,
7    format="%(asctime)s %(levelname)s %(message)s",
8    stream=sys.stdout,
9)
10
11for i in range(3):
12    logging.info("worker heartbeat %s", i)
13    time.sleep(1)

Writing logs to stdout is best for containers because orchestrators collect container streams.

Validate the Runtime Path

Sometimes output is absent because a different command is running than expected.

bash
docker inspect demo --format '{{.Config.Cmd}}'
docker exec -it demo ps -ef

Also check whether the app exits immediately due to an exception.

bash
docker logs demo --tail 100

If the container exits fast, detached mode can hide the failure if you only check running containers.

bash
docker ps -a --filter name=demo

Production Notes for Gunicorn and Uvicorn

When running web servers:

  • use flags that send access and error logs to standard streams
  • avoid writing logs only to local files inside ephemeral containers

Example for Gunicorn:

bash
1gunicorn main:app \
2  --bind 0.0.0.0:8000 \
3  --access-logfile - \
4  --error-logfile -

The dash means write to standard streams, which container logging systems can collect.

Fast Diagnostic Checklist

When logs are missing, follow a fixed checklist instead of guessing:

  • confirm the container is still alive with docker ps -a
  • inspect recent output with docker logs --tail 200 container_name
  • verify startup command and environment variables
  • run the same image in attached mode once to compare behavior
bash
docker run --rm --name diag python:3.12-slim python -u -c "import time; [print(i) or time.sleep(1) for i in range(3)]"

If attached mode prints as expected but detached mode does not, the issue is usually logging configuration, buffering, or process lifecycle. This small differential test saves time during incident response because it narrows the search area immediately.

Common Pitfalls

  • Running in detached mode and expecting terminal style live output without docker logs -f.
  • Forgetting Python buffering behavior when output is not attached to a tty.
  • Logging only to files inside the container, then assuming orchestrator logs will include those lines.
  • App process crashing on startup while only checking docker ps and not docker ps -a.
  • Using shell wrappers that redirect stdout or stderr unintentionally.

Summary

  • Detached containers do not display logs automatically; use docker logs.
  • Missing output is often caused by buffering, not missing print statements.
  • Use python -u, PYTHONUNBUFFERED=1, or explicit flush calls.
  • Prefer the logging module and send logs to standard streams.
  • Always verify container state and startup command when logs look empty.

Course illustration
Course illustration

All Rights Reserved.