CertGrid CertGrid
Troubleshooting·Docker

Inspecting Docker Containers and Processes

How to answer the four questions you ask when something is wrong: what state is it in, what is it printing, what is it running, and what is it consuming. Every command below was run against a live nginx container.

Containers and Images Guide 7 of 46 Beginner

Tested on the versions above. PIDs, IP addresses, timestamps and memory figures change on every run. Match the shape of the output, not the exact strings.

One Docker host is all this guide needs. Nothing here depends on a second machine, and the hardware above is modest on purpose - a 2 core, 4 GB VM runs everything in this path.
Server NameIP AddressOSRolesCPURAMHDD
DOCKER01192.168.0.21Ubuntu 26.04 LTSDocker Host2 Core4 GB50 GB

Before you start

  1. What state is it in?

    docker inspect holds the authoritative record. Three fields answer most questions: the status, when it started, and how many times it has restarted. A restart count climbing on its own is the signature of a crash loop, and it is invisible in docker ps because the container keeps reappearing as Up.

    bash Example session
    docker inspect cg-web --format "{{.State.Status}} started={{.State.StartedAt}} restarts={{.RestartCount}}"running started=2026-08-20T05:22:55.200044778Z restarts=0

    Expected resultStatus running, a start timestamp, and a restart count.

    Success conditionrestarts=0. Anything above zero on a container you did not restart yourself means it has been failing and being brought back.

  2. What is it printing?

    Logs are the container's stdout and stderr. --tail limits how far back you look and --timestamps prefixes each line with when Docker received it, which matters when you are correlating against another system's clock. Add -f to follow live.

    bash Example session
    docker logs --tail 3 --timestamps cg-web2026-08-20T05:22:55.324669532Z 2026/08/20 05:22:55 [notice] 1#1: start worker process 302026-08-20T05:22:55.325074936Z 2026/08/20 05:22:55 [notice] 1#1: start worker process 312026-08-20T05:22:55.357433243Z 172.17.0.1 - - [20/Aug/2026:05:22:55 +0000] "GET / HTTP/1.1" 200 896 "-" "curl/8.18.0" "-"

    Expected resultThree lines, each with a Docker timestamp followed by the application's own log line.

    Success conditionYou see recent activity. If a container exited, its logs remain readable until the container is removed - that is where the reason will be.

  3. What is it actually running?

    docker top lists the processes inside the container as the host sees them. Two things are worth noticing: the PIDs are host PIDs, not the PID 1 the container sees internally, and the user column shows the real account each process runs as. Here nginx starts as root then drops its workers to an unprivileged user.

    bash Example session
    docker top cg-webUID     PID    PPID   C   STIME   TTY   TIME       CMDroot    3633   3610   0   05:22   ?     00:00:00   nginx: master process nginx -g daemon off;pollina+ 3720  3633   0   05:22   ?     00:00:00   nginx: worker process

    Expected resultA master process and one or more workers. Output is abridged - the real listing includes every worker.

    Success conditionYou can see the process tree. If only one unexpected process is listed, the container may be running something other than what you intended - check docker inspect --format "{{.Config.Cmd}}".

  4. What is it consuming?

    docker stats streams live resource usage. --no-stream takes one sample and exits, which is what you want in a script or a guide. The memory limit shown is the host's total when no limit has been set on the container - that is worth knowing, because an unlimited container can consume everything the host has.

    bash Example session
    docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}" cg-webNAME      CPU %     MEM USAGE / LIMIT     NET I/Ocg-web    0.00%     10.78MiB / 3.319GiB   1.51kB / 1.68kB

    Expected resultOne row of live figures. An idle nginx uses almost no CPU and around 10 MiB.

    Success conditionYou get a sample and the command exits. If the LIMIT column shows the host's full memory, no limit is set on this container.

  5. Look inside without restarting anything

    When the outside view is not enough, run a command inside. This is read-only investigation - checking a version, listing a config directory, reading a file the application uses.

    bash
    docker exec cg-web nginx -vnginx version: nginx/1.31.4docker exec cg-web sh -c "ls /etc/nginx/conf.d"default.conf

    Expected resultThe version banner and the directory listing.

    Success conditionBoth commands return. If exec fails with No such container, the container has stopped - exec only works on running containers.

  6. Where is it reachable?

    docker port reports the published mappings without you having to parse inspect output. Both an IPv4 and an IPv6 mapping appear because Docker publishes on both families by default.

    bash
    docker port cg-web80/tcp -> 0.0.0.0:808080/tcp -> [::]:8080

    Expected resultOne line per published port per address family.

    Success conditionThe container port appears on the left and the host binding on the right. Empty output means nothing was published - the container is only reachable from other containers.

Troubleshooting

Official sources