Why “run” and “inspect” are the core of day-to-day Docker
Once you already understand what images and containers are and how Dockerfiles build images, most of your daily work becomes a tight loop: start a container, verify it is doing what you expect, look inside it when something is off, and stop or remove it cleanly. This chapter focuses on the core commands used in that loop, with practical, repeatable steps and the mental model for what each command shows you.
We will use a few small examples (a web server, a database, and a “sleeping” container) to practice. The goal is not to memorize flags, but to know which command answers which question: “Is it running?”, “What ports are open?”, “What is it logging?”, “What environment variables did it get?”, “What files are in the container?”, “Why did it exit?”, and “How do I clean up?”
Running containers: docker run as the all-in-one starter
docker run creates a new container from an image and starts it. It is effectively a shortcut for “create + start” with configuration in one command. The most common things you decide at run time are: container name, whether it runs in the background, port publishing, environment variables, and volume mounts.
Basic run patterns
1) Run a container in the foreground (attached):
docker run nginx:alpineThis will attach your terminal to the container’s main process. If that process writes to stdout/stderr, you will see it. If you stop it with Ctrl+C, the container stops.
Continue in our app.
You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.
Or continue reading below...Download the app
2) Run in the background (detached):
docker run -d nginx:alpineDetached mode returns you to your shell immediately and prints a container ID. The container keeps running in the background.
3) Give the container a friendly name:
docker run -d --name web nginx:alpineNaming is practical because many other commands accept a name instead of a long ID.
4) Publish a port from container to host:
docker run -d --name web -p 8080:80 nginx:alpineThis maps host port 8080 to container port 80. You can now access the service via http://localhost:8080 on the host.
5) Set environment variables:
docker run -d --name demo-env -e APP_MODE=dev -e FEATURE_X=true nginx:alpineEnvironment variables are a common way to configure containers at runtime.
6) Mount a host directory into the container (bind mount):
docker run -d --name web -p 8080:80 -v "$PWD/site":/usr/share/nginx/html:ro nginx:alpineThis serves files from your local site folder. The :ro makes it read-only inside the container.
Choosing between --rm and keeping containers
For short-lived experiments, you often want the container removed automatically when it exits:
docker run --rm alpine:3.20 echo "hello from a temporary container"--rm is great for one-off commands. For services you want to inspect after stopping (logs, exit codes, configuration), do not use --rm so you can examine the container after it exits.
Overriding the default command
Many images define a default command. You can override it by appending a command to docker run:
docker run --rm alpine:3.20 ls -laThis runs ls -la inside the container and then exits.
Interactive containers: -it
When you need a shell or interactive program, use -it (interactive + pseudo-TTY):
docker run --rm -it alpine:3.20 shYou are now inside the container. Type exit to leave.
Listing and identifying containers: docker ps
After starting containers, the first inspection question is usually “What is running right now?”
docker psThis shows running containers. Key columns include:
- CONTAINER ID: short ID you can use in commands
- IMAGE: which image it was created from
- COMMAND: the main process command
- STATUS: running time or exit status
- PORTS: published ports, if any
- NAMES: friendly name (auto-generated if you didn’t set one)
To see all containers, including stopped ones:
docker ps -aThis is essential when a container exits quickly and disappears from docker ps but still exists and can be inspected.
Practical step-by-step: spot a container that exited
1) Run a container that exits immediately:
docker run --name quick alpine:3.20 sh -c "echo done; exit 2"2) Check running containers (you won’t see it):
docker ps3) Check all containers (you will see it with an exit code):
docker ps -a4) You can now inspect why it exited using logs and exit code (covered below).
Watching logs: docker logs
Containers typically write application output to stdout/stderr. Docker captures that output, and docker logs lets you view it.
docker logs webCommon options:
-f: follow (stream) logs liketail -f--tail N: show only the last N lines--since 10m: show logs since a time (e.g., 10 minutes)-t: show timestamps
docker logs -f --tail 50 webWhen debugging, logs are usually the first place to look. If a container exits immediately, docker logs often tells you what failed (missing config, permission issues, port conflicts inside the app, etc.).
Starting, stopping, restarting: docker start, docker stop, docker restart
These commands manage container lifecycle after creation.
docker stopsends a graceful stop signal and waits before forcing termination.docker startstarts an existing stopped container.docker restartstops then starts.
docker stop webdocker start webdocker restart webWhy this matters: if you created a container with a specific name, port mapping, environment variables, and mounts, docker start reuses that configuration. You do not need to retype the full docker run command.
Force stopping: docker kill
If a container does not stop gracefully, you can force it:
docker kill webUse this sparingly; it is similar to abruptly terminating a process.
Inspecting container details: docker inspect
docker inspect returns a detailed JSON document about a container (or image, network, volume). It is the most complete source of truth for “what did Docker actually configure?”
docker inspect webThe output is large. In practice, you often filter it using Go template formatting:
docker inspect -f '{{.State.Status}}' webdocker inspect -f '{{.State.ExitCode}}' quickdocker inspect -f '{{.Name}}' webUseful inspection targets:
- State: running, exited, paused; start/finish timestamps; exit code
- Config: environment variables, command, working directory
- HostConfig: port bindings, mounts, restart policy
- NetworkSettings: container IP, networks, exposed ports
Practical step-by-step: find the host port mapped to a container port
Sometimes you used -p 0:80 (random host port) or you forgot what you mapped. You can query it.
1) Run with a random host port:
docker run -d --name web-random -p 0:80 nginx:alpine2) Inspect the port mapping:
docker inspect -f '{{json .NetworkSettings.Ports}}' web-random3) Or use docker ps to see the published port in a human-friendly way:
docker ps --filter name=web-randomExecuting commands inside a running container: docker exec
docker exec runs a new process inside an already running container. This is different from docker run, which creates a new container. Use exec for live troubleshooting: checking files, testing connectivity, viewing environment variables, or running admin commands.
Example: open a shell in a running container:
docker exec -it web shExample: run a single command:
docker exec web ls -la /usr/share/nginx/htmlExample: check environment variables from inside:
docker exec demo-env sh -c 'env | sort | head'Practical step-by-step: verify a web server is serving the files you expect
1) Create a local folder and file:
mkdir -p site && printf '<h1>Hello from bind mount</h1>' > site/index.html2) Run Nginx with the bind mount:
docker run -d --name web-mount -p 8081:80 -v "$PWD/site":/usr/share/nginx/html:ro nginx:alpine3) Inspect the container’s filesystem path:
docker exec web-mount ls -la /usr/share/nginx/html4) Confirm the file content:
docker exec web-mount sh -c 'cat /usr/share/nginx/html/index.html'5) Check logs if the page is not loading:
docker logs --tail 50 web-mountCopying files to/from containers: docker cp
Sometimes you need to extract a generated file (a report, a build artifact) or inject a config file for quick testing. docker cp copies files between your host and a container.
Copy from container to host:
docker cp web-mount:/etc/nginx/nginx.conf ./nginx.confCopy from host to container:
docker cp ./nginx.conf web-mount:/etc/nginx/nginx.confNote: if you copy into a running container, the application may need a reload/restart to pick up changes. For many services, a restart is the simplest approach:
docker restart web-mountViewing resource usage: docker stats
When a container feels slow or your laptop fan spins up, you want a quick view of CPU and memory usage.
docker statsThis shows live metrics per running container. You can also target a specific container:
docker stats webUse this to confirm whether a container is consuming unexpected resources, and to compare multiple containers at once.
Seeing processes inside containers: docker top
docker top lists processes running inside a container (from the host’s perspective).
docker top webThis is useful when:
- You suspect the main process spawned child processes
- You want to confirm which command is actually running
- You need a quick check without opening a shell via
docker exec
Understanding networking at a glance: docker port
While docker inspect can show port bindings, docker port is a quick shortcut to display published ports.
docker port webOr for a specific container port:
docker port web 80This answers “Which host port is mapped to container port 80?” without parsing JSON.
Container events and “what just happened?”: docker events
When troubleshooting intermittent issues, it helps to see a stream of Docker events: container start/stop/die, network connect/disconnect, and more.
docker eventsFilter by container:
docker events --filter container=webFilter by time window:
docker events --since 30mThis is especially useful when containers are managed by scripts and you want to confirm the order of operations.
Cleaning up: removing containers with docker rm and pruning
Stopped containers take disk space (logs and metadata). Removing them keeps your environment tidy.
Remove a stopped container:
docker rm quickRemove a running container (force):
docker rm -f webRemove multiple containers by name/ID:
docker rm web web-mount web-randomPractical step-by-step: clean up everything from this chapter
1) List all containers you created:
docker ps -a2) Stop running ones:
docker stop web web-mount web-random demo-env 2>/dev/null3) Remove them:
docker rm web web-mount web-random demo-env quick 2>/dev/null4) Optionally remove unused stopped containers in general:
docker container prunedocker container prune removes all stopped containers. It will ask for confirmation.
A practical troubleshooting workflow using core commands
When a container does not behave as expected, you can follow a consistent sequence. This is a practical “decision tree” you can apply to most beginner projects.
Scenario: “My container isn’t reachable in the browser”
1) Is it running?
docker ps --filter name=webIf it’s not running, check all containers:
docker ps -a --filter name=web2) Did it exit? What exit code?
docker inspect -f '{{.State.Status}} {{.State.ExitCode}}' web3) What do the logs say?
docker logs --tail 100 web4) Are ports published as expected?
docker port webOr:
docker ps --filter name=web5) If it’s running but still not working, check inside quickly:
docker exec -it web shThen verify the service is listening and files exist (commands vary by image; for Alpine-based images you might use basic tools available in the image). If the image is minimal and lacks tools, you can still inspect config files and directory contents with ls and cat.
Scenario: “It worked yesterday; what changed?”
1) Compare configuration via inspect (environment, mounts, ports):
docker inspect web2) Look for recent restarts or failures:
docker events --since 2h --filter container=web3) Watch resource usage while reproducing the issue:
docker stats webReference cheat sheet: core commands and the question they answer
docker run: “Start a new container with these settings.”docker ps: “What is running?”docker ps -a: “What exists (including stopped)?”docker logs: “What did the app output?”docker stop/start/restart: “Control lifecycle of an existing container.”docker inspect: “Show the full configuration and state details.”docker exec: “Run a command inside a running container.”docker cp: “Copy files between host and container.”docker stats: “How much CPU/memory is it using?”docker top: “Which processes are running inside?”docker port: “Which host ports map to container ports?”docker events: “What Docker actions occurred over time?”docker rm/docker container prune: “Remove containers and clean up.”