Skip to content
Unverified — AI-generated content. Help verify this page

Docker Cheat Sheet

Quick reference for Docker commands, Dockerfile best practices, Docker Compose patterns, and container debugging.

Deep dive: Docker Section | Docker Security


Container Lifecycle

CommandDescription
docker run -d --name app imgRun container in background
docker run -it img /bin/shRun container interactively
docker run --rm imgRun and auto-remove on exit
docker run -p 8080:3000 imgMap host port 8080 to container 3000
docker run -v /host:/cont imgBind mount host directory
docker run --env-file .env imgLoad environment variables from file
docker start containerStart a stopped container
docker stop containerGraceful stop (SIGTERM, then SIGKILL)
docker kill containerImmediate stop (SIGKILL)
docker restart containerStop and start
docker rm containerRemove stopped container
docker rm -f containerForce remove running container

Image Management

CommandDescription
docker build -t name:tag .Build image from Dockerfile
docker build -f Dockerfile.prod .Build from specific Dockerfile
docker build --no-cache .Build without layer cache
docker imagesList local images
docker image pruneRemove dangling images
docker image prune -aRemove all unused images
docker tag img:v1 registry/img:v1Tag image for registry
docker push registry/img:v1Push to registry
docker pull img:tagPull from registry
docker save img > img.tarExport image to tarball
docker load < img.tarImport image from tarball
docker history imgShow image layer history

Container Inspection

CommandDescription
docker psList running containers
docker ps -aList all containers
docker logs containerView container logs
docker logs -f containerFollow container logs
docker logs --tail 100 containerLast 100 log lines
docker inspect containerFull container JSON metadata
docker statsLive resource usage
docker top containerRunning processes in container
docker diff containerFilesystem changes since start
docker port containerPort mappings

Exec & Copy

CommandDescription
docker exec -it container shShell into running container
docker exec container cmdRun command in container
docker cp container:/path ./localCopy from container to host
docker cp ./local container:/pathCopy from host to container

Dockerfile Patterns

Production Node.js Dockerfile

dockerfile
# Stage 1: Install dependencies
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production

# Stage 2: Build
FROM node:20-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 3: Production
FROM node:20-alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S app && \
    adduser -S app -u 1001
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY package.json ./
USER app
EXPOSE 3000
CMD ["node", "dist/main.js"]

Production Go Dockerfile

dockerfile
FROM golang:1.22-alpine AS build
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /server ./cmd/server

FROM scratch
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=build /server /server
EXPOSE 8080
ENTRYPOINT ["/server"]

Key Dockerfile Instructions

InstructionPurposeExample
FROMBase imageFROM node:20-alpine
WORKDIRSet working directoryWORKDIR /app
COPYCopy files (respects .dockerignore)COPY . .
ADDCopy + extract archives + URLsADD app.tar.gz /app
RUNExecute command during buildRUN npm ci
CMDDefault command (overridable)CMD ["node", "app.js"]
ENTRYPOINTFixed command (args appended)ENTRYPOINT ["/server"]
ENVSet environment variableENV NODE_ENV=production
ARGBuild-time variableARG VERSION=latest
EXPOSEDocument port (does not publish)EXPOSE 3000
VOLUMECreate mount pointVOLUME /data
USERSet runtime userUSER app
HEALTHCHECKContainer health checkSee below

Healthcheck

dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

Layer Optimization

Order matters -- put rarely-changing layers first:

dockerfile
# 1. System deps (rarely change)
RUN apk add --no-cache curl

# 2. App deps (change sometimes)
COPY package.json package-lock.json ./
RUN npm ci

# 3. App code (changes often)
COPY . .
RUN npm run build

Reduce layers -- combine related RUN commands:

dockerfile
# Bad: 3 layers
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*

# Good: 1 layer
RUN apt-get update && \
    apt-get install -y curl && \
    rm -rf /var/lib/apt/lists/*

Docker Compose

Basic Compose File

yaml
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb
      - REDIS_URL=redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    volumes:
      - .:/app
      - /app/node_modules

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

  cache:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  pgdata:

Compose Commands

CommandDescription
docker compose upStart all services
docker compose up -dStart in background
docker compose up --buildRebuild and start
docker compose downStop and remove
docker compose down -vStop, remove, and delete volumes
docker compose logs -f appFollow logs for one service
docker compose exec app shShell into service
docker compose psList service status
docker compose restart appRestart one service
docker compose pullPull latest images
docker compose configValidate and view merged config

Networking

CommandDescription
docker network lsList networks
docker network create mynetCreate network
docker network inspect mynetInspect network details
docker network connect mynet containerConnect container to network
docker network disconnect mynet containerDisconnect from network

Network Types

TypeUse Case
bridgeDefault. Containers on same host communicate via DNS
hostContainer shares host network. No port mapping needed
noneNo networking. Complete isolation
overlayMulti-host networking (Swarm)

Volumes

CommandDescription
docker volume lsList volumes
docker volume create myvolCreate named volume
docker volume inspect myvolVolume details
docker volume rm myvolDelete volume
docker volume pruneRemove unused volumes

Volume Types

bash
# Named volume (Docker manages storage)
docker run -v myvol:/data img

# Bind mount (host path)
docker run -v /host/path:/container/path img

# tmpfs mount (in-memory, Linux only)
docker run --tmpfs /tmp img

# Read-only mount
docker run -v /host/path:/data:ro img

Debugging Containers

Container Will Not Start

bash
# Check logs
docker logs container

# Inspect exit code
docker inspect container --format='Exit: .State.ExitCode'

# Run interactively to debug
docker run -it --entrypoint sh img

# Check resource limits
docker stats container

Container Is Slow

bash
# Check resource usage
docker stats container

# Check process list
docker top container

# Profile with strace (if available)
docker exec container strace -p 1 -c

Networking Issues

bash
# Check container IP
docker inspect container | grep '"IPAddress"'

# Test DNS resolution
docker exec container nslookup other-service

# Test connectivity
docker exec container wget -qO- http://other-service:3000/health

# Check port bindings
docker port container

Disk Space Issues

bash
# Check Docker disk usage
docker system df

# Detailed breakdown
docker system df -v

# Clean everything unused
docker system prune -a --volumes

Security Quick Reference

PracticeCommand / Pattern
Run as non-rootUSER 1001 in Dockerfile
Read-only filesystemdocker run --read-only img
Drop capabilitiesdocker run --cap-drop ALL img
No new privilegesdocker run --security-opt no-new-privileges img
Resource limitsdocker run -m 512m --cpus 1 img
Scan for vulnerabilitiesdocker scout cves img
Use minimal base imageFROM alpine or FROM scratch
Pin image digestsFROM node@sha256:abc123...

When to Use X vs Y

DecisionChoice AChoice BUse A WhenUse B When
Base imagealpinedebian-slimSize matters, no glibc depsNeed glibc, broad package support
Base imagenode:alpinescratchNeed runtime (Node, Python)Compiled binary (Go, Rust)
Mount typeNamed volumeBind mountPersistent data (DB, uploads)Development hot-reload
CMD formatExec form ["cmd"]Shell form cmdProduction (signal handling)Need shell expansion
Multi-stageYesNoProduction imagesSimple dev Dockerfiles
ComposeYesNoMulti-container local devSingle container, CI/CD

.dockerignore Template

node_modules
.git
.gitignore
.env*
*.md
dist
coverage
.vscode
.idea
docker-compose*.yml
Dockerfile*
.dockerignore

Test Yourself
  1. What flag auto-removes a container when it exits?docker run --rm

  2. How do you map host port 8080 to container port 3000?docker run -p 8080:3000 img

  3. What command shows live resource usage of running containers?docker stats

  4. How do you build an image without using the layer cache?docker build --no-cache .

  5. What command gets a shell into an already-running container?docker exec -it container sh

  6. What Dockerfile instruction sets the default command that can be overridden at runtime?CMD

  7. How do you stop and remove all containers, networks, and volumes created by Compose?docker compose down -v

  8. What command scans an image for known vulnerabilities?docker scout cves img

  9. How do you copy a file from a container to the host?docker cp container:/path ./local

  10. What is the purpose of EXPOSE in a Dockerfile? It documents the port the container listens on but does NOT actually publish it.

Common Gotchas

  • Running as root inside containers. Always add a USER instruction in production Dockerfiles -- running as root means a container escape grants root on the host.
  • Using latest tag in production. The latest tag is mutable and can change without warning. Pin image versions or use digests (node@sha256:...).
  • Forgetting .dockerignore. Without it, COPY . . sends your entire directory (including node_modules, .git, .env) to the build context, bloating images and leaking secrets.
  • Putting COPY . . before RUN npm install. This busts the dependency cache on every code change. Copy package.json and lock file first, install, then copy the rest.

One-Liner Summary

Docker packages your app and its dependencies into an isolated, portable container that runs the same everywhere -- master the Dockerfile layer cache and multi-stage builds to keep images small and builds fast.

"What I cannot create, I do not understand." — Richard Feynman