Dash0 Raises $110M Series B at $1B Valuation

  • 11 min read

Where to Find Docker Daemon Logs

The Docker daemon logs are what dockerd itself writes: startup messages, image pull errors, networking failures, plugin load issues, signals the daemon received. They are separate from container logs, which capture what your applications inside containers send to stdout and stderr. If your container is broken, you want container logs. If Docker itself is misbehaving (won't start, hangs, fails to pull, mysteriously kills containers), the daemon log is where the answer lives.

Where those logs end up depends on your operating system and how Docker was installed. The rest of this article walks through each platform, then covers how to crank up the verbosity when the default info level isn't telling you enough.

Linux with systemd

On any current Linux distribution with systemd (Ubuntu, Debian, Fedora, RHEL, Rocky, Alma, and so on), the Docker daemon runs as a systemd service and writes to the journal. View the logs with:

bash
1
journalctl -u docker.service

A few flags that make this more useful in practice:

bash
1234567891011
# Follow live, like tail -f
journalctl -u docker.service -f
# Last hour only
journalctl -u docker.service --since "1 hour ago"
# Errors and worse
journalctl -u docker.service -p err
# Include extended fields and context
journalctl -xu docker.service

Representative output looks like this:

text
123
Mar 14 09:32:17 host-01 dockerd[1234]: time="2026-03-14T09:32:17.123456789Z" level=info msg="Starting up"
Mar 14 09:32:17 host-01 dockerd[1234]: time="2026-03-14T09:32:17.456789012Z" level=info msg="Loading containers: start."
Mar 14 09:32:18 host-01 dockerd[1234]: time="2026-03-14T09:32:18.789012345Z" level=info msg="Daemon has completed initialization"

journald stores these in a binary format under /var/log/journal/, which is why you can't just cat them. journalctl is the tool. If you work with the journal a lot, Dash0's guide on managing systemd logs with journalctl goes deeper on filtering, exporting, and persistence.

On a non-systemd Linux box, or on a system customized to log to syslog or rsyslog, check /var/log/syslog, /var/log/messages, or /var/log/docker.log and grep for dockerd:

bash
1
sudo grep dockerd /var/log/syslog | tail -100

Docker Desktop on macOS and Windows

Docker Desktop runs the Docker daemon inside a small Linux virtual machine (VM) and exposes the VM's logs as files on the host filesystem. There's a dockerd.log for the daemon itself and a containerd.log for the runtime underneath it.

On macOS:

bash
1
tail -f ~/Library/Containers/com.docker.docker/Data/log/vm/dockerd.log

On Windows with WSL2:

powershell
1
Get-Content -Path "$env:LOCALAPPDATA\Docker\log\vm\dockerd.log" -Tail 100 -Wait

If you want a packaged diagnostic bundle to share with support, click the Docker Desktop tray icon and choose Troubleshoot.

Windows Server with Windows containers

Native Windows containers (not Docker Desktop) log to the Windows Event Log rather than to a flat file. They show up under Windows Logs → Application in Event Viewer, filtered by source Docker, or through PowerShell:

powershell
1
Get-EventLog -LogName Application -Source Docker -Newest 100

"I think I actually want container logs"

If you got here looking for what your application inside a container wrote to stdout, that's a different thing. The default json-file log driver stores per-container logs at:

text
1
/var/lib/docker/containers/<container-id>/<container-id>-json.log

You almost never want to read those files directly. docker logs <container> returns the same content and handles whatever logging driver you have configured. The how to view Docker container logs article covers this in detail, and Mastering Docker logs goes further into log drivers, rotation, and shipping logs out of the host.

Enable debug logging

The default daemon log level is info, which surfaces startup events, errors, and major lifecycle messages but skips the per-API-call detail you usually need when something weird is going on. Switch to debug when the default output isn't enough.

The recommended way is via daemon.json. On Linux, edit /etc/docker/daemon.json (create it if it doesn't exist) and add:

json
1234
{
"debug": true,
"log-level": "debug"
}

Then signal the daemon to reload its config without a full restart:

bash
1
sudo kill -SIGHUP $(pidof dockerd)

Verify it took effect:

bash
1
docker info --format '{{.Debug}}'
text
1
true

On Docker Desktop, don't edit daemon.json directly. Open Settings, then Docker Engine, change the JSON there, and click Apply & Restart.

If you'd rather restart the daemon manually, the -D flag (short for --debug) enables debug logging from the command line:

bash
12
sudo systemctl stop docker
sudo dockerd -D

This is fine for a quick experiment but not for a production host. Running dockerd manually outside of systemd means it inherits your shell's environment instead of the one systemd sets up, which can change behavior in subtle ways and make debugging harder rather than easier.

Configure log level and format in daemon.json

The same daemon.json file accepts several keys that affect what and how the daemon logs:

json
12345
{
"debug": false,
"log-level": "info",
"log-format": "json"
}

debug: true enables debug-level logging plus a few extra debug-only behaviors. If both debug: true and log-level are set, debug: true takes precedence: the daemon logs at debug level regardless of what log-level says. The official Docker docs recommend keeping log-level at info or debug when debug: true is also set, to avoid confusion. log-level accepts debug, info, warn, error, fatal, with info as the default. log-format accepts text (the legacy default) or json. JSON is much easier to grep and parse if you're shipping logs anywhere downstream.

Don't confuse these with the log-driver and log-opts keys in the same file. Those configure where container logs go (journald, syslog, fluentd, and so on), not how the daemon itself logs. The container logging driver docs cover those separately.

After editing, send SIGHUP (sudo kill -SIGHUP $(pidof dockerd)) or restart the service. On Docker Desktop, click Apply & Restart.

Common pitfalls

The most common confusion is expecting docker logs to show daemon logs. It doesn't. It shows container logs. There's no docker daemon-logs subcommand either; daemon logs come from the host's logging subsystem: journalctl, the Docker Desktop VM log file, or the Windows Event Log.

Debug mode is also loud. A busy daemon at debug produces a lot of output, with every API call and every container lifecycle event recorded. The CIS Docker Benchmark explicitly recommends running production daemons at info for this reason. Turn debug back off when you're done; leaving it on indefinitely fills disk and tanks the signal-to-noise ratio of future investigations.

Be aware that SIGHUP doesn't reload everything. Changes to debug and log-level in daemon.json get picked up by SIGHUP, but many other keys like data-root, storage-driver, or default-runtime require a full daemon restart. If you've changed a setting and it doesn't seem to take effect, run sudo systemctl restart docker.

A frequent dead end is /var/log/docker.log. You'll still find blog posts and Stack Overflow answers that point to it as the canonical location, but on any modern systemd-based install that file either doesn't exist or contains nothing useful. Use journalctl -u docker.service instead.

One last thing for Docker Desktop users: the VM log files get rotated and effectively wiped each time you quit and reopen Docker Desktop. If you're chasing a startup issue, capture the log before you restart Docker Desktop, not after.

Final thoughts

Once you've found the answer in the daemon log, the next step is usually to keep that information available without SSH-ing into the host every time something looks off. Shipping daemon logs alongside container logs and host metrics lets you correlate Docker engine events with application behavior across your whole fleet, and stop treating the runtime itself as a black box. On Linux, the OpenTelemetry Journald Receiver does this directly: it tails the journal and forwards everything dockerd has written, alongside whatever else is in there.

Dash0 is an OpenTelemetry-native observability platform that ingests Docker daemon and container logs through the OpenTelemetry Collector, alongside infrastructure metrics and distributed traces. The Docker engine becomes inspectable the same way the apps running on top of it are. See log management for the full pipeline. Start a free trial to see your Docker fleet, logs, and traces in one view. No credit card required.