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 starts an additional process inside an already running container. The most common use is an interactive shell:
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:
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 directoryexec only works on running containers. If the container has exited, use docker logs to see why.
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:
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 timestampOnly 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 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:
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}}' webUseful 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 copies files between the host and a container's filesystem, in either direction, and works even when the container is stopped:
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.jsonThe 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.
Three small commands complete the picture:
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 startdocker 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.
Why does an application that writes its log to `/var/log/app.log` inside the container produce nothing in `docker logs`?
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.