docker container logs shows a container's recent output, a chosen time window, or a live stream, without ever touching its state. You will finish with a repeatable way to do all three and leave a live stream running safely. The examples use Docker Community Edition CLI 29.8.1, installed from the docker-ce-cli package. Allow about 10 minutes if you already have a container to inspect.
You need a shell, a Docker client, and access to the Docker daemon. Most log reads do not need sudo, but access to the Docker socket is privileged in practice. If a normal command gets a permission error, check your approved Docker access policy with the administrator instead of copying commands from an untrusted account into the Docker group.
Start by listing running containers and copy the name or ID of the one you mean to inspect. A name is easier to recognise, while an ID avoids ambiguity when names are similar.
$ docker container ls --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}'
CONTAINER ID NAMES IMAGE STATUS
abc123def456 api example/api:1.4 Up 12 minutes
Replace CONTAINER_NAME in the commands below with that name. The command is an alias pair: docker container logs is the full form and docker logs is the shorter equivalent.
Checkpoint: Make sure the name belongs to the environment you intend to examine. Reading logs is non-destructive, but the wrong container can send you looking for a fault in the wrong service.
Fetch the last few lines first. This keeps a busy service from flooding your terminal. The default for --tail is all, so always add a limit when you are starting an investigation.
$ docker container logs --tail 50 CONTAINER_NAME
For a container with JSON log output, you might see records like this:
{"time":"2026-09-22T09:36:35.716613815Z","level":"INFO","msg":"service ready"}
An integer is the useful form for --tail. The local manpage calls the option a string and sets its default to all, but a negative number or non-integer is not a sensible way to request a bounded tail. If you need everything, use --tail all deliberately and consider redirecting it to a file with enough disk space.
Checkpoint: Confirm that the output belongs to the service and that the process is writing to standard output or standard error. An application that writes only to a file inside the container will not make that file appear here.
Use --timestamps when you are comparing output with an alert, deployment or system event.
$ docker container logs --tail 20 --timestamps CONTAINER_NAME
2026-09-22T09:36:35.234480227Z {"time":"2026-09-22T09:36:35.234358045Z","level":"INFO","msg":"starting service"}
The added value is an RFC3339Nano timestamp. It is separate from any timestamp your application already writes, so a structured log can contain two timestamps. Do not assume that a line's displayed order proves the order in which concurrent processes produced it.
Use --since for output after a point and --until for output before one. Relative Go durations are convenient during an incident:
$ docker container logs --since 15m --until 2m --timestamps CONTAINER_NAME
These durations are evaluated relative to the Docker client's machine time. For a repeatable handover, use an explicit UTC timestamp with a Z suffix:
$ docker container logs --since '2026-09-22T09:30:00Z' --until '2026-09-22T09:40:00Z' CONTAINER_NAME
Unix timestamps with optional fractional seconds and several date formats are also accepted. If a date has no timezone, the client's local timezone is used. That is an easy source of false empty results when the client and the incident record use different zones.
Checkpoint: If a window returns nothing, widen it before concluding that the service was silent. Check the client's clock, timezone suffix and the container's start time.
Add --follow when you want the existing logs followed by new stdout and stderr output. Combine it with --tail so a long history does not scroll past the point you are watching.
$ docker container logs --follow --tail 20 --timestamps CONTAINER_NAME
Press Ctrl-C to stop the client stream. This stops your log reader, not the container. For a bounded live check, combine follow mode with --since or --until; otherwise a follow command can remain attached to your terminal indefinitely.
Do not substitute docker attach just to watch output. Attach has different input and signal behaviour. Logs are the safer read-only choice for this task.
--details asks Docker to add extra attributes supplied through --log-opt, such as labels or environment-related values. Those attributes can contain operational or sensitive information. Share the normal output first and inspect details privately before pasting them into a ticket.
$ docker container logs --details --tail 20 CONTAINER_NAME
The command works only when the container uses the json-file or journald logging driver, according to the installed manpage. A container configured with a driver that does not support reading can produce a daemon error even though the application is running. Inspect the configuration without changing it:
$ docker container inspect --format '{{.HostConfig.LogConfig.Type}}' CONTAINER_NAME
json-file
If the result is another driver, use that driver's supported log retrieval path. Do not recreate or restart a production container merely to make docker logs work. Those actions change service state and may lose the evidence you were trying to collect.
--tail and add --timestamps when timing matters.--since and --until values without mixing timezones accidentally.Ctrl-C.