Docker Cheat Sheet
Every command, every flag - searchable across all tabs, filterable by level, copy-ready.
Every command, every flag - searchable across all tabs, filterable by level, copy-ready.
This Docker cheat sheet covers every command you need, from pulling images to managing full Swarm clusters. No filler. Just commands.
What's inside:
Images - build, pull, tag, save, export, commit, multi-platform builds
Containers - run flags, exec, logs, copy, diff, stats, resource limits
Volumes & Networks - named volumes, bind mounts, bridge and overlay networks
Docker Compose - full CLI reference plus docker-compose.yml structure examples
Dockerfile - every instruction explained, multi-stage builds, BuildKit cache mounts
Registry & Hub - push, pull, private registries, run your own local registry
System & Cleanup - prune commands, disk usage, safe and nuclear cleanup options
Swarm - init, services, stacks, rolling updates, secrets management
Built for all skill levels. Filter by Beginner, Intermediate, or Advanced to cut the noise. Search across all tabs instantly with /. Every snippet has a one-click copy button.
Some commands include a preview that explains flags, output format, or gotchas. The --format Go template examples, restart policies, ENTRYPOINT vs CMD differences, and BuildKit cache mount behavior are all covered inline.
No login. No paywall. Free to use.
Docker is an open-source platform for building, running, and shipping applications inside containers.
A container packages an application together with its libraries, dependencies, and configuration files so it runs the same on any machine - your laptop, a test server, or production.
Before Docker, "works on my machine" was a real problem. Dependency mismatches, OS differences, missing runtime versions. Docker solves all of that.
It's not a virtual machine. Containers share the host OS kernel, which makes them faster to start and much lighter on resources.
Docker isn't one thing. It's a set of parts that work together.
The background service running on your host. It does the actual work: creates containers, manages images, handles networking and volumes.
You don't interact with it directly. The Docker client talks to it over a socket.
The CLI tool you use. When you run docker run or docker build, the client sends that instruction to the daemon.
Read-only templates used to create containers. Built from a Dockerfile, layer by layer.
Images live in registries. You pull them down, run them, or build your own.
A running instance of an image. Isolated from other containers and from the host - its own filesystem, network, and process space.
Containers are stateless by default. Data doesn't survive a restart unless you use volumes.
Where images are stored and distributed. Docker Hub is the default public registry - thousands of official and community images.
You can also run a private container registry for internal images.
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
Log out and back in after adding your user to the docker group. Otherwise every command needs sudo.
Download Docker Desktop from docker.com. Includes the daemon, CLI, and Docker Compose in one package.
Docker Desktop on Windows runs containers through WSL 2. Enable WSL 2 before installing, or containers will be significantly slower.
docker --version
docker info
docker info shows daemon status, container count, and system-level details. If it hangs, the daemon isn't running.
docker run is the most-used command in the Docker CLI. It pulls the image (if not cached), creates a container, and starts it.
docker run [OPTIONS] IMAGE [COMMAND]
Common flags: -d (detached), -p (port mapping), -e (environment variable), -v (volume), --name (container name), --rm (auto-remove on exit).
docker run -d nginx
Detached mode runs the container in the background. You get the container ID back. Use docker logs to see output.
docker run -d -p 8080:80 nginx
Format: HOST_PORT:CONTAINER_PORT.
The container exposes port 80 internally. Port 8080 on your machine forwards to it. Open http://localhost:8080 to confirm.
docker run -e DB_HOST=localhost -e DB_PORT=5432 myapp
Pass config without hardcoding it into the image. Critical for production environment deployments - you want the same image across environments, with different env vars per environment. That's environment parity.
docker run -v myvolume:/app/data myapp
Volumes persist data outside the container lifecycle. Use named volumes (above) or bind mounts for dev work.
docker ps
Shows container ID, image, command, uptime, ports, and name. Add -a to include stopped containers.
docker ps -a
Stopped containers still exist until you remove them. docker ps -a -q returns only IDs - useful for bulk operations.
docker stop CONTAINER_ID
Sends SIGTERM, waits 10 seconds, then sends SIGKILL if the container hasn't exited. Graceful by default.
docker start CONTAINER_ID
Restarts a stopped container with its original configuration. Doesn't re-pull the image.
docker restart CONTAINER_ID
Stop + start in one command. Useful after changing environment variables or config files that require a full restart.
docker pause CONTAINER_ID
docker unpause CONTAINER_ID
Freezes all processes inside the container without stopping it. Rarely needed in day-to-day work, but handy for snapshots.
docker rm CONTAINER_ID
Only works on stopped containers. Add -f to force-remove a running one.
docker container prune
Cleans up all stopped containers at once. Prompts for confirmation unless you pass -f.
docker rm -f CONTAINER_ID
Skips the graceful stop. Use when a container is stuck and docker stop isn't working.
docker logs CONTAINER_ID
Prints all stdout/stderr output since the container started. Add --tail 50 to limit output, or --since 1h for a time window.
docker logs -f CONTAINER_ID
Live-streams log output. Works like tail -f. Hit Ctrl+C to exit - the container keeps running.
docker exec CONTAINER_ID ls /app
Runs a one-off command in a running container without opening a full shell.
docker exec -it CONTAINER_ID /bin/bash
-it = interactive + TTY. Use /bin/sh if the image doesn't include bash (common in Alpine-based images).
docker inspect CONTAINER_ID
Returns full JSON: network config, mounts, environment variables, restart policy, and more. Pipe to jq for readable output.
docker stats
Live CPU, memory, network I/O, and block I/O for all running containers. Add a container name/ID to watch a specific one.
docker pull ubuntu
Pulls the latest tag by default. Always be specific in production - latest changes.
docker pull node:20-alpine
Tag format: IMAGE:TAG. Alpine variants are much smaller than full distributions. node:20-alpine is ~50MB vs ~300MB for node:20.
docker tag myapp yourusername/myapp:1.0
docker push yourusername/myapp:1.0
Tag before pushing. The registry path is username/repo:tag. You need to be logged in via docker login.
docker images
Shows repository, tag, image ID, creation date, and size. Add -a to include intermediate layers.
docker rmi IMAGE_ID
Fails if a container (even stopped) is using the image. Remove the container first, or add -f.
docker image prune -a
Removes all images not referenced by any container. -a includes untagged and tagged images with no containers. Significant disk space savings on dev machines.
docker tag SOURCE_IMAGE TARGET_IMAGE:TAG
Tagging is how you version images and prepare them for a registry push. Same image, multiple tags - no duplication on disk.
docker search postgres
Returns name, description, stars, and official status. Official images are maintained by Docker or the upstream vendor - prefer them over random community images.
A Dockerfile is a plain text configuration file that defines how a Docker image gets built - base image, dependencies, file copies, and startup command, all in one place.
Every line creates a new image layer. Order matters: put rarely-changing instructions first to maximize build cache hits.
FROM node:20-alpine
Every Dockerfile starts with FROM. Sets the base image. Use slim or Alpine variants in production - smaller attack surface, faster pulls.
RUN apt-get update && apt-get install -y curl
Executes a command during the build. Chain commands with && to keep them on one layer and reduce image size.
CMD ["node", "server.js"]
Default command when the container starts. Only one CMD per Dockerfile. Gets overridden if you pass a command to docker run.
ENTRYPOINT ["python", "app.py"]
Like CMD, but harder to override. Use ENTRYPOINT for the main process and CMD for default arguments to it.
COPY ./src /app/src
Copies files from the build context into the image. Prefer COPY over ADD unless you need archive extraction.
ADD archive.tar.gz /app/
Like COPY but also extracts .tar archives and supports URLs. Use sparingly - COPY is more predictable.
ENV NODE_ENV=production
Sets environment variables available at build time and runtime. Baked into the image, visible in docker inspect.
EXPOSE 3000
Documents which port the container listens on. Doesn't actually publish the port - that's -p in docker run.
WORKDIR /app
Sets the working directory for subsequent RUN, CMD, COPY, and ADD instructions. Creates the directory if it doesn't exist.
ARG VERSION=1.0
Build-time variable. Passed with --build-arg VERSION=2.0. Not available at runtime - use ENV for that.
VOLUME ["/app/data"]
Declares a mount point. Docker creates an anonymous volume at this path if no volume is mounted at run time.
LABEL maintainer="team@example.com"
Adds metadata to the image. Useful for CI pipelines, image audits, and filtering with docker images --filter.
USER node
Switches to a non-root user for all following instructions. Running as root inside containers is a security risk - always set USER before CMD.
HEALTHCHECK CMD curl -f http://localhost:3000/health || exit 1
Tells Docker how to test if the container is healthy. Failed health checks show up in docker ps under STATUS.
ONBUILD COPY . /app
Triggers a deferred instruction when the image is used as a base. Useful for reusable base images, tricky to debug otherwise.
docker build .
Builds from the Dockerfile in the current directory. The . is the build context - everything in that directory gets sent to the daemon.
docker build -t myapp:1.0 .
Always tag your builds. Untagged images become <none> and clutter docker images.
docker build -f ./docker/Dockerfile.prod -t myapp:prod .
Useful when you maintain multiple Dockerfiles per environment (dev, staging, prod) inside the same codebase.
docker build --no-cache -t myapp:fresh .
Forces a full rebuild. Use when a RUN apt-get layer is stale or you suspect a cached layer has outdated dependencies.
Chain RUN commands with && and clean up in the same layer:
RUN apt-get update && apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
Each RUN is a layer. Cleanup in a separate RUN doesn't shrink the image - the data still exists in the previous layer.
FROM node:20 AS builder
WORKDIR /app
COPY . .
RUN npm run build
FROM node:20-alpine
COPY --from=builder /app/dist /app/dist
CMD ["node", "/app/dist/server.js"]
Multi-stage builds keep build tools out of the final image. The builder stage compiles everything; the second stage ships only the output. Final image can drop from 800MB to under 100MB.
Use Alpine base images, .dockerignore to exclude node_modules and .git, and multi-stage builds.
Run docker image history IMAGE_ID to see which layers are eating the most space.
A Docker volume is persistent storage that exists outside the container filesystem. Data written to a volume survives container stops, restarts, and removals.
Three storage types: named volumes (managed by Docker), bind mounts (host path mapped into container), tmpfs mounts (in-memory only).
docker volume create myvolume
Creates a named volume stored at Docker's default volume path. On Linux: /var/lib/docker/volumes/.
docker volume ls
Shows all volumes, including anonymous ones created by containers. Anonymous volumes have random hex IDs - hard to track, clean up regularly.
docker volume inspect myvolume
Returns mount point, creation date, driver, and labels in JSON. Tells you exactly where Docker volumes are stored on the host.
docker volume rm myvolume
Fails if a container is using the volume. Stop and remove the container first.
docker volume prune
Deletes all volumes not attached to any container. Permanent - no recovery. Double-check before running in any environment with real data.
docker run -v myvolume:/app/data myapp
myvolume mounts at /app/data inside the container. If the volume doesn't exist, Docker creates it automatically.
docker run -v $(pwd)/src:/app/src myapp
Maps a host directory directly into the container. Standard practice in local development - edit files on the host, changes reflect instantly inside the container.
A Docker network is an isolated communication layer between containers. Containers on the same network reach each other by container name - no IP addresses needed.
The default. Containers on the same bridge network communicate with each other; isolated from containers on other networks.
Run docker network inspect bridge to see which containers are connected.
docker run --network host nginx
Container shares the host's network stack directly. No port mapping needed - but no isolation either. Linux only; doesn't work on Docker Desktop for Mac/Windows.
docker run --network none myapp
Completely disables networking. Use for batch jobs or security-sensitive workloads that don't need any network access.
Used with Docker Swarm for multi-host networking. Containers on different physical hosts communicate as if they're on the same network. Requires Swarm mode.
docker network create mynetwork
Creates a user-defined bridge network. Always use named networks in Compose or multi-container setups - default bridge doesn't support DNS resolution by container name.
docker network ls
Shows all networks, their driver, and scope. You'll always see bridge, host, and none by default.
docker network inspect mynetwork
Returns connected containers, IP ranges, gateway, and driver config.
docker network connect mynetwork CONTAINER_ID
Attaches a running container to an additional network. A container can belong to multiple networks simultaneously.
docker network disconnect mynetwork CONTAINER_ID
Removes the container from the network without stopping it.
docker network rm mynetwork
Fails if any container is still connected. Disconnect all containers first.
Docker Compose is a tool for defining and running multi-container applications from a single YAML file.
One docker compose up starts your entire stack - app, database, cache, proxy - with correct networks and volumes, every time.
docker compose up -d
Builds images (if needed), creates networks and volumes, starts all services. -d runs in detached mode.
docker compose down
Stops and removes containers and networks. Add -v to also delete volumes - careful with database data.
docker compose build
Rebuilds images without starting containers. Use --no-cache to force a clean build.
docker compose start
docker compose stop
Start/stop existing containers without removing them. Unlike up/down, these don't recreate anything.
docker compose ps
Lists containers for the current Compose project with their state and port bindings.
docker compose logs -f servicename
Tails logs from a specific service. Omit the service name to see all services at once.
docker compose exec app /bin/sh
Opens a shell in a running service container. Equivalent to docker exec -it but references the service name from the Compose file.
docker compose pull
Pulls updated images for all services defined in the Compose file without starting them.
docker compose restart servicename
Restarts a specific service. Doesn't rebuild the image or re-read the Compose file - use up --force-recreate for that.
version: "3.9"
Specifies the Compose file format version. Version 3.x is standard for most use cases. Omit it entirely in newer Compose V2 - it's deprecated.
services:
app:
image: myapp:latest
Defines each container in your stack. Every service gets its own container, network alias, and configuration block.
networks:
backend:
driver: bridge
Defines custom networks for the stack. Services on the same named network communicate by service name.
volumes:
db_data:
Declares named volumes for the stack. Referenced in service definitions under volumes:.
environment:
- DATABASE_URL=postgres://user:pass@db:5432/mydb
Sets environment variables per service. Use an .env file with env_file: to keep secrets out of the Compose file.
depends_on:
- db
Controls startup order. app starts after db - but doesn't wait for db to be ready. Pair with a health check or retry logic in your app.
ports:
- "8080:80"
Maps host ports to container ports. Same format as -p in docker run.
build:
context: .
dockerfile: Dockerfile.prod
Tells Compose to build the image from a local Dockerfile instead of pulling from a registry.
docker login
docker logout
docker login prompts for your Docker Hub username and password (or token). Credentials are stored in ~/.docker/config.json.
Use access tokens instead of passwords - revokable, scoped, and safer for CI environments.
docker login registry.example.com
docker pull registry.example.com/myapp:1.0
Specify the registry hostname before the image name. Works with AWS ECR, GCP Artifact Registry, GitHub Container Registry, or any self-hosted registry.
Docker accumulates stopped containers, unused images, dangling volumes, and abandoned networks. Left unchecked on dev machines, it can consume 10–20GB easily.
docker system df
Shows disk usage by images, containers, volumes, and build cache. Run this first to see where the space is going.
docker system prune
Removes stopped containers, dangling images, unused networks, and build cache in one command. Add -a to also remove unused (not just dangling) images.
docker system prune -a --volumes
Full cleanup. Everything not currently in use gets removed. Don't run this on a shared build server without checking first.
docker info
Shows daemon version, OS, kernel, total containers, images, storage driver, and resource limits. First thing to check when something behaves unexpectedly.
docker version
Prints client and server versions separately. Useful when debugging compatibility issues between Docker CLI and daemon.
Docker Swarm is Docker's built-in container orchestration tool. It turns a group of Docker hosts into a single cluster, distributing containers across nodes automatically.
Less complex than Kubernetes. Good fit for smaller teams already using Docker who need basic multi-host deployment without the overhead.
docker swarm init --advertise-addr 192.168.1.10
Turns the current host into a Swarm manager. Outputs a join token for worker nodes.
docker swarm join --token SWMTKN-... 192.168.1.10:2377
Joins a worker node to the swarm cluster. Run this on each additional host.
docker node ls
Lists all nodes in the swarm with their role (manager/worker), status, and availability. Manager-only command.
docker service create --replicas 3 -p 80:80 nginx
Creates a Swarm service - a container that runs across multiple nodes with automatic load balancing and restart.
docker service ls
Lists all services in the swarm with replica counts and port mappings.
docker service scale myservice=5
Scales a service to the specified number of replicas. Swarm distributes the new containers across available nodes automatically.
docker stack deploy -c docker-compose.yml mystack
Deploys a full Compose file to the swarm as a stack. The Swarm equivalent of docker compose up.
|
Docker Compose |
Docker Swarm |
|
|---|---|---|
|
Use case |
Local dev, single host |
Multi-host production clusters |
|
Scaling |
Manual, single machine |
Automatic, across nodes |
|
Config file |
|
Same format, deployed via |
|
Networking |
Bridge (local) |
Overlay (multi-host) |
|
Complexity |
Low |
Medium |
|
When to use |
Dev environments, simple deployments |
When you need high availability across multiple hosts |
Compose and Swarm use the same file format. A Compose file written for local development can often be deployed to Swarm with minimal changes.
Add USER to your Dockerfile before CMD. Running as root inside a container is the default - and a real risk if the container is ever compromised.
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
docker scout cves myapp:latest
Docker Scout (built into Docker Desktop) scans images for known CVEs. Integrate into your build pipeline to catch vulnerabilities before app deployment.
docker run --read-only myapp
Mounts the container filesystem as read-only. Attackers can't write malicious files if they break in. Combine with --tmpfs /tmp for processes that need temporary write access.
docker run --memory="512m" --cpus="1.0" myapp
Without limits, a single runaway container can starve the entire host. Always set memory and CPU limits in production.
Use docker stats to understand actual consumption before setting limits - guessing too low causes unexpected container kills.
docker run is the one to learn first. It pulls an image, creates a Docker container, and starts it in a single command. Once you understand its flags - -d, -p, -v, -e - everything else clicks into place.
docker stop sends SIGTERM and waits up to 10 seconds for a graceful shutdown. docker kill sends SIGKILL immediately - no waiting. Use stop by default; kill only when a container is stuck and unresponsive.
Run docker container prune. It deletes every stopped container in one shot and prompts for confirmation. Add -f to skip the prompt. For a full cleanup including unused images and volumes, use docker system prune -a --volumes.
CMD sets the default command and gets overridden easily at runtime. ENTRYPOINT defines the fixed executable - harder to override. Use both together: ENTRYPOINT for the process, CMD for its default arguments.
Use docker logs -f CONTAINER_ID for live log output and docker stats for real-time CPU and memory usage. For deeper inspection - mounts, env vars, network config - run docker inspect CONTAINER_ID.
An image is a read-only template. A container is a running instance of that image. One image can spin up dozens of containers simultaneously. Where Docker images are stored depends on your storage driver and OS.
Use -e VAR=value in docker run, or define them under environment: in your docker-compose.yml. For multiple variables, an .env file with env_file: keeps things cleaner and keeps secrets out of version control.
Use named volumes or bind mounts. Without them, all data written inside the container is lost when it stops. Mount a volume with -v myvolume:/app/data in docker run, or declare it under volumes: in Compose.
It removes stopped containers, dangling images, unused networks, and the build cache. Add -a to also delete unused tagged images. Add --volumes to include Docker volumes. Significant disk space recovery on active dev machines.
Any time you have more than one container. Docker Compose defines your full stack - app, database, cache - in one YAML file, with shared networks and volumes wired up automatically. Far easier to manage than multiple docker run commands.