Tools: Docker Demystified: The Only Cheat Sheet You Need

Tools: Docker Demystified: The Only Cheat Sheet You Need

Container Lifecycle

Container Inspection & Monitoring

Exec & Interaction

Image Management

Dockerfile Reference

CMD vs ENTRYPOINT

Multi-Stage Builds

Networking

Network Drivers

Volumes & Storage

Volume Types

Docker Compose

Cleanup & Maintenance

Security Best Practices

Common Gotchas 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. Gotcha: On the default bridge network, containers can't resolve each other by name. Create a custom bridge network to get automatic DNS resolution. If you found this useful, share it with a colleague who needs it. Subscribe for more developer resources every week. 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. Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Command

Copy

# Create & Start -weight: 500;">docker run <image> # Pull + create + -weight: 500;">start -weight: 500;">docker run -it <image> bash # Interactive with TTY -weight: 500;">docker run -d <image> # Detached (background) -weight: 500;">docker run --name myapp <image> # Named container -weight: 500;">docker run --rm <image> # Auto--weight: 500;">remove on exit -weight: 500;">docker run -p 8080:80 <image> # Map host:container port -weight: 500;">docker run -e ENV_VAR=value <image> # Set environment variable -weight: 500;">docker run --env-file .env <image> # Load env from file -weight: 500;">docker run -v /host/path:/container/path <image> # Bind mount -weight: 500;">docker run --memory="512m" --cpus="1.5" <image> # Resource limits # Start / Stop / Restart -weight: 500;">docker -weight: 500;">start <container> # Start stopped container -weight: 500;">docker -weight: 500;">stop <container> # Graceful -weight: 500;">stop (SIGTERM) -weight: 500;">docker kill <container> # Force -weight: 500;">stop (SIGKILL) -weight: 500;">docker -weight: 500;">restart <container> # Remove -weight: 500;">docker rm <container> # Remove stopped container -weight: 500;">docker rm -f <container> # Force -weight: 500;">remove running container -weight: 500;">docker container prune # Remove all stopped containers # Create & Start -weight: 500;">docker run <image> # Pull + create + -weight: 500;">start -weight: 500;">docker run -it <image> bash # Interactive with TTY -weight: 500;">docker run -d <image> # Detached (background) -weight: 500;">docker run --name myapp <image> # Named container -weight: 500;">docker run --rm <image> # Auto--weight: 500;">remove on exit -weight: 500;">docker run -p 8080:80 <image> # Map host:container port -weight: 500;">docker run -e ENV_VAR=value <image> # Set environment variable -weight: 500;">docker run --env-file .env <image> # Load env from file -weight: 500;">docker run -v /host/path:/container/path <image> # Bind mount -weight: 500;">docker run --memory="512m" --cpus="1.5" <image> # Resource limits # Start / Stop / Restart -weight: 500;">docker -weight: 500;">start <container> # Start stopped container -weight: 500;">docker -weight: 500;">stop <container> # Graceful -weight: 500;">stop (SIGTERM) -weight: 500;">docker kill <container> # Force -weight: 500;">stop (SIGKILL) -weight: 500;">docker -weight: 500;">restart <container> # Remove -weight: 500;">docker rm <container> # Remove stopped container -weight: 500;">docker rm -f <container> # Force -weight: 500;">remove running container -weight: 500;">docker container prune # Remove all stopped containers # Create & Start -weight: 500;">docker run <image> # Pull + create + -weight: 500;">start -weight: 500;">docker run -it <image> bash # Interactive with TTY -weight: 500;">docker run -d <image> # Detached (background) -weight: 500;">docker run --name myapp <image> # Named container -weight: 500;">docker run --rm <image> # Auto--weight: 500;">remove on exit -weight: 500;">docker run -p 8080:80 <image> # Map host:container port -weight: 500;">docker run -e ENV_VAR=value <image> # Set environment variable -weight: 500;">docker run --env-file .env <image> # Load env from file -weight: 500;">docker run -v /host/path:/container/path <image> # Bind mount -weight: 500;">docker run --memory="512m" --cpus="1.5" <image> # Resource limits # Start / Stop / Restart -weight: 500;">docker -weight: 500;">start <container> # Start stopped container -weight: 500;">docker -weight: 500;">stop <container> # Graceful -weight: 500;">stop (SIGTERM) -weight: 500;">docker kill <container> # Force -weight: 500;">stop (SIGKILL) -weight: 500;">docker -weight: 500;">restart <container> # Remove -weight: 500;">docker rm <container> # Remove stopped container -weight: 500;">docker rm -f <container> # Force -weight: 500;">remove running container -weight: 500;">docker container prune # Remove all stopped containers -weight: 500;">docker ps # List running containers -weight: 500;">docker ps -a # List ALL containers -weight: 500;">docker logs <container> # View logs -weight: 500;">docker logs -f <container> # Follow/tail logs -weight: 500;">docker logs --tail 100 <container> # Last 100 lines -weight: 500;">docker inspect <container> # Full JSON metadata -weight: 500;">docker stats # Live CPU/mem/net usage -weight: 500;">docker top <container> # Running processes -weight: 500;">docker ps # List running containers -weight: 500;">docker ps -a # List ALL containers -weight: 500;">docker logs <container> # View logs -weight: 500;">docker logs -f <container> # Follow/tail logs -weight: 500;">docker logs --tail 100 <container> # Last 100 lines -weight: 500;">docker inspect <container> # Full JSON metadata -weight: 500;">docker stats # Live CPU/mem/net usage -weight: 500;">docker top <container> # Running processes -weight: 500;">docker ps # List running containers -weight: 500;">docker ps -a # List ALL containers -weight: 500;">docker logs <container> # View logs -weight: 500;">docker logs -f <container> # Follow/tail logs -weight: 500;">docker logs --tail 100 <container> # Last 100 lines -weight: 500;">docker inspect <container> # Full JSON metadata -weight: 500;">docker stats # Live CPU/mem/net usage -weight: 500;">docker top <container> # Running processes -weight: 500;">docker exec -it <container> bash # Shell into running container -weight: 500;">docker exec -it <container> sh # Use sh if bash unavailable -weight: 500;">docker exec <container> ls /app # Run single command -weight: 500;">docker cp <container>:/path/file ./local # Copy FROM container -weight: 500;">docker cp ./local <container>:/path/file # Copy TO container -weight: 500;">docker exec -it <container> bash # Shell into running container -weight: 500;">docker exec -it <container> sh # Use sh if bash unavailable -weight: 500;">docker exec <container> ls /app # Run single command -weight: 500;">docker cp <container>:/path/file ./local # Copy FROM container -weight: 500;">docker cp ./local <container>:/path/file # Copy TO container -weight: 500;">docker exec -it <container> bash # Shell into running container -weight: 500;">docker exec -it <container> sh # Use sh if bash unavailable -weight: 500;">docker exec <container> ls /app # Run single command -weight: 500;">docker cp <container>:/path/file ./local # Copy FROM container -weight: 500;">docker cp ./local <container>:/path/file # Copy TO container -weight: 500;">docker images # List local images -weight: 500;">docker pull nginx:1.25 # Pull specific tag -weight: 500;">docker build -t myapp:1.0 . # Build from Dockerfile -weight: 500;">docker build --no-cache -t myapp . # Build without cache -weight: 500;">docker build --build-arg KEY=value . # Pass build arguments -weight: 500;">docker tag myapp:1.0 myrepo/myapp:1.0 # Tag image -weight: 500;">docker rmi <image> # Remove image -weight: 500;">docker image prune -a # Remove ALL unused images -weight: 500;">docker images # List local images -weight: 500;">docker pull nginx:1.25 # Pull specific tag -weight: 500;">docker build -t myapp:1.0 . # Build from Dockerfile -weight: 500;">docker build --no-cache -t myapp . # Build without cache -weight: 500;">docker build --build-arg KEY=value . # Pass build arguments -weight: 500;">docker tag myapp:1.0 myrepo/myapp:1.0 # Tag image -weight: 500;">docker rmi <image> # Remove image -weight: 500;">docker image prune -a # Remove ALL unused images -weight: 500;">docker images # List local images -weight: 500;">docker pull nginx:1.25 # Pull specific tag -weight: 500;">docker build -t myapp:1.0 . # Build from Dockerfile -weight: 500;">docker build --no-cache -t myapp . # Build without cache -weight: 500;">docker build --build-arg KEY=value . # Pass build arguments -weight: 500;">docker tag myapp:1.0 myrepo/myapp:1.0 # Tag image -weight: 500;">docker rmi <image> # Remove image -weight: 500;">docker image prune -a # Remove ALL unused images FROM node:20-alpine WORKDIR /app LABEL maintainer="[email protected]" ARG NODE_ENV=production ENV PORT=3000 NODE_ENV=production # Copy package.json FIRST for cache efficiency COPY package*.json ./ RUN -weight: 500;">npm ci --only=production COPY . . VOLUME ["/app/data"] EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=3s --retries=3 \ CMD -weight: 500;">curl -f http://localhost:3000/health || exit 1 USER node CMD ["node", "server.js"] FROM node:20-alpine WORKDIR /app LABEL maintainer="[email protected]" ARG NODE_ENV=production ENV PORT=3000 NODE_ENV=production # Copy package.json FIRST for cache efficiency COPY package*.json ./ RUN -weight: 500;">npm ci --only=production COPY . . VOLUME ["/app/data"] EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=3s --retries=3 \ CMD -weight: 500;">curl -f http://localhost:3000/health || exit 1 USER node CMD ["node", "server.js"] FROM node:20-alpine WORKDIR /app LABEL maintainer="[email protected]" ARG NODE_ENV=production ENV PORT=3000 NODE_ENV=production # Copy package.json FIRST for cache efficiency COPY package*.json ./ RUN -weight: 500;">npm ci --only=production COPY . . VOLUME ["/app/data"] EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=3s --retries=3 \ CMD -weight: 500;">curl -f http://localhost:3000/health || exit 1 USER node CMD ["node", "server.js"] # Stage 1: Builder FROM node:20 AS builder WORKDIR /app COPY package*.json ./ RUN -weight: 500;">npm ci COPY . . RUN -weight: 500;">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"] # Stage 1: Builder FROM node:20 AS builder WORKDIR /app COPY package*.json ./ RUN -weight: 500;">npm ci COPY . . RUN -weight: 500;">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"] # Stage 1: Builder FROM node:20 AS builder WORKDIR /app COPY package*.json ./ RUN -weight: 500;">npm ci COPY . . RUN -weight: 500;">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"] -weight: 500;">docker network ls # List all networks -weight: 500;">docker network create mynet # Bridge network (default) -weight: 500;">docker network connect mynet <container> # Add container to network -weight: 500;">docker run --network mynet <image> # Start on specific network -weight: 500;">docker network ls # List all networks -weight: 500;">docker network create mynet # Bridge network (default) -weight: 500;">docker network connect mynet <container> # Add container to network -weight: 500;">docker run --network mynet <image> # Start on specific network -weight: 500;">docker network ls # List all networks -weight: 500;">docker network create mynet # Bridge network (default) -weight: 500;">docker network connect mynet <container> # Add container to network -weight: 500;">docker run --network mynet <image> # Start on specific network -weight: 500;">docker volume create mydata # Create named volume -weight: 500;">docker volume ls # List volumes -weight: 500;">docker run -v mydata:/app/data <image> # Named volume -weight: 500;">docker run -v /host/path:/app/data <image># Bind mount -weight: 500;">docker volume create mydata # Create named volume -weight: 500;">docker volume ls # List volumes -weight: 500;">docker run -v mydata:/app/data <image> # Named volume -weight: 500;">docker run -v /host/path:/app/data <image># Bind mount -weight: 500;">docker volume create mydata # Create named volume -weight: 500;">docker volume ls # List volumes -weight: 500;">docker run -v mydata:/app/data <image> # Named volume -weight: 500;">docker run -v /host/path:/app/data <image># Bind mount # -weight: 500;">docker-compose.yml key sections: # services, volumes, networks -weight: 500;">docker compose up # Start all services -weight: 500;">docker compose up -d # Detached mode -weight: 500;">docker compose up --build # Rebuild images first -weight: 500;">docker compose down # Stop & -weight: 500;">remove containers -weight: 500;">docker compose down -v # Also -weight: 500;">remove volumes -weight: 500;">docker compose logs -f app # Follow specific -weight: 500;">service -weight: 500;">docker compose exec app bash # Shell into -weight: 500;">service -weight: 500;">docker compose run app -weight: 500;">npm test # Run one-off command # -weight: 500;">docker-compose.yml key sections: # services, volumes, networks -weight: 500;">docker compose up # Start all services -weight: 500;">docker compose up -d # Detached mode -weight: 500;">docker compose up --build # Rebuild images first -weight: 500;">docker compose down # Stop & -weight: 500;">remove containers -weight: 500;">docker compose down -v # Also -weight: 500;">remove volumes -weight: 500;">docker compose logs -f app # Follow specific -weight: 500;">service -weight: 500;">docker compose exec app bash # Shell into -weight: 500;">service -weight: 500;">docker compose run app -weight: 500;">npm test # Run one-off command # -weight: 500;">docker-compose.yml key sections: # services, volumes, networks -weight: 500;">docker compose up # Start all services -weight: 500;">docker compose up -d # Detached mode -weight: 500;">docker compose up --build # Rebuild images first -weight: 500;">docker compose down # Stop & -weight: 500;">remove containers -weight: 500;">docker compose down -v # Also -weight: 500;">remove volumes -weight: 500;">docker compose logs -f app # Follow specific -weight: 500;">service -weight: 500;">docker compose exec app bash # Shell into -weight: 500;">service -weight: 500;">docker compose run app -weight: 500;">npm test # Run one-off command -weight: 500;">docker system prune # Remove all unused objects -weight: 500;">docker system prune -a --volumes # Nuclear option (data loss!) -weight: 500;">docker system df # Show Docker disk usage -weight: 500;">docker system prune # Remove all unused objects -weight: 500;">docker system prune -a --volumes # Nuclear option (data loss!) -weight: 500;">docker system df # Show Docker disk usage -weight: 500;">docker system prune # Remove all unused objects -weight: 500;">docker system prune -a --volumes # Nuclear option (data loss!) -weight: 500;">docker system df # Show Docker disk usage - CMD -- Default command/args, overridable with -weight: 500;">docker run <image> <cmd> - ENTRYPOINT -- Fixed executable, only overridable with --entrypoint flag - Combined -- ENTRYPOINT receives CMD as default arguments - 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. - 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 - 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 -weight: 500;">npm ci not -weight: 500;">npm -weight: 500;">install in Dockerfiles - EXPOSE doesn't publish ports. It's documentation only. Use -p to actually publish. - -weight: 500;">docker -weight: 500;">stop sends SIGTERM, then SIGKILL after 10s. Make sure your app handles SIGTERM gracefully. - Volumes aren't removed with -weight: 500;">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.