When a Docker container misbehaves, your first instinct should be the same as with any other service: check the logs. Unlike a traditional virtual machine or bare-metal server, a Docker container does not expose a familiar /var/log directory you can browse at will. Instead, Docker captures whatever the containerised process writes to stdout and stderr, and exposes it through its own logging subsystem. Once you understand how that works, troubleshooting becomes much faster.
This guide walks through the core docker logs workflow: finding a container identifier, viewing its full log output, and tailing the log in real time.
How Docker Logging Works
By default, Docker uses the json-file logging driver, which captures a container’s standard output and standard error streams and stores them as JSON-encoded lines on the host filesystem. The docker logs command reads those stored lines and presents them to you. Because logging is tied to the process streams rather than to files inside the container, this approach works for every container regardless of what is running inside it — a web server, a database, a bare shell session, or anything else.
One important caveat: docker logs only works with the json-file and journald logging drivers. If your Docker daemon is configured to use a remote logging driver such as syslog, fluentd, awslogs, or gelf, log entries are forwarded externally and docker logs will return no output. Check your daemon configuration if the command returns nothing for a container you expect to have logs.
Step 1 — Find the Container Name or ID
Every docker logs invocation requires either the container’s name or its ID. List all running containers with:
docker ps
The output table includes the following columns relevant here:
- CONTAINER ID — a 64-character hex string, usually displayed truncated to 12 characters (e.g.,
e7565ec8e16d). - IMAGE — the image the container was started from (e.g.,
nginx,debian). - NAMES — a human-readable name, either assigned with
--nameat run time or auto-generated by Docker (e.g.,loving_hopper).
You can pass either the full container ID, a unique prefix of the container ID (even four characters is usually enough), or the container name to docker logs. To include stopped containers in the listing, use docker ps -a.
Step 2 — View a Container’s Full Log Output
The basic syntax is:
docker logs CONTAINER
Replace CONTAINER with the name or ID from the previous step. For example, if you have an nginx container named web:
docker logs web
Or using a container ID prefix:
docker logs e7565ec8e16d
This prints everything the container has written to stdout and stderr since it started. For a long-running, busy container this can be a very large amount of text, which is why the options in the next sections are so useful in practice.
Step 3 — Follow Logs in Real Time
The -f (or --follow) flag streams new log lines to your terminal as they are written, similar to tail -f on a traditional log file:
docker logs -f CONTAINER
Combine -f with --tail to start from only the most recent lines instead of replaying the entire history first:
docker logs --tail=50 -f CONTAINER
This is the most practical form of the command for active troubleshooting. You can trigger the behaviour you want to investigate — a failing login, a bad request, a crash loop — and watch the relevant log lines appear immediately. Press Ctrl+C to stop following.
Useful docker logs Options at a Glance
| Option | Description |
|---|---|
--follow / -f | Stream log output in real time. |
--tail N | Show only the last N lines. Use all to show everything (the default). |
--since TIMESTAMP | Show logs produced after a given timestamp or relative duration, e.g. --since 30m or --since 2024-01-15T10:00:00. |
--until TIMESTAMP | Show logs produced before a given timestamp or relative duration. |
--timestamps / -t | Prefix each log line with the container’s timestamp. |
Practical Examples
Show the last 100 lines with timestamps:
docker logs --tail=100 -t web
Show only entries from the past 10 minutes:
docker logs --since 10m web
Follow logs for a container started interactively (e.g., a Debian shell) from a second terminal:
In terminal 1, start the container:
docker run -it debian /bin/bash
In terminal 2, tail its logs using the first four characters of its ID:
docker logs --tail=10 -f 692a
Commands you run inside the Debian shell — such as apt-get update — will produce output that appears in the following terminal as it happens.
Viewing Logs for Stopped Containers
Log data persists after a container stops, as long as the container itself has not been removed. You can still run docker logs CONTAINER against a stopped container to inspect what happened before it exited. This is particularly useful when a container crashes on startup before you have a chance to follow its output live. Once you run docker rm, however, the log data is gone.
Next Steps: Centralised Logging
For a single host and a handful of containers, docker logs is sufficient. At scale — multiple hosts, dozens of services, high log volumes — you will want to route container logs to a centralised log management system. Docker supports a range of logging drivers out of the box (including syslog, journald, fluentd, awslogs, gelf, and splunk) that forward log entries to an external destination without changing anything inside the container. Configuring a logging driver is done either per container (--log-driver flag on docker run) or globally in the Docker daemon configuration file.
Understanding docker logs and how Docker captures stdout/stderr is the essential foundation before moving on to any of those more advanced setups.