Docker Images and Containers: Pull, Run, Inspect & Manage
Learn how Docker images and containers work. Covers docker pull, docker run, port mapping, volumes, environment variables, docker ps, docker logs, and container lifecycle.

You know what Docker is and have it installed. Now it's time to actually use it. This lesson covers the two most fundamental Docker objects — images and containers — and the commands you'll use constantly: docker pull, docker run, docker ps, docker logs, and docker stop.
By the end, you'll be comfortable pulling images from Docker Hub and running containers with port mapping, environment variables, and volumes.
Docker Images in Depth
An image is a layered, read-only filesystem snapshot. Layers are stacked on top of each other, and each layer only stores the changes from the layer below it — this is called a union filesystem.
myapp image:
Layer 5: COPY . /app (your source code — changes often)
Layer 4: RUN npm install (dependencies — changes when package.json changes)
Layer 3: RUN apt-get install (system packages — rarely changes)
Layer 2: node:20-slim (Node.js 20 base — rarely changes)
Layer 1: debian:bookworm-slim (OS base — almost never changes)Layers are cached and shared. If two images share the same base layer (debian:bookworm-slim), Docker only stores that layer once on disk. This makes images efficient to store and fast to build when only the top layers change.
Image Tags
Images are identified by a name and a tag: name:tag. The tag usually represents a version:
nginx:1.25 # specific version
nginx:latest # most recent (default if no tag specified)
node:20-alpine # Node.js 20 on Alpine Linux (tiny base image)
postgres:16 # PostgreSQL 16Never use latest in production — it changes over time and breaks reproducibility. Pin to a specific version.
Pulling Images from Docker Hub
docker pull downloads an image to your local machine without running it:
docker pull nginx:1.25
docker pull node:20-alpine
docker pull postgres:16List Local Images
docker images
# or
docker image lsOutput:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx 1.25 a0e45e2ce6e6 2 weeks ago 187MB
node 20-alpine 3fdefedb2fce 3 weeks ago 131MB
postgres 16 b781f3a53e61 1 month ago 431MBRemove an Image
docker rmi nginx:1.25Running Containers: docker run
Port Mapping: -p
docker run -p 8080:80 nginx:1.25Format: -p HOST_PORT:CONTAINER_PORT. This maps port 80 inside the container to port 8080 on your machine. Open http://localhost:8080 — you'll see the nginx welcome page.
Run in the Background: -d
docker run -d -p 8080:80 nginx:1.25Without -d, the container's output is attached to your terminal and stops when you press Ctrl+C. With -d, it runs in the background and returns the container ID.
Name a Container: --name
docker run -d -p 8080:80 --name my-nginx nginx:1.25Named containers are easier to reference than their random IDs.
Environment Variables: -e
docker run -d \
-e POSTGRES_USER=myuser \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
--name my-postgres \
postgres:16Volumes: -v
Containers are ephemeral — data written inside a container is lost when the container is removed. Volumes mount a directory from your host into the container, making data persistent:
docker run -d \
-v /my/local/data:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=secret \
--name my-postgres \
postgres:16Format: -v HOST_PATH:CONTAINER_PATH
Run Interactively: -it
docker run -it ubuntu:22.04 bash-i keeps stdin open. -t allocates a pseudo-TTY. Together, they give you an interactive shell inside the container. Type exit to leave.
Managing Running Containers
List Containers
docker ps # running containers only
docker ps -a # all containers (including stopped)View Logs
docker logs my-nginx
docker logs -f my-nginx # follow logs in real time
docker logs --tail 50 my-nginx # last 50 linesExecute a Command in a Running Container
docker exec -it my-nginx bashThis opens a shell inside an already-running container without stopping it. Extremely useful for debugging.
Stop and Start Containers
docker stop my-nginx # graceful shutdown (SIGTERM, then SIGKILL after 10s)
docker start my-nginx # restart a stopped container
docker restart my-nginx # stop + start
docker kill my-nginx # immediate SIGKILLRemove Containers
docker rm my-nginx # remove a stopped container
docker rm -f my-nginx # force-remove a running container
docker container prune # remove all stopped containersInspect Container Details
docker inspect my-nginxReturns a JSON object with everything about the container: image, networking, mounts, environment variables, resource limits.
# Live resource usage for all running containers
docker statsContainer Lifecycle Summary
docker run → Created → Running
docker stop → Running → Stopped (exited)
docker start → Stopped → Running
docker rm → Stopped → Removed (gone)
docker rm -f → Running → Removed (gone)A stopped container still exists on disk — you can restart it or inspect its logs. It's only permanently gone after docker rm.
Quick Reference: Most Used Commands
| Command | What It Does |
|---|---|
docker pull name:tag | Download an image |
docker images | List local images |
docker rmi name:tag | Remove an image |
docker run -d -p H:C name:tag | Run container in background with port mapping |
docker run -it name:tag bash | Run container interactively |
docker ps | List running containers |
docker ps -a | List all containers |
docker logs name | View container output |
docker exec -it name bash | Shell into running container |
docker stop name | Gracefully stop container |
docker rm name | Remove stopped container |
docker stats | Live resource usage |
docker inspect name | Full container details (JSON) |
Previous: Lesson 2 — Install Docker | Next: Lesson 4 — Dockerfile Guide
Part of the Docker & Kubernetes Mastery course.
External references:
