Why Docker Logs Empty for Running Container (and How to Fix It)
When docker logs comes back empty for a running container, the app is usually writing to a file or another output instead of stdout—or the logging driver isn't storing anything. This guide walks through the inspection steps and fixes for both Linux and Windows hosts.
Rao Aadil, India 8 min read
Confirm the symptom: container is running, docker logs is empty
Start with docker ps -a. The STATUS column must show Up for the container you are checking; Exited or Restarting means the container is not in the stable running state this article assumes. Next, run docker logs <container> with no flags. If you get nothing at all, try docker logs --tail 50 <container> to rule out a situation where only the last few lines were truncated by a previous --tail option. Then run docker inspect <container> --format '{{.State.Status}}' to confirm the container is actually running and not stuck in a restart loop.
These commands are identical on Linux and Windows; use PowerShell or cmd on Windows. If docker logs returns an error such as "No such container" or "configured logging driver does not support reading", that points to a different cause than an empty log result. An empty result means Docker has no captured output for the container, while an error means the logging driver itself cannot be read by docker logs. Keep these two cases separate.
Inspect containers, read logs, check stats, restart services and run Compose stacks, just by describing what you want.
“why does this container keep restarting”
It reads the real state of the server before it says anything, shows you the exact command, and waits for your approval. Windows and Linux, over the SSH access you already have.
Check whether the process inside the container writes to stdout/stderr
Determine where the application actually sends its output. On Linux, run docker exec <container> ps aux to list running processes. On Windows, use docker exec <container> powershell Get-Process or docker exec <container> cmd /c tasklist. Look for the main application process and any child processes. If the main process is not PID 1, or if the entrypoint script launched the app in the background and then ran something like tail -f /dev/null, the app's logs may not be connected to the container's stdout and stderr.
Inspect the entrypoint and command that started the container with:
docker inspect <container> --format '{{.Config.Entrypoint}} {{.Config.Cmd}}'
This command works on both Linux and Windows. Look for a wrapper script that redirects output to a file, backgrounds the app with &, or omits an exec call before the main binary. Those are common reasons a healthy process produces no docker logs output.
Look for log files inside the container. On Linux:
docker exec <container> sh -c 'ls -l /var/log /app/logs 2>/dev/null'
On Windows:
docker exec <container> powershell Get-ChildItem C:\logs -ErrorAction SilentlyContinue
Applications that default to file logging include nginx (writes to access.log and error.log), Tomcat (catalina.out), Java applications with file appenders, and Node.js services configured with file transports. If you find a log file that is growing, the app is writing somewhere other than stdout. A less common edge case is a container started with -t (TTY allocation). Some applications write directly to the TTY device instead of stdout; docker logs will then be empty even though the container appears interactive.
Identify the Docker logging driver and configuration
Get the effective logging driver and any driver-specific options:
docker inspect <container> --format '{{.HostConfig.LogConfig.Type}} {{.HostConfig.LogConfig.Config}}'
The most common driver is json-file, which stores logs on disk and is readable by docker logs. The local driver also supports docker logs. The none driver discards all output, so docker logs will always be empty. Drivers such as syslog, gelf, and fluentd send logs to an external system; docker logs may return nothing or report that the driver does not support reading, depending on the Docker version. This command works on Linux and Windows.
Check the daemon-level default in daemon.json. On Linux this file is at /etc/docker/daemon.json; on Windows it is at C:\ProgramData\docker\config\daemon.json. Look for a top-level "log-driver" key set to "none" or an external driver. If a container does not specify --log-driver, it inherits this daemon default. Note that docker logs is designed to work with the json-file, journald, and local drivers in most current Docker distributions, but support for journald reading can vary. For other drivers, you must consult the external log system directly.
Find the real cause: why output isn’t captured
If the effective driver is none or an external driver like syslog, the reason for empty logs is straightforward: the container’s stdout and stderr are not being stored in a way that docker logs can read. If the driver is json-file, the problem is almost always that PID 1—the main process inside the container—does not write to stdout or stderr. Instead, the application writes to a file inside the container, or a wrapper script runs the app as a background process and then becomes PID 1 without forwarding the app's output.
On Linux, a common pattern is missing symlinks from log files to /dev/stdout or /dev/stderr. For example, an nginx container might have /var/log/nginx/access.log as a regular file instead of a symlink to /dev/stdout. When the symlink is present, nginx writes to stdout and docker logs captures it. On Windows, stdout capture can vary by base image and Docker Desktop version; some Windows container configurations do not forward stdout from certain process models, so even an app that calls Console.WriteLine may not show up in docker logs.
To prove logs are being written somewhere, use docker exec to tail the container’s actual log file. On Linux:
docker exec <container> tail -f /var/log/app.log
On Windows, you can use docker exec <container> powershell Get-Content -Wait C:\logs\app.log (the behavior of -Wait inside a container may differ; use it as a diagnostic, not a permanent fix). If output appears there, the app is logging to a file and the fix is to redirect that output to stdout.
Fix: make logs appear in docker logs
If the logging driver is none or an external driver that docker logs cannot read, you must recreate the container with a readable driver. Use docker run --log-driver json-file (or local) when starting the container. You cannot change the logging driver of an existing container; the container must be recreated. Alternatively, change the daemon default in /etc/docker/daemon.json (Linux) or C:\ProgramData\docker\config\daemon.json (Windows) to "log-driver": "json-file", restart Docker, and then recreate the container. On Windows, restarting the Docker service or Docker Desktop is required after editing daemon.json.
When the app logs to files, change its configuration to write to stdout. For nginx, symlink access.log to /dev/stdout and error.log to /dev/stderr. For Tomcat, use a console appender instead of the default file appender. For Node.js, use console.log rather than a file transport. For Java, configure a ConsoleAppender in logback or log4j.
When you can't change the application, use a wrapper script as the container’s entrypoint that tails the log file to stdout. On Linux, a wrapper like this works:
#!/bin/sh
tail -F /var/log/app.log &
exec your-app
The tail -F follows the file even if it is rotated, and the app runs as PID 1 with its own output forwarded. On Windows, you can use Get-Content -Wait in a PowerShell script, but process management and signal handling differ, so test carefully with your base image.
For Compose users, add a logging: section to the service in docker-compose.yml:
services:
app:
image: your-image
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
Then run docker compose up -d to recreate the service with the new logging configuration. The same --log-driver flag works on Windows for docker run.
After any fix, verify with:
docker logs --tail 20 <container>
You should now see recent output. If not, repeat the inspection steps to confirm the driver and the process output path.
Prevent it from happening again
Have applications write to stdout and stderr, not to files inside the container. This is the single most reliable way to keep docker logs working.
Standardize the logging driver across your environment. Document your choice in Dockerfiles, Compose files, and daemon.json, and keep daemon.json under version control. For Compose stacks, include a logging: block for each service with rotation settings (such as max-size and max-file) to prevent disk exhaustion.
Add a post-deployment smoke test that runs docker logs --tail 1 <container> to confirm logs are flowing. An AI agent that manages Docker can inspect container logging configurations and run read-only diagnostics inside the container to determine whether the process writes to stdout or files. It cannot modify the Docker daemon configuration on the host, so any changes to daemon.json remain a manual step. Periodically review the effective logging driver of running containers with docker inspect on both Linux and Windows to catch misconfigurations before they cause silent failures.