Docker Cheatsheet

27

Containers without the confusion

The Docker commands you'll actually use day to day

Official docs →
Images & containersVolumes & networksCompose

Last updated: 2026-03-29

Docker is one of those tools that feels like overkill until you deploy to production for the first time without it — and then you never go back. At its core, Docker just packages your app and its environment into a portable unit called a container. Same code, same dependencies, same behavior, whether it's running on your laptop, your CI pipeline, or a server in Frankfurt.

The mental model is simple: images are blueprints, containers are running instances of those blueprints. You build an image once, then spin up as many containers from it as you need. Volumes persist data beyond a container's lifecycle, and networks let containers talk to each other. Docker Compose ties it all together when you need multiple services working in concert.

We've organized this by the resources you're working with — images, containers, volumes, networks — and then Docker Compose gets its own section because it's practically its own tool at this point. Start with Images and Containers if you're new. Once those feel natural, volumes and networks will click fast. And if you're running anything with more than one service, Compose is where you'll live.

One golden rule: don't put data you care about inside a container without a volume. Containers are ephemeral by design. When they're gone, everything inside them is gone too. Volumes are your lifeline.

Images
docker build -t <name> .
Build an image from the Dockerfile in the current directory
docker build -t <name>:<tag> .
Build and tag an image with a specific version
docker build --no-cache -t <name> .
Build from scratch, ignoring cached layers
docker pull <image>
Download an image from a registry (Docker Hub by default)
docker push <image>
Upload an image to a registry
docker images
List all locally stored images
docker images -q
List image IDs only (handy for scripting)
docker tag <image> <new:tag>
Create a new tag pointing to an existing image
docker rmi <image>
Remove an image
docker rmi $(docker images -q -f dangling=true)
Remove all dangling (untagged) images
docker image prune
Remove unused images (dangling ones)
docker image prune -a
Remove all images not used by any container
docker history <image>
Show the layer history of an image
docker inspect <image>
Show detailed metadata about an image in JSON
Containers
docker run <image>
Create and start a container from an image
docker run -d <image>
Run a container in the background (detached mode)
docker run -it <image> sh
Run interactively with a shell (great for debugging)
docker run -p 8080:80 <image>
Map host port 8080 to container port 80
docker run --name <name> <image>
Run a container with a human-friendly name
docker run --rm <image>
Automatically remove the container when it exits
docker run -e KEY=value <image>
Pass an environment variable into the container
docker run --env-file .env <image>
Load environment variables from a file
docker ps
List running containers
docker ps -a
List all containers, including stopped ones
docker start <container>
Start a stopped container
docker stop <container>
Gracefully stop a running container (SIGTERM, then SIGKILL)
docker kill <container>
Immediately kill a running container (SIGKILL)
docker restart <container>
Stop and start a container
docker exec -it <container> sh
Open a shell inside a running container
docker exec <container> <cmd>
Run a one-off command inside a running container
docker logs <container>
Show stdout/stderr from a container
docker logs -f <container>
Follow logs in real time (like tail -f)
docker logs --tail 100 <container>
Show the last 100 lines of logs
docker rm <container>
Remove a stopped container
docker rm -f <container>
Force-remove a container, even if running
docker rm $(docker ps -aq)
Remove all stopped containers
docker cp <container>:/path /local
Copy files from a container to your host
docker inspect <container>
Show detailed container metadata as JSON
docker stats
Live stream of CPU, memory, and network usage for all containers
Volumes
docker volume create <name>
Create a named volume
docker run -v <vol>:/data <image>
Mount a named volume at /data inside the container
docker run -v $(pwd):/app <image>
Bind-mount the current directory into the container
docker run -v $(pwd):/app:ro <image>
Bind-mount as read-only (container cannot write to it)
docker volume ls
List all volumes
docker volume inspect <name>
Show details about a volume (mount point, driver, etc.)
docker volume rm <name>
Remove a volume
docker volume prune
Remove all volumes not used by any container
Networks
docker network create <name>
Create a user-defined bridge network
docker network create --driver overlay <name>
Create an overlay network (for Swarm / multi-host)
docker run --network <name> <image>
Run a container attached to a specific network
docker network connect <net> <container>
Connect a running container to a network
docker network disconnect <net> <container>
Disconnect a container from a network
docker network ls
List all networks
docker network inspect <name>
Show network details including connected containers
docker network rm <name>
Remove a network
docker network prune
Remove all unused networks
Docker Compose
docker compose up
Create and start all services defined in compose.yaml
docker compose up -d
Start services in the background
docker compose up --build
Rebuild images before starting services
docker compose up <service>
Start only a specific service (and its dependencies)
docker compose down
Stop and remove containers, networks created by up
docker compose down -v
Same as down, but also remove named volumes
docker compose down --rmi all
Stop everything and remove images too
docker compose build
Build or rebuild all service images
docker compose build --no-cache
Rebuild all images from scratch
docker compose logs
Show logs from all services
docker compose logs -f <service>
Follow logs for a specific service
docker compose ps
List containers managed by Compose
docker compose exec <service> sh
Open a shell in a running service container
docker compose run <service> <cmd>
Run a one-off command in a new container for that service
docker compose pull
Pull the latest images for all services
docker compose restart <service>
Restart a specific service
docker compose config
Validate and display the resolved Compose config
System & Cleanup
docker system df
Show disk usage by images, containers, and volumes
docker system prune
Remove stopped containers, unused networks, and dangling images
docker system prune -a --volumes
The nuclear option — reclaim all unused space
docker info
Show system-wide Docker configuration and stats
docker version
Show Docker client and server versions

Use docker run --rm for throwaway containers. Without it, stopped containers pile up silently. Run docker ps -a sometime — you might be surprised how many zombies are lurking.

Add a .dockerignore file to your project. It works like .gitignore but for builds. Excluding node_modules, .git, and local config files can shrink your build context from gigabytes to kilobytes and speed up builds dramatically.

Order your Dockerfile instructions from least to most frequently changed. Docker caches layers top-down, so putting COPY package.json and RUN npm install before COPY . . means you only reinstall dependencies when they actually change — not on every code edit.

Use docker compose up --build during development instead of separate build and up steps. It rebuilds only what changed and saves you from the classic "why isn't my change showing up" head-scratcher.

Run docker system prune regularly. Docker is surprisingly good at hoarding disk space. Add -a --volumes if you want to go scorched earth, but be careful — that removes everything not actively in use, including named volumes with data.

Prefer docker compose exec over docker exec when using Compose. You can reference services by name instead of hunting for container IDs. docker compose exec db psql -U postgres beats copying a 12-character hash every time.

Use multi-stage builds to keep production images lean. Build your app in one stage with all the dev dependencies, then copy just the compiled output into a minimal base image. Your 1.2 GB Node image becomes 150 MB.

Related Tools