Docker captures everything a container writes to stdout and stderr and stores it with a logging driver. That’s why well-built images log to the console instead of files — and why docker logs is the first command to run when a container misbehaves.

View logs

docker logs myapp                 # everything so far
docker logs -f myapp              # follow new output
docker logs --tail 100 myapp      # last 100 lines
docker logs -f --tail 50 myapp    # last 50, then follow
docker logs -t myapp              # prefix each line with a timestamp

Filter by time

docker logs --since 10m myapp
docker logs --since 2026-11-04T08:00:00 --until 2026-11-04T09:00:00 myapp
docker logs --since 1h myapp 2>&1 | grep -i error

Note the 2>&1: Docker replays the container’s stderr on your terminal’s stderr, so pipe both streams if you want grep to see error output.

Docker Compose

docker compose logs                  # all services
docker compose logs -f app worker    # follow specific services
docker compose logs --tail 200 db
docker compose logs -f --no-log-prefix app

Container exits immediately?

If a container restarts in a loop or exits right away, its logs still exist:

docker ps -a                         # find the exited container and its exit code
docker logs <container-id>
docker inspect -f '{{.State.ExitCode}} {{.State.Error}}' <container-id>

Exit code 137 usually means the process was killed — often by the out-of-memory killer (docker inspect -f '{{.State.OOMKilled}}').

Where logs are stored

With the default json-file driver:

docker inspect -f '{{.LogPath}}' myapp
# /var/lib/docker/containers/<id>/<id>-json.log

Each line is a JSON object with the message, stream and timestamp. Don’t edit these files; use docker logs.

The problem: logs grow forever

The json-file driver has no size limit by default. A chatty container can fill your disk over weeks. Check:

sudo du -sh /var/lib/docker/containers/*/*-json.log | sort -h | tail

Set limits globally

/etc/docker/daemon.json:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
sudo systemctl restart docker

Each container then keeps at most 3 × 10 MB. The settings apply to newly created containers; recreate existing ones (docker compose up -d --force-recreate).

Alternatively, use the local driver, which compresses logs and rotates by default (100 MB per container) while still supporting docker logs:

{ "log-driver": "local" }

Per container

docker run --log-opt max-size=10m --log-opt max-file=3 myapp
services:
  app:
    image: myapp
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

Emergency: truncate a huge log

sudo truncate -s 0 $(docker inspect -f '{{.LogPath}}' myapp)

Then set limits so it doesn’t happen again. See also disk full troubleshooting.

Send logs to journald or syslog

On systemd hosts, the journald driver puts container logs in the system journal alongside everything else:

{ "log-driver": "journald" }
journalctl CONTAINER_NAME=myapp -f
journalctl -u docker CONTAINER_NAME=myapp --since today

docker logs keeps working with journald. Journald’s own size limits apply — see journalctl.

Other drivers (syslog, gelf, fluentd, awslogs, splunk) forward logs to central systems. With remote drivers, docker logs may not work unless Docker’s dual logging cache is enabled (it is by default in recent versions).

Centralized logging

For several servers or many containers, collect logs in one place:

  • Grafana Loki + Promtail/Alloy — lightweight, pairs with Grafana. See Loki log aggregation.
  • ELK/OpenSearch — powerful full-text search, heavier on resources.
  • Vector or Fluent Bit — fast log shippers that read Docker’s JSON files or journald.

Apps that log to files

Some images write logs to files inside the container (e.g. /var/log/app.log), which docker logs can’t see and which disappear with the container. Fixes:

  • Configure the app to log to stdout/stderr (most support it).
  • Symlink log files to /dev/stdout and /dev/stderr in the Dockerfile, as the official Nginx image does.
  • Mount a volume for the log directory and rotate it with logrotate.

Quick reference

Task Command
Follow logs docker logs -f NAME
Last N lines docker logs --tail N NAME
Time window --since 30m, --until …
Timestamps -t
Compose service docker compose logs -f SERVICE
Log file path docker inspect -f '{{.LogPath}}' NAME
Cap size max-size, max-file in daemon.json

More everyday commands in the Docker cheat sheet. Disk space matters on any server — every Docker VPS plan comes with SSD storage, but setting log limits keeps it free for your data.

  • Docker
  • Logs
  • Troubleshooting