The Commands That Actually Matter
Docker has over 50 commands. You’ll use about 10 of them regularly. The rest are either for building images, managing swarm clusters, or edge cases you’ll look up once a year. This guide covers the 10 commands I run most frequently across six Docker hosts, with the flags I actually use rather than every flag in the man page.
From the homelab: I run Docker across my entire homelab — from a Proxmox cluster to Raspberry Pis. Every self-hosted service I operate runs in containers. Knowing these commands inside out saves hours of troubleshooting.
I’m going to skip the installation basics here. If you haven’t got Docker running yet, follow our guides for Ubuntu 24.04, Debian 12, or Raspberry Pi first, then come back.
Every example uses real homelab scenarios. No abstract “mycontainer” names. If you’re running a homelab with Docker, these are the situations you’ll actually encounter.

1. docker ps – What’s Running Right Now
This is the command you’ll run most often. It shows all currently running containers.
docker ps
Output shows container ID, image, command, created time, status, ports, and name. On a busy host, the default output wraps and becomes unreadable. Use --format to clean it up:
# Clean, readable output
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# Include stopped containers
docker ps -a
# Only show container IDs (useful for scripting)
docker ps -q
When you’ll use this: Every time you SSH into a Docker host. It’s your first check. “Is everything running?” Before you do anything else, run docker ps and make sure nothing has fallen over.
If you find yourself running docker ps --format with the same format string repeatedly, add an alias to your ~/.bashrc: alias dps='docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"'. Saves a lot of typing over time.
2. docker logs – What Went Wrong (or Right)
When a container crashes, misbehaves, or you just want to see what it’s doing, docker logs shows you the container’s stdout and stderr output.
# Show all logs for a container
docker logs portainer
# Follow logs in real time (like tail -f)
docker logs -f uptime-kuma
# Show last 50 lines
docker logs --tail 50 nginx
# Show logs with timestamps
docker logs -t grafana
# Combine: last 100 lines, then follow with timestamps
docker logs --tail 100 -ft nextcloud
When you’ll use this: When a container won’t start, when a service returns errors, or when you need to verify something is working. I check logs immediately after any docker compose up -d to make sure services started cleanly.
For Compose-managed containers, you can also use docker compose logs -f servicename from the project directory, which is slightly more convenient.
If you haven’t configured log rotation in your daemon.json, container logs grow without limit. I once had a Nextcloud container generate 12 GB of log data in a week. Check log sizes with docker system df -v and configure rotation as described in our Docker installation guide.
3. docker exec – Get Inside a Running Container
Sometimes you need to poke around inside a container. Maybe you need to check a config file, run a database query, or debug a networking issue. docker exec lets you run commands inside a running container.
# Open an interactive shell
docker exec -it nextcloud bash
# If bash isn't available (alpine images), use sh
docker exec -it redis sh
# Run a single command without entering the shell
docker exec mariadb mysql -u root -p -e "SHOW DATABASES;"
# Check what user a container runs as
docker exec portainer id
# View a file inside a container
docker exec nginx cat /etc/nginx/nginx.conf
The -it flags are almost always used together: -i keeps stdin open (interactive) and -t allocates a terminal. Without them, you get a non-interactive session that’s hard to use.
When you’ll use this: Debugging. A container is running but behaving oddly, and you need to see what’s happening from inside. Or you need to run a database migration, clear a cache, or check if a config file was mounted correctly. This is your “get inside and look around” tool.
Don’t make changes inside containers unless they’re persisted through a volume. Any modification to the container’s filesystem (outside of mounted volumes) is lost when the container restarts. If you need to change a config file, edit it on the host and restart the container.
4. docker compose up / down – Deploy and Tear Down
If you’re managing services with Docker Compose (and you should be), these are the commands that start and stop everything.
# Start all services in the background
docker compose up -d
# Stop and remove containers (volumes are preserved)
docker compose down
# Stop, remove, AND delete volumes (destructive - deletes data)
docker compose down -v
# Rebuild and restart (after changing a Dockerfile)
docker compose up -d --build
# Start only one specific service
docker compose up -d grafana
When you’ll use this: Every time you deploy, update, reconfigure, or troubleshoot a Compose-managed service. The typical workflow for updating a service is: docker compose pull (get latest images), then docker compose down && docker compose up -d.
For a deeper dive into Compose files, see our Docker Compose beginner’s guide.
Be very careful with docker compose down -v. The -v flag deletes named volumes, which is where your databases, application state, and persistent data live. I’ve seen people run this thinking it just stops containers. It doesn’t. It destroys data. Always double-check before adding -v.
5. docker system prune – Reclaim Disk Space
Docker accumulates cruft. Stopped containers, unused networks, dangling images (layers from previous builds that are no longer referenced), and build cache all consume disk space silently.
# See what's using space
docker system df
# Detailed breakdown
docker system df -v
# Remove stopped containers, unused networks, dangling images, build cache
docker system prune -f
# Also remove ALL unused images (not just dangling)
docker system prune -a -f
When you’ll use this: When your Docker host starts running low on disk space, or as part of regular monthly maintenance. I run docker system df weekly on all hosts and prune when reclaimable space exceeds a few gigabytes.
The difference between prune and prune -a matters. Without -a, it only removes “dangling” images (layers with no tag). With -a, it removes every image not used by a running container. If you’ve pulled images you plan to use later but haven’t started yet, -a will delete them.
6. docker stats – Live Resource Monitoring
A real-time view of CPU, memory, network, and disk I/O for all running containers. Think of it as top but for containers.
# Live stats for all containers
docker stats
# Stats for specific containers
docker stats nextcloud mariadb redis
# One-time snapshot (doesn't stream)
docker stats --no-stream
# Formatted output
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
When you’ll use this: When the host feels sluggish and you want to know which container is eating resources. When you’re deciding whether to add more RAM to a VM. When you want to verify that a memory limit you set in Compose is actually being respected.
Run docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}" to get a quick snapshot of memory usage across all containers. I run this before deploying a new service to check if there’s enough headroom. On a Pi with 4 GB RAM, this becomes essential planning information.
7. docker inspect – The Full Story
When you need detailed information about a container, image, network, or volume, docker inspect gives you everything in JSON format. It’s verbose, but it answers questions that no other command can.
# Full inspection (verbose JSON)
docker inspect nextcloud
# Get just the IP address
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nextcloud
# Get mounted volumes
docker inspect -f '{{json .Mounts}}' nextcloud | jq
# Get environment variables
docker inspect -f '{{json .Config.Env}}' nextcloud | jq
# Check restart policy
docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' nextcloud
When you’ll use this: Debugging networking issues (what IP does this container have?), verifying volume mounts are correct, checking what environment variables a container received, or finding out why a container’s restart policy isn’t working as expected.
The -f flag uses Go template syntax, which is awkward at first but powerful for extracting specific fields. Pipe to jq for readable JSON output.
8. docker network ls – Understanding Container Networking
Shows all Docker networks on the host. Each Compose project creates its own network, and understanding this helps debug connectivity issues.
# List all networks
docker network ls
# Inspect a specific network (shows which containers are connected)
docker network inspect bridge
# See which containers are on a network
docker network inspect monitoring_default --format '{{range .Containers}}{{.Name}} {{end}}'
When you’ll use this: When containers can’t reach each other. When you’re setting up cross-project networking (containers from different Compose files that need to communicate). When you want to verify that a container is on the network you expect.
Each Compose project creates a network named projectdirectory_default. Containers within that project can reach each other by service name. Containers on different networks can’t talk to each other unless you explicitly connect them or use an external network.
9. docker volume ls – Where Your Data Lives
Lists all Docker-managed volumes. These are the named volumes defined in your Compose files (or created manually) that persist container data.
# List all volumes
docker volume ls
# See detailed info about a volume
docker volume inspect nextcloud_nc_data
# Find volumes that aren't used by any container
docker volume ls -f dangling=true
# Remove unused volumes (careful!)
docker volume prune -f
When you’ll use this: When you need to find where a container’s data is stored on disk. When you’re backing up persistent data. When you’re cleaning up after removing old services and want to reclaim the volume space.
Treat docker volume prune with the same caution as rm -rf. It deletes volumes not attached to any running container. If you’ve stopped a service temporarily and its volumes are “dangling,” prune will destroy your data. Always check what’s dangling with docker volume ls -f dangling=true before pruning.
10. docker pull – Get the Latest Images
Downloads the latest version of an image from the registry. This is how you update your containers to the newest release.
# Pull a specific image
docker pull portainer/portainer-ce:latest
# Pull all images defined in a Compose file
docker compose pull
# Pull a specific service from a Compose file
docker compose pull grafana
When you’ll use this: Before updating services. The update workflow is: docker compose pull to download new image versions, then docker compose down && docker compose up -d to replace the running containers with the updated images.
docker compose pull is the one you’ll use most often, as it pulls updated images for all services in your Compose file at once.
Not all image updates are safe. Pulling latest for an application is usually fine, but pulling latest for a database can jump major versions and break things. Pin database images to specific versions (e.g., mariadb:10.11, postgres:16) and upgrade those deliberately after reading the release notes.
Bonus: Quick Combinations
These aren’t individual commands but combinations I use frequently enough that they’re worth mentioning:
# Restart a single container
docker restart nextcloud
# Stop all running containers (emergency brake)
docker stop $(docker ps -q)
# Remove all stopped containers
docker container prune -f
# Watch container logs across an entire Compose project
docker compose logs -f --tail 20
# Check if a container can reach the internet
docker exec nextcloud ping -c 3 1.1.1.1
# Check DNS resolution inside a container
docker exec nextcloud nslookup google.com
# Copy a file from a container to the host
docker cp nextcloud:/var/www/html/config/config.php ./config-backup.php
# See the last time a container was restarted
docker inspect -f '{{.State.StartedAt}}' nextcloud
Printable Cheat Sheet
Here’s a condensed reference you can keep handy. Print it, bookmark it, or save it to your notes app.
| Command | Purpose | Key Flags |
|---|---|---|
docker ps |
List running containers | -a (all), -q (IDs only), --format |
docker logs NAME |
View container output | -f (follow), --tail N, -t (timestamps) |
docker exec -it NAME bash |
Shell into a container | -it (interactive terminal) |
docker compose up -d |
Start Compose services | -d (detached), --build (rebuild) |
docker compose down |
Stop Compose services | -v (delete volumes too) |
docker system prune -f |
Clean up unused resources | -a (include unused images) |
docker stats |
Live resource usage | --no-stream (snapshot), --format |
docker inspect NAME |
Detailed container/network info | -f (format/filter) |
docker network ls |
List Docker networks | inspect NAME for details |
docker volume ls |
List persistent volumes | -f dangling=true (unused) |
docker pull IMAGE |
Download/update an image | docker compose pull for stacks |
In interviews for infrastructure and DevOps roles, you’ll often be asked to troubleshoot a scenario involving Docker. Knowing docker logs, docker exec, docker inspect, and docker stats gives you a methodical troubleshooting approach: check the logs, get inside the container, inspect the configuration, monitor resources. That systematic approach matters more than memorising every flag. Interviewers want to see how you think through problems, not whether you’ve memorised the man pages.
docker logs --tail 50 container_name to grab the last 50 lines. Pair with --timestamps when you need to correlate events with other services.Key Takeaways
docker psis your first command on any Docker host. Make it a habitdocker logs -fis your primary debugging tool. Check logs after every deploymentdocker exec -itgets you inside a container for hands-on debugging, but don’t make changes that aren’t persisted through volumesdocker compose up -danddocker compose downare your daily deployment commands. Never usedown -vunless you want to delete datadocker system pruneprevents disk space problems, butprune -aremoves images you might want to keepdocker statsshows you which container is consuming resources in real timedocker inspectanswers the detailed questions: IP address, mounts, environment variables, restart policy- Pin database images to specific versions. Use
latestfor applications, but update databases deliberately - Combine
docker compose pullfollowed bydownandup -dfor routine service updates
Related Guides
If you found this useful, these guides continue the journey:
- Docker Compose Beginner’s Guide — Learn to manage multi-container applications with Docker Compose
- How to Install Docker on Ubuntu 24.04 — Step-by-step Docker installation on Ubuntu 24.04 LTS
- How to Install Docker on Debian 12 — Install Docker on the most stable server OS available
- How to Install Docker on Raspberry Pi — Get Docker running on ARM-based Raspberry Pi hardware
- Uptime Kuma Docker Monitoring Setup — Monitor your services and get alerts when something goes down

ReadTheManual is run, written and curated by Eric Lonsdale.
Eric has over 20 years of professional experience in IT infrastructure, cloud architecture, and cybersecurity, but started with PCs long before that.
He built his first machine from parts bought off tables at the local college campus, hoping they worked. He learned on BBC Micros and Atari units in the early 90s, and has built almost every PC he’s used between 1995 and now.
From helpdesk to infrastructure architect, Eric has worked across enterprise datacentres, Azure environments, and security operations. He’s managed teams, trained engineers, and spent two decades solving the problems this site teaches you to solve.
ReadTheManual exists because Eric believes the best way to learn IT is to build things, break things, and actually read the manual. Every guide on this site runs on infrastructure he owns and maintains.
Enjoyed this guide?
New articles on Linux, homelab, cloud, and automation every 2 days. No spam, unsubscribe anytime.

