DEV Community

Apaksh
Apaksh

Posted on

Docker Demystified: The Only Cheat Sheet You Need

Docker is one of those tools that's simple in concept and maddeningly complex in practice. You understand containers, you've pulled an image, and then suddenly you're debugging a networking issue between three services at 11pm and you can't remember if it's docker compose down -v or docker compose down --volumes. This cheat sheet is my antidote to that. Pin it, bookmark it, and stop wasting time on Docker documentation.

Container Lifecycle

# Create & Start
docker run <image>                          # Pull + create + start
docker run -it <image> bash                 # Interactive with TTY
docker run -d <image>                       # Detached (background)
docker run --name myapp <image>             # Named container
docker run --rm <image>                     # Auto-remove on exit
docker run -p 8080:80 <image>              # Map host:container port
docker run -e ENV_VAR=value <image>        # Set environment variable
docker run --env-file .env <image>         # Load env from file
docker run -v /host/path:/container/path <image>  # Bind mount
docker run --memory="512m" --cpus="1.5" <image>   # Resource limits

# Start / Stop / Restart
docker start <container>                   # Start stopped container
docker stop <container>                    # Graceful stop (SIGTERM)
docker kill <container>                    # Force stop (SIGKILL)
docker restart <container>

# Remove
docker rm <container>                      # Remove stopped container
docker rm -f <container>                   # Force remove running container
docker container prune                     # Remove all stopped containers
Enter fullscreen mode Exit fullscreen mode

Container Inspection & Monitoring

docker ps                                  # List running containers
docker ps -a                               # List ALL containers
docker logs <container>                    # View logs
docker logs -f <container>                 # Follow/tail logs
docker logs --tail 100 <container>         # Last 100 lines
docker inspect <container>                 # Full JSON metadata
docker stats                               # Live CPU/mem/net usage
docker top <container>                     # Running processes
Enter fullscreen mode Exit fullscreen mode

Exec & Interaction

docker exec -it <container> bash           # Shell into running container
docker exec -it <container> sh             # Use sh if bash unavailable
docker exec <container> ls /app            # Run single command
docker cp <container>:/path/file ./local   # Copy FROM container
docker cp ./local <container>:/path/file   # Copy TO container
Enter fullscreen mode Exit fullscreen mode

Image Management

docker images                              # List local images
docker pull nginx:1.25                     # Pull specific tag
docker build -t myapp:1.0 .               # Build from Dockerfile
docker build --no-cache -t myapp .        # Build without cache
docker build --build-arg KEY=value .      # Pass build arguments
docker tag myapp:1.0 myrepo/myapp:1.0    # Tag image
docker rmi <image>                         # Remove image
docker image prune -a                      # Remove ALL unused images
Enter fullscreen mode Exit fullscreen mode

Dockerfile Reference

FROM node:20-alpine
WORKDIR /app
LABEL maintainer="you@example.com"
ARG NODE_ENV=production
ENV PORT=3000 NODE_ENV=production

# Copy package.json FIRST for cache efficiency
COPY package*.json ./
RUN npm ci --only=production
COPY . .

VOLUME ["/app/data"]
EXPOSE 3000

HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

USER node
CMD ["node", "server.js"]
Enter fullscreen mode Exit fullscreen mode

CMD vs ENTRYPOINT

  • CMD -- Default command/args, overridable with docker run <image> <cmd>
  • ENTRYPOINT -- Fixed executable, only overridable with --entrypoint flag
  • Combined -- ENTRYPOINT receives CMD as default arguments

Multi-Stage Builds

# Stage 1: Builder
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Production (only copies what's needed)
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/server.js"]
Enter fullscreen mode Exit fullscreen mode

Networking

docker network ls                          # List all networks
docker network create mynet               # Bridge network (default)
docker network connect mynet <container>   # Add container to network
docker run --network mynet <image>         # Start on specific network
Enter fullscreen mode Exit fullscreen mode

Network Drivers

  • bridge -- Default, single host. Containers talk by name on custom bridge.
  • host -- Max performance, no isolation. Uses host network.
  • none -- Complete isolation.
  • overlay -- Multi-host (Swarm). Cross-host communication.

Gotcha: On the default bridge network, containers can't resolve each other by name. Create a custom bridge network to get automatic DNS resolution.

Volumes & Storage

docker volume create mydata               # Create named volume
docker volume ls                           # List volumes
docker run -v mydata:/app/data <image>    # Named volume
docker run -v /host/path:/app/data <image># Bind mount
Enter fullscreen mode Exit fullscreen mode

Volume Types

  • Named Volume (-v name:/path) -- Docker-managed, best for persistent app data
  • Bind Mount (-v /host:/container) -- Host OS managed, best for development
  • Anonymous (-v /path) -- Docker-managed, best for temporary data
  • tmpfs (--tmpfs /path) -- Memory-based, best for sensitive data

Docker Compose

# docker-compose.yml key sections:
# services, volumes, networks

docker compose up                          # Start all services
docker compose up -d                       # Detached mode
docker compose up --build                  # Rebuild images first
docker compose down                        # Stop & remove containers
docker compose down -v                     # Also remove volumes
docker compose logs -f app                 # Follow specific service
docker compose exec app bash               # Shell into service
docker compose run app npm test            # Run one-off command
Enter fullscreen mode Exit fullscreen mode

Cleanup & Maintenance

docker system prune                        # Remove all unused objects
docker system prune -a --volumes           # Nuclear option (data loss!)
docker system df                           # Show Docker disk usage
Enter fullscreen mode Exit fullscreen mode

Security Best Practices

  • Use specific tags -- never just "latest" in production
  • Run as non-root user
  • Minimize image layers and attack surface
  • Use .dockerignore to avoid leaking secrets
  • Use COPY over ADD unless you need URL fetching or auto-extraction
  • Use npm ci not npm install in Dockerfiles

Common Gotchas

  • EXPOSE doesn't publish ports. It's documentation only. Use -p to actually publish.
  • docker stop sends SIGTERM, then SIGKILL after 10s. Make sure your app handles SIGTERM gracefully.
  • Volumes aren't removed with docker compose down. You need -v flag.
  • latest tag isn't always the latest. It's just a tag -- pin versions in production.
  • Build context is sent to Docker daemon. A large project directory = slow builds. Use .dockerignore.
  • Each RUN creates a new layer. Chain commands with && to reduce image size.

If you found this useful, share it with a colleague who needs it. Subscribe for more developer resources every week.


Want the full resource?

Docker Cheat Sheet — $6.99 on Gumroad

Get the complete, downloadable version. Perfect for bookmarking, printing, or sharing with your team.

Get it now on Gumroad →


If you found this useful, drop a ❤️ and follow for more developer resources every week.

Top comments (0)