Guide to Balancing Speed and Control in DevOps

➡️ Download

Docker

Docker Container Logs: How to View & Manage

docker container logs

🚀 Level Up Your Infrastructure Skills

You focus on building. We’ll keep you updated. Get curated infrastructure insights that help you make smarter decisions.

Easy access to application logs is crucial for development, so you can effectively monitor and debug your services. Viewing a Docker container’s logs lets you check what’s happening inside the container, giving you a starting point for troubleshooting.

In this guide, we’ll show you how to access Docker container logs and use the different options available. We’ll also briefly explore Docker’s log storage settings so you can tailor your container observability to your needs.

What we’ll cover:

  1. What are Docker container logs?
  2. How to view Docker container logs
  3. Checking Docker container logs with Docker Compose
  4. Where are Docker container logs stored?
  5. How to clear Docker container logs
  6. Best practices for managing Docker container logs

What are Docker container logs?

Docker container logs provide the output from the foreground process running inside the container. Docker collects the log lines that the process writes to its standard output and error streams (stdout and stderr) and makes them available to view within the Docker CLI.

The log’s content and formatting depend on what the application writes in the container. If you’re containerizing your own app, you should ensure you write your logs to stdout and stderr so they’re accessible to Docker’s built-in logging mechanism. Now, let’s see Docker container logs in action.

How to view Docker container logs

To view logs from a running or stopped Docker container, use the docker logs command followed by the container name or ID.

Common options can be combined to create precise log views, such as streaming only recent log entries with timestamps

  • --timestamps: Adds timestamps to each log line
  • --follow: Streams logs in real time, similar to tail -f.
  • --since and --until: Filters logs by time range. Accepts relative or ISO timestamps.
  • --tail: Shows only the most recent N lines of logs.

This method works only if the container’s logging driver supports log retrieval (e.g., json-file, which is the default). For other drivers like syslog or fluentd, consult their respective systems to access logs.

To follow along with this article, try starting a simple Docker container using the official NGINX image:

$ docker run -d -p 8080:80 --name demo-nginx  nginx:latest
cc316e105c8edb542526a3f4edcb0f6e75a4706d9ab0d207bd013e47c0d4a7eb

NGINX automatically emits some logs on startup. These will show up in Docker’s log stream. NGINX also writes a log line for each HTTP request you make. You can visit localhost:8080 in your browser to access the containerized app and add a new line to the log.

1. docker logs

You can retrieve a Docker container’s logs using the docker logs CLI command. You must specify the ID or name of the container you want to access. 

If you don’t know these details, you can run the docker ps command first to find out. 

In the example above, we named our container demo-nginx.

$ docker logs demo-nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2025/04/28 16:17:10 [notice] 1#1: using the "epoll" event method
2025/04/28 16:17:10 [notice] 1#1: nginx/1.27.5

Docker will display the container’s entire log in your terminal. The log is printed exactly as the containerized app, NGINX, in this case, has written it.

Note: The docker logs command is an alias of the modern longhand version, docker container logs. These variations can be used interchangeably.

2. docker logs --timestamps

Because the docker logs command displays the log’s content as it was written, timestamps will be shown only if the app included them in its messages. 

The example above demonstrates that regular NGINX log lines are already timestamped, but some of the early messages during startup are not.

Docker stores a timestamp independently whenever a log line is written. You can view these timestamps alongside the log output by adding the -t or --timestamps flag to your docker logs command:

$ docker logs demo-nginx --timestamps
2025-04-28T16:17:10.257324357Z /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
2025-04-28T16:17:10.257358388Z /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
2025-04-28T16:17:10.258819585Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
2025-04-28T16:17:10.269785717Z 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
2025-04-28T16:17:10.275276586Z 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf

Now, each container log line is prefixed with its complete timestamp in RFC 3339 format. This lets you easily identify when each event occurred.

3. docker logs --follow

It’s often useful to livestream new logs into your terminal as they’re written. This lets you continually monitor your container and engage in more efficient debugging workflows. Include the -f or --follow flag with your docker logs command to activate this mode:

$ docker logs demo-nginx -f
docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
...

The container’s logs will stream into your terminal window until you press Ctrl+C.

4. docker logs --since and docker logs --until

Docker lets you filter container logs to view only the messages written during a specific timeframe. This allows you to find relevant log lines written around the time a problem occurred.

The docker logs command’s --since and --until flags activate these filters. They can be used either independently or together. Each flag accepts an RFC 3339 timestamp string in date, date/time, or complete format. You can also pass a Unix timestamp or a relative duration string such as 1h or 1h30m.

# Get the log messages emitted 5-10 minutes ago
$ docker logs demo-nginx --since 10m --until 5m

5. docker logs --tail

Running docker logs without other flags can cause a very large amount of output to be written to your terminal. The command dumps the log’s entire existing content, which could be thousands of lines for a busy application.

Specifying the --tail flag (or its -n short counterpart) lets you specify how many lines to display, starting from the end of the log. For example, --tail 5 will show the five most recent lines.

$ docker logs demo-nginx --tail 5
2025/04/28 16:17:10 [notice] 1#1: start worker process 35
2025/04/28 16:17:10 [notice] 1#1: start worker process 36
172.17.0.1 - - [28/Apr/2025:16:17:47 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0" "-"
172.17.0.1 - - [28/Apr/2025:16:17:47 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://172.17.0.2/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0" "-"
2025/04/28 16:17:47 [error] 29#29: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "172.17.0.2", referrer: "http://172.17.0.2/"

The --tail option can also be combined with --follow. For example, running docker logs <container> --follow --tail 5 will show the five most recent lines from the log, then any new output until you press Ctrl+C.

Viewing Docker Container logs in the Docker Desktop GUI

Our examples so far have focused on accessing your container logs with the docker CLI. However, if you’re using Docker Desktop, you can also view a container’s logs through Desktop’s graphical interface. 

Simply click the container’s name in the Containers list shown within the app:

Viewing Docker Container logs in the Docker Desktop GUI

The container’s logs will display within the Docker Desktop window:

logs display within the Docker Desktop

New log lines will automatically appear in the window as they’re emitted. You can search the logs and toggle whether timestamps are displayed using the buttons in the top right.

You can also copy displayed logs to your clipboard or clear what’s visible within the window. The latter option can help you focus more easily on new incoming log messages.

How to view Docker Compose container logs

Docker Compose simplifies configuring and running multi-container applications. You can still get the logs from Compose containers using the regular docker logs command, but the Compose CLI also provides its own counterpart that lets you see the combined output from all the containers in your stack.

Run docker compose logs within your project’s working directory to view the log output from your stack’s containers:

$ docker compose logs
nginx-1  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx-1  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
nginx-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
nginx-1  | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
nginx-1  | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf

Docker Compose prefixes each log line with the service name and replica ID of the container that emitted the message. The names are colorized so you can easily identify the output from different containers when viewing a busy log stream.

The docker compose logs command supports the --follow, --tail, --timestamps, --since, and --until flags in the same way as docker logs

You can learn more about logging with Docker Compose in our separate companion guide.

Where are Docker container logs stored?

Docker’s logging engine has a plugin-based architecture. To change where logs are stored, you can switch between different logging drivers.

By default, Docker stores log messages locally using the json-file driver. Each log message is saved as a JSON object in a single text file. The file is usually located at /var/lib/docker/containers/<container id>/<container-id>-json.log, but you can run the following command to find the exact path for a specific container:

$ docker inspect demo-nginx --format='{{.LogPath}}'
/var/lib/docker/containers/cc316e105c8edb542526a3f4edcb0f6e75a4706d9ab0d207bd013e47c0d4a7eb/cc316e105c8edb542526a3f4edcb0f6e75a4706d9ab0d207bd013e47c0d4a7eb-json.log

Local logging is convenient during development, but it’s unsuitable for use in production environments. Other built-in log drivers let you send your logs to external observability platforms, ready to archive and search. Docker includes drivers for Amazon CloudWatch, Fluentd, Google Cloud Logging, and Splunk, among others.

You can configure the active log driver by editing your Docker daemon config file, typically found at /etc/docker/daemon.json. If you’re using Docker Desktop, you can view and edit the file by heading to the app’s Settings screen, then selecting “Docker Engine” from the left sidebar:

Within your daemon config file, the log-driver key specifies the name of the logging driver to use, while log-opts passes options to that driver. You should refer to the documentation for your chosen driver to learn which options are supported.

The following example provides a simple demo of how to save logs to a Fluentd instance that’s running locally on your machine:

{
	"log-driver": "fluentd",
	"log-opts": {
		"fluentd-address": "127.0.0.1:24224"
	}
}

You must restart the Docker daemon after you make changes to the file:

$ sudo service docker restart

You can also customize the active log driver and its config options on a per-container basis. Passing --log-driver and --log-opt flags to docker run will override the defaults provided by your daemon settings:

$ docker run -d --name demo-nginx --log-driver=fluentd --log-opt fluentd-address=127.0.0.1:24224 nginx:latest

How long are Docker container logs retained?

Docker container logs are retained based on the logging driver configuration and system storage limits. By default, the json-file driver stores logs indefinitely until disk space fills up. However, most setups use log rotation settings to limit this:

  • max-size: limits log file size (e.g., 10m)
  • max-file: limits number of log files (e.g., 3)

Together, they control log retention. For example, max-size=10m and max-file=3 retains up to 30MB of logs per container.

How to clear Docker container logs

To clear Docker container logs, truncate the container’s json.log file directly on the host. For example:

truncate -s 0 /var/lib/docker/containers/<container-id>/<container-id>-json.log

This clears the log without removing the container. Replace <container-id> with the actual ID. Ensure the container uses the default json-file logging driver, or this won’t apply. For log rotation, consider configuring log-opts in Docker’s daemon.json.

Best practices for managing Docker container logs

Here are some best practices for advanced log management in Docker:

  1. Use a centralized logging system: Forward logs to systems like ELK Stack, Fluentd, or Loki. This enables persistent storage, querying, and visualization, as container logs are ephemeral and lost if a container crashes or is removed.
  2. Log to STDOUT/STDERR: Design containers to emit logs to standard output and error streams. Docker captures these automatically and integrates well with log drivers and log forwarders, avoiding filesystem complexity inside containers.
  3. Rotate and limit logs: Configure Docker’s log driver with options like max-size and max-file to prevent disk exhaustion.
  4. Use structured logging (e.g., JSON): Output log data in a structured format to make indexing and parsing easier in centralized systems. Most logging platforms support JSON, enabling efficient filtering and aggregation.

We also encourage you to explore the ways Spacelift offers full flexibility when it comes to customizing your workflow. You can bring your own Docker image and use it as a runner to speed up deployments that leverage third-party tools. Spacelift’s official runner image can be found here.

 

If you want to learn more about what you can do with Spacelift, check out this article, create a free account today, or book a demo with one of our engineers.

Key points

Docker container logs capture the standard output and error stream messages emitted by your container’s foreground process. You can view a container’s logs using the docker logs command, the Docker Desktop interface, or docker compose logs for Compose applications. Regular log monitoring helps you detect unusual activity and debug any container problems.

Because container logging is a standardized mechanism, similar tools to docker logs are available in other container tools and environments. For instance, you can use kubectl logs to get the logs from containers running in a Kubernetes Pod. The log content will be equivalent to that shown by docker logs for a container running the same image.

Finally, it’s worth noting that plain log files aren’t enough to effectively monitor containers at scale. When you’re collecting container logs in production, you should use the settings we’ve highlighted above to configure an external log driver such as Fluentd or Splunk. External solutions let you index, search, and retain logs indefinitely for a more robust container observability experience.

Solve your infrastructure challenges

Spacelift is a flexible orchestration solution for IaC development. It delivers enhanced collaboration, automation, and controls to simplify and accelerate the provisioning of cloud-based infrastructures.

Learn more