Docker Commands Cheat Sheet

Most used
docker ps -a                               # all containers, running or not
docker run -d --name web -p 8080:80 nginx  # run in the background, publish a port
docker logs -f web                         # follow a container's output
docker exec -it web sh                     # shell inside a running container
docker compose up -d                       # start the stack in compose.yaml
docker system df                           # what is using disk space

These commands are for Docker Engine on Linux with the Compose v2 plugin (docker compose, with a space). To install it on Ubuntu, Debian, Fedora or Arch, see Docker on Linux. If every command fails with a socket error, read permission denied on docker.sock. Most commands accept a container name or the first few characters of its ID.

Running containers

CommandWhat it does
docker run imageCreate and start a container in the foreground
docker run -d imageRun detached (in the background)
docker run -it ubuntu:26.04 bashInteractive shell in a new container
docker run --rm -it alpine shThrowaway container, removed on exit
docker run --name web nginxGive the container a name
docker run -p 8080:80 nginxPublish container port 80 on host port 8080 (all interfaces)
docker run -p 127.0.0.1:8080:80 nginxPublish on localhost only
docker run -v mydata:/var/lib/mysql mariadbMount a named volume
docker run -v "$PWD":/app -w /app node:22 npm testBind-mount the current directory and set the working dir
docker run -e TZ=Europe/Berlin --env-file .env imageSet environment variables
docker run --restart unless-stopped imageRestart automatically, including after reboot
docker run --memory 512m --cpus 1.5 imageLimit memory and CPU
docker run --network mynet imageAttach to a user-defined network
docker run --user "$(id -u):$(id -g)" imageRun as your UID so created files aren't owned by root

Managing containers

CommandWhat it does
docker psRunning containers
docker ps -aAll containers, with exit status
docker ps --format '{{.Names}}\t{{.Status}}\t{{.Ports}}'Custom columns
docker stop web / docker start webStop (SIGTERM, then SIGKILL after 10 s) / start again
docker restart webRestart
docker kill webKill immediately
docker rm webRemove a stopped container (-f stops it first)
docker rename old newRename a container
docker update --restart no webChange restart policy or limits on an existing container
docker cp web:/etc/nginx/nginx.conf .Copy files out of (or into) a container
docker commit web myimage:debugSave a container's state as an image (for debugging, not builds)

Logs, exec and inspection

CommandWhat it does
docker logs webContainer output (stdout and stderr)
docker logs -f --tail 100 webFollow, starting from the last 100 lines
docker logs --since 10m -t webLast 10 minutes, with timestamps
docker exec -it web bashShell in a running container (sh if no bash)
docker exec -u root -it web shShell as root even if the image uses another user
docker exec web cat /etc/os-releaseRun one command
docker inspect webFull JSON configuration and state
docker inspect -f '{{.State.ExitCode}} {{.State.OOMKilled}}' webWhy did it stop?
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' webContainer IP address
docker port webPublished port mappings
docker top webProcesses inside the container
docker statsLive CPU, memory and network use (--no-stream for one shot)
docker eventsStream of daemon events (starts, stops, OOM kills)

Images and builds

CommandWhat it does
docker imagesList local images (docker image ls)
docker pull nginx:1.29Download an image tag
docker build -t myapp:1.0 .Build from the Dockerfile in the current directory (BuildKit)
docker build -f docker/Dockerfile.prod -t myapp .Use a different Dockerfile
docker build --no-cache -t myapp .Rebuild every layer
docker buildx build --platform linux/amd64,linux/arm64 -t user/app --push .Multi-architecture build and push
docker tag myapp:1.0 registry.example.com/myapp:1.0Add another name to an image
docker login registry.example.comLog in to a registry
docker push registry.example.com/myapp:1.0Upload an image
docker rmi myapp:1.0Remove an image
docker history myapp:1.0Layers and their sizes
docker save -o myapp.tar myapp:1.0 / docker load -i myapp.tarMove images between machines without a registry

Volumes and networks

CommandWhat it does
docker volume lsList volumes
docker volume create mydataCreate a named volume
docker volume inspect mydataWhere it lives (/var/lib/docker/volumes/...)
docker volume rm mydataDelete a volume and its data
docker volume pruneDelete unused anonymous volumes (-a includes named ones)
docker network lsList networks
docker network create mynetUser-defined bridge: containers resolve each other by name
docker network connect mynet webAttach a running container
docker network inspect mynetSubnet and connected containers

Docker Compose (v2)

Run these in the directory with compose.yaml (or docker-compose.yml), or point to it with -f.

CommandWhat it does
docker compose up -dCreate and start all services in the background
docker compose up -d --buildRebuild images first
docker compose downStop and remove containers and networks (volumes are kept)
docker compose down -vAlso delete the stack's volumes (data loss)
docker compose psStatus of the stack's services
docker compose logs -f appFollow one service's logs
docker compose exec app shShell in a running service
docker compose run --rm app npm testOne-off command in a new container
docker compose pull && docker compose up -dUpdate images and recreate changed containers
docker compose restart appRestart a service (does not apply compose file changes)
docker compose configValidate and print the merged configuration
docker compose watchSync or rebuild on file changes (needs a develop section)
docker compose -p name -f other.yaml up -dCustom project name and file

Cleanup and disk space

Check before pruning

Prune commands delete without a backup. docker system prune -a --volumes removes every image not used by a container and every unused volume, which may include database data. Run docker system df -v first.

CommandWhat it does
docker system dfSpace used by images, containers, volumes and build cache
docker container pruneRemove all stopped containers
docker image pruneRemove dangling (untagged) images
docker image prune -aRemove all images not used by any container
docker builder pruneClear the BuildKit build cache
docker system pruneStopped containers, unused networks, dangling images, build cache
docker image prune -a --filter 'until=168h'Only images older than a week
docker rm $(docker ps -aq -f status=exited)Remove exited containers by filter

Common recipes

A minimal compose.yaml for a web app with a database:

services:
  app:
    image: ghcr.io/example/app:latest
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      DATABASE_URL: postgres://app:secret@db:5432/app
    depends_on:
      - db
    restart: unless-stopped
  db:
    image: postgres:17
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
    volumes:
      - dbdata:/var/lib/postgresql/data
    restart: unless-stopped
volumes:
  dbdata:

Back up and restore a named volume:

docker run --rm -v dbdata:/data -v "$PWD":/backup alpine tar -czf /backup/dbdata.tar.gz -C /data .
docker run --rm -v dbdata:/data -v "$PWD":/backup alpine tar -xzf /backup/dbdata.tar.gz -C /data

Port already taken when starting a container (address already in use)? Find the owner:

sudo ss -tlnp | grep ':8080 '
docker ps --filter publish=8080

Debug a container that exits immediately by overriding its command:

docker logs myapp
docker run --rm -it --entrypoint sh myimage

Run Docker without sudo (security note: the docker group is root-equivalent):

sudo usermod -aG docker "$USER"
newgrp docker      # or log out and back in
docker run --rm hello-world

Disk full because of Docker (see also No space left on device):

docker system df
docker builder prune -f
docker image prune -a -f
sudo du -sh /var/lib/docker/containers/*/*-json.log | sort -h | tail

Cap container log size globally in /etc/docker/daemon.json, then sudo systemctl restart docker (applies to new containers):

{
  "log-driver": "json-file",
  "log-opts": { "max-size": "10m", "max-file": "3" }
}

Gotchas

  • docker-compose vs docker compose. The hyphenated v1 tool is end-of-life and missing from current repos. Use the plugin: docker compose. On Debian/Ubuntu from Docker's repo the package is docker-compose-plugin.
  • Published ports bypass ufw and firewalld rules. Docker inserts its own iptables/nftables rules, so -p 8080:80 is reachable from the internet even if ufw denies 8080. Bind to 127.0.0.1: for local-only services.
  • Option order in docker run. Options go before the image name; anything after it is the command run inside the container. docker run nginx -p 80:80 passes -p to nginx.
  • Bind mounts and SELinux. On Fedora and other SELinux systems, a bind mount gives "permission denied" inside the container until you add :Z (private) or :z (shared): -v "$PWD":/app:Z. Don't use it on system directories like /home or /etc.
  • restart doesn't reload compose changes. After editing compose.yaml, run docker compose up -d to recreate the changed services.
  • :latest is not "newest". It's just a tag, and docker run won't re-pull it. Pin versions and docker compose pull to update.
  • Exit code 137 means SIGKILL, usually the OOM killer or a --memory limit; check docker inspect -f '{{.State.OOMKilled}}'. Exit code 143 is a normal SIGTERM stop.

Reference: Docker CLI reference and Docker Compose docs. The daemon itself is a systemd service; manage it with the systemctl cheat sheet.

Frequently asked questions

How do I get a shell inside a running container?

docker exec -it name bash, or sh for minimal images such as Alpine that don't include bash.

How do I remove all stopped containers and unused images?

docker container prune removes stopped containers and docker image prune -a removes images no container uses. docker system prune does containers, networks, dangling images and build cache in one go.

What is the difference between docker-compose and docker compose?

docker-compose is the old standalone Python v1 tool, which is end-of-life. docker compose (with a space) is the v2 plugin installed with Docker Engine; it reads the same compose.yaml files.

Why do I get permission denied on /var/run/docker.sock?

Your user isn't in the docker group. Add it with sudo usermod -aG docker $USER and log out and back in, or use rootless Docker. Membership in that group is equivalent to root access.

How do I see why a container exited?

docker ps -a shows the exit code and docker logs name shows its output. Exit code 137 usually means it was killed for using too much memory.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.