/user/kayd @ devops :~$ cat docker.md

Docker Cheatsheet Docker Cheatsheet

QR Code linking to: Docker Cheatsheet
Karandeep Singh
Karandeep Singh
• 7 minutes

Summary

A dense, practical Docker reference covering the image lifecycle, container run flags, Dockerfiles with multi-stage builds, compose, and cleanup commands.

I use Docker more than any other tool and still end up looking up the same flags every week, so I keep this page open in a tab. Just the commands I actually run, nothing padded out. If you run containers in production, pair this with my Kubernetes Cheatsheet, because most of these images end up in a cluster eventually.

Image Lifecycle

Docs: docker image commands (Docker Docs)

docker build -t myapp:1.0 .               # Build from Dockerfile in current dir
docker build -t myapp:1.0 -f prod.Dockerfile .   # Custom Dockerfile name
docker build --no-cache -t myapp:1.0 .    # Ignore build cache
docker tag myapp:1.0 registry.example.com/team/myapp:1.0
docker push registry.example.com/team/myapp:1.0
docker pull nginx:1.27-alpine
docker images                             # List local images
docker image inspect myapp:1.0            # Full metadata (JSON)
docker history myapp:1.0                  # Layer-by-layer sizes
docker save myapp:1.0 -o myapp.tar        # Export image to tarball
docker load -i myapp.tar                  # Import from tarball
CommandWhat it does
docker build -t name:tag .Build an image from a Dockerfile
docker tag src tgtAdd another name/tag to an image
docker push name:tagUpload to a registry
docker pull name:tagDownload from a registry
docker rmi name:tagDelete a local image
docker login registry.example.comAuthenticate to a registry

Running Containers

Docs: docker container run reference on Docker Docs

docker run -d --name web -p 8080:80 nginx:1.27-alpine
docker run --rm -it ubuntu:24.04 bash     # Throwaway interactive container
docker run -d --restart unless-stopped -e TZ=America/Edmonton myapp:1.0

Run Flags I Use Constantly

FlagMeaningExample
-dDetached (background)docker run -d nginx
-pPublish port host:container-p 8080:80
-vMount volume or bind mount-v pgdata:/var/lib/postgresql/data
-eSet environment variable-e POSTGRES_PASSWORD=secret
--env-fileLoad env vars from file--env-file .env
--networkAttach to a network--network backend
--rmAuto-remove on exitdocker run --rm alpine echo hi
--restartRestart policy--restart unless-stopped
-itInteractive TTY-it ubuntu bash
--nameName the container--name web
--memory / --cpusResource limits--memory 512m --cpus 1.5

Restart policies: no (default), on-failure[:max-retries], always, unless-stopped. I use unless-stopped on standalone hosts so containers survive reboots but respect a manual docker stop.

Exec, Logs, Inspect, Stats

Docs: docker container commands (Docker Docs)

docker ps                                 # Running containers
docker ps -a                              # Include stopped ones
docker exec -it web sh                    # Shell into a running container
docker exec web env                       # One-off command, no TTY
docker logs web                           # Dump logs
docker logs -f --tail 100 web             # Follow, last 100 lines
docker logs --since 15m web               # Logs from the last 15 minutes
docker inspect web                        # Full JSON: mounts, IP, env, state
docker inspect -f '{{ .NetworkSettings.IPAddress }}' web
docker stats                              # Live CPU/mem/net per container
docker top web                            # Processes inside the container
docker cp web:/etc/nginx/nginx.conf ./    # Copy files out (or in)
docker stop web && docker rm web          # Stop then remove
docker kill web                           # SIGKILL immediately

Dockerfile Essentials

Docs: Dockerfile reference on Docker Docs

InstructionPurpose
FROMBase image (first non-comment line; one per stage)
WORKDIRSet working directory (creates it if missing)
COPYCopy files from build context into image
RUNExecute a command at build time (new layer)
ENVSet persistent environment variable
ARGBuild-time variable (not in final image env)
EXPOSEDocument the listening port (metadata only)
USERRun as a non-root user (drop root)
ENTRYPOINTFixed executable
CMDDefault args (overridable at docker run)
HEALTHCHECKCommand Docker runs to test container health

Multi-Stage Build (Go example)

# Stage 1: build
FROM golang:1.24-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /app ./cmd/server

# Stage 2: minimal runtime
FROM alpine:3.21
RUN adduser -D -u 10001 appuser
COPY --from=builder /app /app
USER appuser
EXPOSE 8080
ENTRYPOINT ["/app"]

The final image here is a few MB instead of ~800MB, since the entire Go toolchain stays behind in the builder stage. If you write Go, my Go (Golang) Cheatsheet covers the build flags used above.

.dockerignore

Keep the build context small. Docker uploads everything in the context to the daemon before building.

.git
node_modules
tmp/
*.log
.env
Dockerfile
docker-compose*.yml

Volumes & Networks

Docs: Docker volumes docs

docker volume create pgdata
docker volume ls
docker volume inspect pgdata              # Shows host mountpoint
docker volume rm pgdata

docker network create backend             # User-defined bridge (has DNS)
docker network ls
docker network inspect backend
docker network connect backend web       # Attach a running container
docker network disconnect backend web

Containers on the same user-defined network resolve each other by container name, so db:5432 just works. The default bridge network does not do name resolution; always create your own.

# Bind mount (host path) vs named volume
docker run -v $(pwd)/conf:/etc/nginx/conf.d:ro nginx   # bind, read-only
docker run -v pgdata:/var/lib/postgresql/data postgres # named volume

Docker Compose

Docs: Docker Compose docs

docker compose up -d                      # Start stack in background
docker compose up -d --build              # Rebuild images first
docker compose down                       # Stop and remove containers/networks
docker compose down -v                    # ...and volumes (destructive!)
docker compose ps                         # Status of services
docker compose logs -f api                # Follow one service's logs
docker compose exec api sh               # Shell into a service
docker compose restart worker            # Restart one service
docker compose pull                       # Refresh images

Sample compose.yaml

services:
  api:
    build: .
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: postgres://app:secret@db:5432/app
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 5s
      timeout: 3s
      retries: 5

volumes:
  pgdata:

Cleanup

Docs: docker system prune (Docker Docs)

docker system df                          # What's eating disk
docker system prune                       # Stopped containers, dangling images, unused networks
docker system prune -a --volumes          # Everything unused, incl. volumes - careful
docker image prune                        # Dangling images only
docker image prune -a                     # All images not used by a container
docker container prune                    # All stopped containers
docker volume prune                       # Unused volumes
docker builder prune                      # Build cache

Debugging Tips

Docs: docker CLI reference on Docker Docs

docker logs --details web                          # Extra log metadata
docker inspect -f '{{ .State.ExitCode }}' web      # Why did it die?
docker inspect -f '{{ json .State.Health }}' web | jq   # Healthcheck history
docker events --filter container=web               # Live daemon events
docker run --rm -it --entrypoint sh myapp:1.0      # Bypass a crashing entrypoint
docker exec -it web sh -c 'wget -qO- localhost:8080/healthz'   # Test from inside
docker run --rm --network container:web nicolaka/netshoot      # Netshoot in the container's netns
docker diff web                                    # Files changed since start
  • Exit code 137 = OOM-killed (or SIGKILL). Check --memory limits and dmesg.
  • Exit code 126/127 = command not executable / not found, usually a bad ENTRYPOINT or a missing shell in a distroless image.
  • Container exits immediately? The main process finished. Run with -it ... sh or check that your process runs in the foreground (no daemon mode inside containers).
  • Can’t reach a service? Confirm -p mapping with docker port web, and remember published ports bind to the host; container-to-container traffic uses the internal port on a shared network.
  • Kubernetes is the next step for these images: kubectl verbs, Deployment and Service YAML skeletons, rollouts, and crash-loop triage
  • Jenkins covers the declarative pipelines that build, tag, and push these images, including docker agents and credential binding
  • Ubuntu Terminal handles the host side: systemd units, journal logs, disk cleanup, and the ufw firewall in front of your containers

The rest of my container notes are in the Containers group, and everything else lives in the cheatsheet library.

Similar Articles

More from devops

tmux Cheatsheet

Quick-reference tmux cheatsheet: sessions, windows, panes, copy mode, synchronize-panes, .tmux.conf …

Jenkins Cheatsheet

Jenkins cheatsheet with declarative pipeline syntax, credentials, parameters, parallel stages, …

Bash Basics Cheatsheet

Quick-reference Bash basics cheatsheet: variables, parameter expansion, conditionals, loops, arrays, …

Kubernetes Cheatsheet

Kubernetes cheatsheet for my daily kubectl work: get/describe/logs/exec, YAML skeletons, rollouts, …