`docker logs` vs `docker exec`: Which One to Reach for First When a Container Looks Dead
A practical Docker debugging guide that explains the difference between reading container output and entering a running container, and why using logs first often gives clearer answers than immediately opening a shell.
Why container debugging gets clumsy: the first instinct is often to “go inside the container.” But if the service is already failing loudly in stdout or stderr, a shell may be adding a layer of activity before you have even read the basic evidence.
What docker logs is for
docker logs reads the output the container has emitted to stdout and stderr. That makes it the first stop when the container starts, exits, restarts, or behaves unexpectedly.
Basic usage:
docker logs my_containerStream new output:
docker logs -f my_containerLimit to the last lines:
docker logs --tail 100 my_containerThat is usually enough to answer the first question: what is the container saying about its own failure?
What docker exec is for
docker exec runs a command inside a running container:
docker exec -it my_container shThis is useful when you need to inspect:
- environment variables
- filesystem state
- process behavior
- internal command results
But it assumes the container is still running and that getting inside is actually the next useful step.
Why logs usually come first
Because a lot of failures are already obvious once you read the emitted output:
- missing environment variables
- binding errors
- dependency startup problems
- syntax or config failures
If the service told you exactly what is wrong, exec is often unnecessary at that stage.
When exec is the right next move
Use it after logs when you need deeper inspection. For example:
- confirm a config file exists where you expect
- check whether a mounted volume contains the right data
- run a diagnostic command inside the same network and filesystem context
That is much more targeted than opening a shell by default out of panic.
A subtle but important limitation
The command you run with docker exec only works while the container’s main process is still running. If the container exits immediately, exec is not your entrypoint because there is no stable process context to enter.
That is another reason logs matter first. They still help even when the container is too short-lived to inspect interactively.
A better first-response sequence
When a container misbehaves, a good order is:
- check container state
- read recent logs
- decide whether the problem is obvious already
- only then open a shell if deeper inspection is actually needed
That sequence sounds basic, but it prevents a lot of random poking around inside containers before the simple evidence has been read.
It also makes handoffs easier, because another developer can reproduce the same first-response process instead of inheriting a pile of ad hoc shell exploration.
That repeatability is a quiet but important debugging win.
The first useful debugging habit is often just a stable order of operations.
Final recommendation
When a container looks dead, read what it said before you walk inside it. docker logs is about evidence. docker exec is about inspection. They are complementary, but they are not interchangeable. Teams often debug containers faster once they stop treating the shell as the first reflex and start treating logs as the first signal.