A quick-reference for Docker and Docker Compose. Docker packages applications into containers — isolated, reproducible environments that run the same everywhere. Images are the blueprint; containers are running instances of an image.
Images are immutable snapshots built from a Dockerfile. Each
RUN, COPY, and
ADD instruction creates a new layer — layers are
cached, so order matters for build speed.
docker pull nginx:alpine
docker push myuser/myimage:1.0
docker build -t myimage:latest .
docker build -t myimage:latest -f Dockerfile.prod .
(-t sets the name:tag; -f specifies a non-default Dockerfile)
Tag an image:docker tag myimage:latest myuser/myimage:1.0
List / remove images:docker imagesdocker rmi myimage:latest
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Containers are running instances of an image. They are ephemeral by default — any filesystem changes are lost when the container is removed. Use volumes to persist data.
docker run -d -p 8080:80 --name web nginx
docker run -it --rm ubuntu bash # interactive, auto-remove on exit
docker run -e ENV_VAR=value myimage # set environment variable
(-d = detached/background, -p = host:container port, -it = interactive TTY)
List containers:docker psdocker ps -a
(-a includes stopped containers)
Start / stop / restart:docker start webdocker stop webdocker restart web
docker exec -it web bash
docker exec web ls /app
docker logs web
docker logs -f web # follow live
docker logs --tail 100 web # last 100 lines
Copy files to/from container:docker cp ./local.txt web:/app/local.txtdocker cp web:/app/output.txt ./output.txt
Inspect a container:docker inspect web
(returns full JSON config — IP, mounts, env vars, etc.)
Volumes persist data outside the container lifecycle. Named volumes are managed by Docker; bind mounts map a host path directly into the container.
docker volume create mydata
docker run -v mydata:/app/data myimage
docker volume ls
docker volume rm mydata
docker run -v /host/path:/container/path myimage
docker run -v $(pwd):/app myimage # mount current dir
(bind mounts reflect live changes — useful for development)
Containers on the same network can communicate by container name. The default bridge network doesn't support DNS; create a custom network instead.
docker network create mynet
docker run --network mynet --name db postgres
docker run --network mynet --name app myimage # can reach "db" by name
List / inspect / remove:docker network lsdocker network inspect mynetdocker network rm mynet
Compose defines multi-container applications in a
docker-compose.yml file. It handles networking,
volumes, and startup order automatically.
docker compose up -d # start in background
docker compose down # stop and remove containers
docker compose down -v # also remove volumes
docker compose build # rebuild images
docker compose ps # list services
docker compose logs -f # follow all service logs
docker compose exec app bash # shell into a service
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data
app:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://postgres:secret@db/mydb
depends_on:
- db
volumes:
pgdata:
Docker accumulates stopped containers, dangling images, and unused
volumes over time. Use prune commands to reclaim
disk space.
docker container prune # remove stopped containers
docker image prune # remove dangling (untagged) images
docker volume prune # remove unused volumes
docker network prune # remove unused networks
docker system prune -a --volumes
(removes all stopped containers, unused images, volumes, and networks — use with care)
Check disk usage:docker system df