Overview

This card covers the Docker commands you reach for every day: building images, running containers, inspecting state, managing networks and volumes, and cleaning up. For orchestration at scale, see kubernetes-commands. All examples assume Docker Engine 25+.

Build

Build before run; tag before push.

CommandWhat it does
docker build -t myapp:latest .Build from Dockerfile in current directory; tag as myapp:latest.
docker build -f docker/prod.Dockerfile -t myapp:prod .Use a non-default Dockerfile.
docker build --no-cache -t myapp:latest .Ignore layer cache; force full rebuild.
docker build --target builder -t myapp:builder .Stop at a named multi-stage stage.
docker build --build-arg NODE_ENV=production .Pass a build-time variable.
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest --push .Multi-platform build and push in one step.
docker image lsList local images with size and tag.
docker image prune -fRemove all dangling (untagged) images.
docker image rm myapp:oldDelete a specific image.

Use --target in multi-stage builds to produce a dev image with tools and a prod image without them from one Dockerfile.

Run

Set restart policy, resource limits, and environment at run time; those are harder to change after the container starts.

CommandWhat it does
docker run -d --name api -p 8080:8080 myapp:latestRun detached, name the container, map port.
docker run --rm -it myapp:latest bashDisposable interactive shell; container removed on exit.
docker run -e DATABASE_URL=postgres://... myapp:latestPass an environment variable.
docker run --env-file .env myapp:latestPass a file of environment variables.
docker run -v $(pwd)/data:/app/data myapp:latestBind-mount a host directory.
docker run -v pgdata:/var/lib/postgresql/data postgres:16Mount a named volume.
docker run --network mynet myapp:latestAttach to a user-defined network.
docker run --memory 512m --cpus 1.0 myapp:latestCap memory and CPU.
docker run --restart unless-stopped myapp:latestRestart unless explicitly stopped.

Prefer --env-file over -e for secrets; keep .env out of version control.

Inspect running containers

Read state before changing it.

CommandWhat it does
docker psRunning containers.
docker ps -aAll containers, including stopped.
docker logs apiTail log output.
docker logs -f --tail 100 apiFollow last 100 lines.
docker exec -it api bashOpen an interactive shell in a running container.
docker exec api envPrint environment variables.
docker inspect apiFull JSON metadata: mounts, network, config.
docker inspect api --format '{{.State.Status}}'Extract a single field with Go template.
docker statsLive CPU/memory/network/IO for all running containers.
docker top apiProcesses inside the container.

docker inspect --format beats piping to jq when the field path is known.

Networks and volumes

Isolate services with user-defined networks; never put unrelated containers on bridge.

CommandWhat it does
docker network create mynetCreate a user-defined bridge network.
docker network lsList networks.
docker network inspect mynetShow connected containers and subnet.
docker network connect mynet apiAttach a running container to a network.
docker volume create pgdataCreate a named volume.
docker volume lsList volumes.
docker volume inspect pgdataShow mountpoint and driver.
docker volume rm pgdataRemove a volume (data is gone).
docker system prune -a --volumesRemove all stopped containers, unused images, networks, and volumes.

Named volumes survive docker system prune unless you add --volumes.

Multi-stage Dockerfile pattern

Keep images small by discarding build tooling in the final stage.

# Stage 1: build
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
 
# Stage 2: runtime
FROM node:22-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 8080
CMD ["node", "dist/server.js"]

Use --target builder during CI to run tests in the build stage without publishing a test image.

Common gotchas

  • docker run without --rm leaves stopped containers behind. Run docker ps -a periodically; use docker container prune to clean them up.
  • Bind mounts on macOS are slow for large directories. Use named volumes for database data and rely on the Dockerfile COPY for source code.
  • docker exec on a container running a non-shell PID 1 (like a Go binary) will fail unless the image includes bash or sh. Use --entrypoint sh at run time instead.
  • COPY . . copies .env unless .dockerignore excludes it. Always add .env and node_modules to .dockerignore.
  • Port mapping -p host:container binds to 0.0.0.0 by default, exposing the port to all interfaces. Use -p 127.0.0.1:8080:8080 in development.
  • docker system prune -a --volumes is irreversible. Run docker system df first to see what would be removed.