Inspecting Containers: exec, logs, inspect, cp and stats

Beginner
12 min

Inspecting Containers: exec, logs, inspect, cp and stats

Most of your time with containers is spent finding out what a running one is doing. This lesson covers the command group you will use daily for that: running commands inside a container, reading its logs, querying its metadata, moving files in and out, and watching resource usage. By the end you will be able to diagnose a misbehaving container without guessing.

docker exec: Run Commands Inside a Container

docker exec starts an additional process inside an already running container. The most common use is an interactive shell:

bash
docker exec -it web sh # Alpine-based images ship sh, not bash docker exec -it web bash # Debian/Ubuntu-based images

-i keeps stdin open and -t allocates a pseudo-terminal; you need both for a usable shell. Without them, exec runs a single command and prints its output, ideal for scripts:

bash
docker exec web nginx -t # nginx: configuration file /etc/nginx/nginx.conf test is successful docker exec -u root web apk add --no-cache curl # run as a different user docker exec -w /usr/share/nginx/html web ls # set the working directory

exec only works on running containers. If the container has exited, use docker logs to see why.

docker logs: Read stdout and stderr

Docker captures everything the container's main process writes to standard output and standard error. docker logs reads that capture, which also works for stopped containers:

bash
docker logs web # everything so far docker logs -f web # follow, like tail -f docker logs --tail 50 web # last 50 lines docker logs --since 10m web # last ten minutes docker logs -t web # prefix each line with a timestamp

Only the main process (PID 1) is captured. An application that writes to a file inside the container is invisible to docker logs, which is why well-built images log to stdout and stderr.

docker inspect: The Full Metadata

docker inspect returns a JSON document with every detail Docker knows about an object: containers, images, volumes and networks. The output is long, so filter it with a Go template:

bash
docker inspect --format '{{.State.Status}}' web # running docker inspect --format '{{.State.ExitCode}}' web # 0 docker inspect --format '{{.Config.Image}}' web # nginx:alpine docker inspect --format '{{json .Mounts}}' web # mounts as JSON docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' web

Useful fields to remember:

| Path | What it tells you | |------|-------------------| | .State.Status, .State.ExitCode | Whether it is running and how it last exited | | .State.OOMKilled | true if the kernel killed it for exceeding its memory limit | | .Config.Env, .Config.Cmd | Environment variables and command baked into the container | | .Mounts | Volumes and bind mounts with source and destination | | .NetworkSettings.Ports | Port mappings, the same data docker port shows |

docker cp: Move Files In and Out

docker cp copies files between the host and a container's filesystem, in either direction, and works even when the container is stopped:

bash
docker cp web:/var/log/nginx/error.log ./error.log # container -> host docker cp ./site/. web:/usr/share/nginx/html/ # host dir contents -> container docker cp config.json web:/app/config.json

The path syntax is container:path; a trailing /. copies a directory's contents rather than the directory itself. Use docker cp for ad-hoc debugging only: changes made this way disappear when the container is removed, so permanent files belong in the image or in a mount.

docker stats, top and port

Three small commands complete the picture:

bash
docker stats # live table for all running containers docker stats --no-stream web # single snapshot, good for scripts docker top web # ps output for the container's processes docker port web # 80/tcp -> 0.0.0.0:8080 docker diff web # files added (A), changed (C) or deleted (D) since start

docker stats shows CPU percentage, memory usage against the limit, network and block I/O; a container pinned at 100% CPU or near its memory limit is a candidate for the limits in the next lesson. docker diff reveals whether an application writes files where it should not. Every command accepts a container name or a unique ID prefix, and the long forms (docker container logs) are equivalent aliases.

Quick Quiz
Question 1 of 3

Why does an application that writes its log to `/var/log/app.log` inside the container produce nothing in `docker logs`?

Key Takeaways

  • docker exec -it <container> sh opens a shell in a running container; without -it it runs a single command.
  • docker logs reads the captured stdout and stderr of the main process, even for stopped containers.
  • docker inspect --format extracts specific fields such as status, exit code, mounts and IP addresses.
  • docker cp moves files in either direction but its changes do not survive container removal.
  • docker stats, docker top, docker port and docker diff show resource use, processes, mappings and filesystem changes.

Next lesson: Container Lifecycle, Restart Policies and Resource Limits — control how containers stop, restart and how much CPU and memory they may use.

Inspecting Containers: exec, logs, inspect, cp and stats - Docker | CodeYourCraft | CodeYourCraft