Docker Basics: The Daily Commands
Docker is the most popular container runtime — it wraps Linux’s namespaces and cgroups behind a friendly CLI and an image format that makes it trivial to package an app with all its dependencies and run it anywhere. This is the practical “what to type” guide.
Install
# Debian/Ubuntu (recommended: official repo, not distro version)
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# log out and back in for group change
# Verify
docker run hello-world
The core concepts
- Image — a read-only template (e.g.
nginx:latest). - Container — a running instance of an image.
- Volume — persistent storage, lives outside the container.
- Network — virtual network for containers to talk to each other.
- Registry — where images live (Docker Hub by default).
Run containers
# Run a one-off command
docker run --rm -it ubuntu:24.04 bash # interactive shell
docker run --rm alpine echo "hello" # run + print + exit
# Run as a long-lived service
docker run -d --name web -p 8080:80 nginx # detached, port forwarded
docker run -d --name db -e POSTGRES_PASSWORD=secret postgres
# Common run flags
-d detached (background)
-it interactive + tty (for shells)
--rm delete container when it exits
-p H:C map host port H to container port C
-v PATH:PATH bind mount a host directory
--name X give container a name
-e KEY=val set env var
--network N attach to network N
--restart=always restart on failure or boot
Inspect what’s running
docker ps # running containers
docker ps -a # also show stopped ones
docker logs web # see container output
docker logs -f web # follow logs
docker exec -it web bash # shell into a running container
docker inspect web # full JSON details
docker stats # live resource usage
docker top web # processes in container
Stop, start, remove
docker stop web # graceful (SIGTERM)
docker kill web # immediate (SIGKILL)
docker start web # start a stopped container
docker restart web
docker rm web # remove (must be stopped)
docker rm -f web # stop + remove
# Bulk cleanup
docker container prune # remove all stopped containers
docker rm $(docker ps -aq) # remove ALL containers (after stopping)
Images
docker images # list local images
docker pull nginx:1.25 # download specific tag
docker rmi nginx:1.25 # remove image
docker image prune # remove unused images
docker image prune -a # remove ALL unused images
docker history nginx # show image layers
Volumes (persistent data)
# Bind mount (host path → container path)
docker run -v /host/data:/var/data myapp
# Named volume (docker-managed)
docker volume create mydata
docker run -v mydata:/var/data myapp
docker volume ls
docker volume inspect mydata
docker volume prune # remove unused
# Read-only mount
docker run -v /host/conf:/etc/myapp:ro myapp
Networks
docker network ls
docker network create mynet
docker run -d --network=mynet --name=db postgres
docker run -d --network=mynet --name=app myapp # can reach 'db' by name
# Default network: 'bridge'
docker network inspect bridge
Build your own image
Create a Dockerfile:
# Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "app.py"]
Build and run:
docker build -t myapp:1.0 .
docker run -d -p 8000:8000 --name myapp myapp:1.0
docker compose (multi-container apps)
Define everything in one YAML file:
# compose.yaml
services:
web:
image: nginx
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
volumes:
- dbdata:/var/lib/postgresql/data
volumes:
dbdata:
Start everything:
docker compose up -d # start in background
docker compose logs -f # follow logs
docker compose ps # status
docker compose down # stop and remove everything
docker compose down -v # also remove volumes
Daily one-liners
# Quick disposable test environment
docker run --rm -it python:3.12 python
# Run a command using a tool you don't have installed
docker run --rm -v $(pwd):/work -w /work node:20 npm install
# Throwaway database for testing
docker run --rm -d -p 5432:5432 -e POSTGRES_PASSWORD=test postgres
# Reverse shell into a misbehaving container
docker exec -it web bash || docker exec -it web sh
# Total disk used by Docker
docker system df
docker system prune -a # clean EVERYTHING unused
Production tips
- Pin image versions (
nginx:1.25.3, notnginx:latest). - Use
--restart=alwaysor run via systemd. - Set resource limits:
--memory=512m --cpus=1. - Run as non-root inside containers (set
USERin Dockerfile). - Use named volumes for stateful data; never rely on container filesystem to persist.
- Use multi-stage builds to keep images small.
Common mistakes
- Storing data in the container filesystem — gone when container is removed.
- Running as root inside the container by default.
- Using
:latestin production — non-deterministic. - Not setting memory limits — one container can eat the whole host.
- Mounting
/var/run/docker.sockinto a container = root on the host.
What to learn next
You’ve reached the end of this roadmap. Where to go from here:
- Kubernetes if you want container orchestration.
- Cloud Linux — apply this knowledge on AWS, GCP, or DigitalOcean.
- Specialize — go deep on networking, security, or DevOps tooling.
The fundamentals you now have transfer everywhere Linux runs — which is most of the modern world.