To view Docker container logs, run docker logs --tail 100 CONTAINER with the container's name or ID. Add --timestamps to compare events with another clock, --since 30m to narrow the window, or --follow to stream new output. docker container logs is the full command; docker logs is its documented alias. These commands read output that the container sent to stdout or stderr and that its logging driver still makes available. They do not read every file inside the container. Docker CLI reference, Docker container logging guide.
View one container's logs
First identify the exact container in the correct Docker context. A service name in an application diagram may not be the container name, and a recreated container has a different ID. Inspect a small list rather than guessing:
docker ps --all --format '{{.Names}}\t{{.Status}}'
Choose one verified name or ID, then use bounded reads:
docker logs --tail 100 CONTAINER
docker logs --tail 100 --timestamps CONTAINER
docker logs --since 30m --tail 100 --timestamps CONTAINER
--tail defaults to all retained lines, so an unqualified docker logs CONTAINER can produce far more output than expected. Docker also treats a negative or non-integer tail value as invalid and falls back to all; use a positive integer. --since accepts a timestamp or relative duration. A timestamp without a timezone offset is interpreted using the client's local timezone, so use an explicit offset or Z when sharing a command across machines. Docker-added timestamps use RFC3339Nano format; they are not necessarily the application's own event time. Docker logs options.
For a fixed incident window, use both bounds. Replace these illustrative times with the actual UTC interval:
docker logs --since '2026-09-16T10:00:00Z' --until '2026-09-16T10:15:00Z' --tail 200 --timestamps CONTAINER
--since and --until select from records still readable through the driver; they cannot recover output that was never captured or has aged out. --until requires Docker API 1.35 or later. Do not confuse a command's empty result with proof that the application did nothing in that window. Docker logs reference.
To watch new records while diagnosing a live issue:
docker logs --follow --since 10m --tail 100 --timestamps CONTAINER
--follow continues until you stop it or the stream ends; it is not a bounded snapshot. Keep the terminal and duration under control, especially for noisy or sensitive workloads. Do not redirect an unrestricted stream to a casually named file or paste raw output into a ticket: logs may contain tokens, personal data, request details, and untrusted text. Capture only the authorized, relevant window and sanitize any excerpt before sharing it.
Use Compose V2 for a service
If the workload is managed by Docker Compose, use its service-aware command instead of guessing generated container names:
docker compose logs --tail 100 --since 30m --timestamps api
docker compose logs --tail 100 --since 30m api worker
The names after logs are service names from the selected Compose project. Without a service name, Compose shows output from the project's services. --tail applies per container; a service with several replicas can therefore return more than 100 lines overall. docker compose logs also supports --follow, --index for a particular replica, and --no-log-prefix when the service prefix is not wanted. Check the selected project and Compose file before interpreting an empty result. The Docker Compose logs reference lists the current options; the Compose-focused guide covers project and replica scoping in more detail.
What Docker captures—and what it does not
Docker normally captures a container process's standard output and standard error and sends those records to its configured logging driver. Whether a line is useful depends first on where the application writes. A process that writes only /var/log/app.log inside the container will not make that file appear in docker logs merely because the container is running. Send application output to stdout/stderr or separately collect that file with a deliberate, supported path. The official Apache httpd and Nginx images illustrate how image configuration can route application logs to those streams; a custom image may differ. Docker's container logging guide.
docker logs is a reader for captured container output, not a search across mounts, the host journal, application databases, or historical containers that were removed. Stdout and stderr lines can also be separate records, so a multiline stack trace may need assembly in a downstream collector before it is treated as one event. Docker's timestamp is capture metadata; an application timestamp in the message may reflect a different clock or timezone. For a practical investigation, record which clock you are comparing and which container instance emitted the line.
The logging driver determines where captured records go and whether Docker can read them back. The daemon has a default driver, but a container can override it. Inspect both without printing the entire container configuration, which may expose environment variables and other sensitive settings:
docker info --format '{{.LoggingDriver}}'
docker inspect --type=container --format '{{.HostConfig.LogConfig.Type}}' CONTAINER
The first command shows the daemon's current default. The second shows the selected container's own driver. They can legitimately differ, including after a daemon setting changed. Docker documents both inspection patterns in its logging-driver configuration guide and inspect reference. Treat driver options as potentially sensitive if you inspect them separately; a remote destination may be embedded in configuration.
Where are Docker container logs stored?
There is no universal host path. Storage depends on the container's logging driver, Docker data-root, runtime environment, and whether local readback or caching is enabled. Rootless Docker and Docker Desktop should not be assumed to use a conventional Linux host path. docker inspect --type=container --format '{{.LogPath}}' CONTAINER can report a path for a driver that has one, but a value is not an invitation to open, edit, truncate, or rotate the file manually. Docker explicitly warns that its json-file and local storage is managed exclusively by the daemon; external tools can interfere with logging. Use Docker's logging commands or a supported collection method. Docker inspect reference, json-file driver, local driver.
The default json-file driver stores Docker-wrapped records with a log value, stream (stdout or stderr), and capture time. Its default is no automatic rotation: max-size is unlimited unless configured. This can consume host storage on a verbose workload. The local driver is Docker's general recommendation where json-file compatibility is not required; it rotates by default, with five files of 20 MB each before compression per container. Those are Docker driver defaults, not a promised retention time or a universal disk allowance. Docker logging configuration, local driver defaults.
For a planned deployment, an operator can choose a bounded local policy such as this example daemon configuration:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
This changes Docker configuration and requires an approved rollout; it is not a command to apply during log inspection. The numeric-looking log-opts values are strings by Docker's schema. A daemon restart is required for changed defaults, and only newly created containers inherit them. Existing containers retain their creation-time driver and options until deliberately recreated. Before any change, check whether another component—particularly a Kubernetes deployment—expects json-file behavior, estimate retention from actual log volume, and verify readback after recreating a non-critical container. Do not hand-edit Docker-managed log files or assume rotation can recover already deleted history. Docker logging-driver configuration.
Remote drivers and the local readback cache
Some drivers send output to another destination. Docker Engine automatically adds a local readback cache when a configured driver cannot read logs itself. This dual logging lets docker logs show recent records in many remote-driver setups. If that cache is disabled for a driver that cannot read, the command can fail with “configured logging driver does not support reading.” By contrast, local, json-file, and journald are readable drivers and do not depend on the dual-logging cache. The none driver intentionally makes container logs unavailable through Docker. Docker dual-logging behavior, supported drivers.
Readback is not a durability promise. Docker documents that a remote-driver network failure can prevent writing to the local cache; cache writes can fail, and some cache records can be lost under backpressure. Likewise, Docker's non-blocking delivery mode can drop new messages when its intermediate buffer is full. A blocking mode has a different application-backpressure trade-off. Choose the mode and retention policy from the workload's loss tolerance, then observe the actual driver and destination behavior. A simple “buffer size divided by log rate” calculation cannot establish a safe outage window. Dual-logging limitations, delivery modes.
Why docker logs may be empty or incomplete
Work from the least invasive check to the most specific hypothesis:
- Wrong container or project. Verify the exact name/ID and whether the workload was recreated. For Compose, verify the selected project, service, and replica. Reading an old stopped container can show old history; reading a new replacement can omit the previous instance's history.
- Output went to a file. Check the application's documented logging destination. If it writes only inside the container, neither
docker logsnor a stdout-only collector will see those file records. Do not infer silence from an empty stream. - A filter hid the available data. Recheck
--since,--until, timezone, and--tail. Use a modest recent window, not an unlimited dump. A negative--tailunexpectedly selects all lines. - The driver cannot provide readback. Inspect the container driver. A non-readable remote driver without its dual-logging cache can make
docker logsunavailable;nonedeliberately captures no readable logs. A readable driver can still have too little retained history. - Records were rotated, dropped, or never delivered. Compare the driver's actual retention and delivery mode with the event time. Docker's local cache is limited; remote failures and full non-blocking buffers can lose records. The absence of a line is not proof that the application did not emit it.
- The error occurred elsewhere. An ingress, proxy, host process, or dependency may have generated the symptom rather than this container. Correlate the correct service and time window with independent evidence before changing logging settings.
For more general evidence-reading habits, see how to read logs. When diagnosing an HTTP error, avoid a blind grep '5xx' over raw output: an HTTP status might not be present, formatted that way, or emitted by this container. Prefer a bounded interval and a verified structured status field, if the application actually logs one. Never print entire container configuration or broad application environment just to explain empty logs.
Centralize logs after the local path works
Local Docker logs are useful for a single container, but retention and search across replacements require a deliberate collection path. Define which application emits which stdout/stderr records, which collector reads them, how it buffers and retries, and how you will detect collection gaps. Include container/service identity and a safe request or deployment correlation field where the source actually provides it. Keep secrets and unnecessary request bodies out of logs before they leave the source. Verify one known, non-sensitive marker through the collector and backend, then confirm fields and timestamps against the original container record.
Fluxtail is a paid Starter/Pro, logs-focused destination, not a Docker logging driver. Its Docker collection guide describes a Fluent Bit path into an HTTP JSON receiver; the host runtime path, receiver URL, token, retry behavior, and final field mapping must be verified for the deployment. Once records arrive, Live Tail and search and filters can help inspect them. Fluxtail cannot recover output Docker never captured or a collector failed to deliver. It is not a metrics, tracing, or APM system.
Keep the two questions separate: docker logs tells you what this container's configured driver can read now; centralized search tells you what your verified pipeline delivered and retained. Neither view alone proves complete capture.