Docker Commands Cheat Sheet
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
| Command | What it does |
|---|---|
docker run image | Create and start a container in the foreground |
docker run -d image | Run detached (in the background) |
docker run -it ubuntu:26.04 bash | Interactive shell in a new container |
docker run --rm -it alpine sh | Throwaway container, removed on exit |
docker run --name web nginx | Give the container a name |
docker run -p 8080:80 nginx | Publish container port 80 on host port 8080 (all interfaces) |
docker run -p 127.0.0.1:8080:80 nginx | Publish on localhost only |
docker run -v mydata:/var/lib/mysql mariadb | Mount a named volume |
docker run -v "$PWD":/app -w /app node:22 npm test | Bind-mount the current directory and set the working dir |
docker run -e TZ=Europe/Berlin --env-file .env image | Set environment variables |
docker run --restart unless-stopped image | Restart automatically, including after reboot |
docker run --memory 512m --cpus 1.5 image | Limit memory and CPU |
docker run --network mynet image | Attach to a user-defined network |
docker run --user "$(id -u):$(id -g)" image | Run as your UID so created files aren't owned by root |
Managing containers
| Command | What it does |
|---|---|
docker ps | Running containers |
docker ps -a | All containers, with exit status |
docker ps --format '{{.Names}}\t{{.Status}}\t{{.Ports}}' | Custom columns |
docker stop web / docker start web | Stop (SIGTERM, then SIGKILL after 10 s) / start again |
docker restart web | Restart |
docker kill web | Kill immediately |
docker rm web | Remove a stopped container (-f stops it first) |
docker rename old new | Rename a container |
docker update --restart no web | Change 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:debug | Save a container's state as an image (for debugging, not builds) |
Logs, exec and inspection
| Command | What it does |
|---|---|
docker logs web | Container output (stdout and stderr) |
docker logs -f --tail 100 web | Follow, starting from the last 100 lines |
docker logs --since 10m -t web | Last 10 minutes, with timestamps |
docker exec -it web bash | Shell in a running container (sh if no bash) |
docker exec -u root -it web sh | Shell as root even if the image uses another user |
docker exec web cat /etc/os-release | Run one command |
docker inspect web | Full JSON configuration and state |
docker inspect -f '{{.State.ExitCode}} {{.State.OOMKilled}}' web | Why did it stop? |
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web | Container IP address |
docker port web | Published port mappings |
docker top web | Processes inside the container |
docker stats | Live CPU, memory and network use (--no-stream for one shot) |
docker events | Stream of daemon events (starts, stops, OOM kills) |
Images and builds
| Command | What it does |
|---|---|
docker images | List local images (docker image ls) |
docker pull nginx:1.29 | Download 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.0 | Add another name to an image |
docker login registry.example.com | Log in to a registry |
docker push registry.example.com/myapp:1.0 | Upload an image |
docker rmi myapp:1.0 | Remove an image |
docker history myapp:1.0 | Layers and their sizes |
docker save -o myapp.tar myapp:1.0 / docker load -i myapp.tar | Move images between machines without a registry |
Volumes and networks
| Command | What it does |
|---|---|
docker volume ls | List volumes |
docker volume create mydata | Create a named volume |
docker volume inspect mydata | Where it lives (/var/lib/docker/volumes/...) |
docker volume rm mydata | Delete a volume and its data |
docker volume prune | Delete unused anonymous volumes (-a includes named ones) |
docker network ls | List networks |
docker network create mynet | User-defined bridge: containers resolve each other by name |
docker network connect mynet web | Attach a running container |
docker network inspect mynet | Subnet and connected containers |
Docker Compose (v2)
Run these in the directory with compose.yaml (or docker-compose.yml), or point to it with -f.
| Command | What it does |
|---|---|
docker compose up -d | Create and start all services in the background |
docker compose up -d --build | Rebuild images first |
docker compose down | Stop and remove containers and networks (volumes are kept) |
docker compose down -v | Also delete the stack's volumes (data loss) |
docker compose ps | Status of the stack's services |
docker compose logs -f app | Follow one service's logs |
docker compose exec app sh | Shell in a running service |
docker compose run --rm app npm test | One-off command in a new container |
docker compose pull && docker compose up -d | Update images and recreate changed containers |
docker compose restart app | Restart a service (does not apply compose file changes) |
docker compose config | Validate and print the merged configuration |
docker compose watch | Sync or rebuild on file changes (needs a develop section) |
docker compose -p name -f other.yaml up -d | Custom project name and file |
Cleanup and disk space
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.
| Command | What it does |
|---|---|
docker system df | Space used by images, containers, volumes and build cache |
docker container prune | Remove all stopped containers |
docker image prune | Remove dangling (untagged) images |
docker image prune -a | Remove all images not used by any container |
docker builder prune | Clear the BuildKit build cache |
docker system prune | Stopped 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-composevsdocker 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 isdocker-compose-plugin.- Published ports bypass ufw and firewalld rules. Docker inserts its own iptables/nftables rules, so
-p 8080:80is reachable from the internet even if ufw denies 8080. Bind to127.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:80passes-pto 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/homeor/etc. restartdoesn't reload compose changes. After editingcompose.yaml, rundocker compose up -dto recreate the changed services.:latestis not "newest". It's just a tag, anddocker runwon't re-pull it. Pin versions anddocker compose pullto update.- Exit code 137 means SIGKILL, usually the OOM killer or a
--memorylimit; checkdocker 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.