Docker cheat sheet: core commands

The Docker lifecycle in one line: pull (or build) an image, docker run it into a container, docker exec into it, docker logs to watch it, and docker stop/docker rm to retire it. Every other command is a variation on that loop.

The commands below behave identically on Docker Desktop (Windows/macOS) and Docker Engine (Linux). Where a container has no shell (e.g. minimal or distroless images), use docker exec without -it and run a specific binary instead.

Published

The run lifecycle

A typical session, end to end
# Pull an image from Docker Hub
docker pull nginx

# Run it in the background, mapping host port 8080 to container port 80
docker run -d -p 8080:80 --name web nginx

# See what is running (add -a for all containers)
docker ps

# Watch its logs (add -f to follow, --tail 50 for the last 50 lines)
docker logs web

# Open a shell inside it
docker exec -it web bash

# Stop and remove it
docker stop web
docker rm web
The commands you will type most
CommandWhat it does
docker run <image>creates and starts a container from an image (pulling it first if needed)
docker pslists running containers; docker ps -a lists every container, stopped or running
docker imageslists local images with tag and size
docker exec -it <c> bashruns an interactive shell inside a running container
docker logs <c>prints a container's stdout/stderr; add -f to follow, --tail 50 to limit
docker stop <c>gracefully stops a running container (SIGTERM, then SIGKILL after a timeout)
docker rm <c>removes a stopped container; docker rm -f <c> stops and removes in one step
docker rmi <image>removes an image

The docker run flags that matter

Run flags, in order of how often you will type them

-d, --detach
run in the background and print the container ID
-p 8080:80
publish a port: host 8080 maps to the container's 80 (host:container)
--name web
give the container a name instead of a random one
-v data:/var/lib/db
mount a named volume (or a host path) so data survives the container
-e KEY=value
set an environment variable; repeat for more, or use --env-file
-it
interactive + TTY — what you add when you want a shell (-i keeps stdin, -t allocates a terminal)
--rm
auto-remove the container when it exits (useful for one-off jobs)
--restart unless-stopped
restart policy: unless-stopped, always, on-failure or no (the default)
Run flags composed — a real, typical example
docker run -d \
  --name postgres \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD=secret \
  -v pgdata:/var/lib/postgresql/data \
  --restart unless-stopped \
  postgres:16
--rm and a named volume (-v name:path) work together — the container deletes itself, the data stays. A bind mount (-v /host/path:/container/path) uses an absolute host path; on Windows/macOS those paths must live under a shared directory (the Docker Desktop file-sharing settings) or the mount silently stays empty.

Building images

A minimal Dockerfile, then building and tagging it
# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

# Build from the current directory, tag it user/app:1.0
docker build -t user/app:1.0 .

# List the image you just built
docker images | grep app

# Push it to a registry (Docker Hub by default)
docker push user/app:1.0
FROM sets the base image, COPY adds files, RUN executes a build-time command, CMD (or ENTRYPOINT) defines the runtime command, and EXPOSE documents a port (it does not publish it — that is still -p at run time). The layer order matters: copy the dependency manifest first so Docker's layer cache can skip reinstalling packages when only your code changes.

Copying files and inspecting

Move files in and out, and see what a container really is

docker cp <c>:/path/file .
copy a file out of a container to the host
docker cp ./file <c>:/path/
copy a file from the host into a container
docker inspect <c>
full JSON metadata: mounts, networks, env, health, IP and more
docker inspect -f '{{.State.Status}}' <c>
Go-template extraction of one field (status here)
docker stats
live CPU/memory/network per running container
docker port <c>
shows the published port mapping for a container

References

FAQ

What is the difference between an image and a container?

An image is the immutable template — the filesystem and config that get built or pulled once and shared. A container is a running instance of that image, with its own writable layer, network namespace and process. Many containers can run from one image, and removing a container never deletes the image.

What is the difference between docker run and docker start?

docker run creates a new container from an image and starts it. docker start starts an existing container that was stopped. To re-run an existing container with the same config, use docker start ; to create a fresh instance, use docker run.

How do I get a shell inside a running container?

docker exec -it bash, or sh for images without bash (like Alpine, which ships /bin/sh). The container must have that shell installed — minimal or distroless images do not, in which case run the specific binary instead: docker exec .

Why is my container exiting immediately?

A container runs only as long as its main process (the Dockerfile CMD/ENTRYPOINT) runs. If that command finishes, the container exits. For a long-running service the CMD must block (a server, not a script that returns); for an interactive image use docker run -it and give it a command like bash. Check the exit reason with docker ps -a and docker logs .