// Basics
// WHAT IS DOCKER
Docker packages applications and their dependencies into containers — isolated, portable environments that run the same way on any machine.
// IMAGE vs CONTAINER
An image is a read-only blueprint. A container is a live, running instance of that image. One image can spawn many containers.
// DOCKERFILE
A plain text file with instructions to build a custom image. Each instruction creates a new layer — Docker caches layers to speed up rebuilds.
Quick check: Run docker --version and docker info to confirm Docker is installed and the daemon is running.
// Images
docker pull nginx # download image from Docker Hub docker pull ubuntu:22.04 # pull specific tag/version docker images # list local images docker image ls # same as above docker rmi nginx # remove image docker image prune # remove all dangling images
// Building a custom image
FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD ["node", "server.js"]
docker build -t myapp:1.0 . # build image from Dockerfile in current dir docker build -t myapp:1.0 -f Dockerfile.prod . # use specific Dockerfile docker tag myapp:1.0 myuser/myapp:1.0 # tag for pushing docker push myuser/myapp:1.0 # push to Docker Hub
// Containers
# Run docker run nginx # run in foreground docker run -d nginx # run detached (background) docker run -d -p 8080:80 nginx # map host:container port docker run -it ubuntu bash # interactive shell docker run --name webserver -d nginx # give it a name docker run --rm -it alpine sh # auto-remove when stopped # Inspect docker ps # list running containers docker ps -a # list all (including stopped) docker logs <id> # view container logs docker logs -f <id> # follow logs live docker inspect <id> # full JSON details docker stats # live CPU/RAM usage # Control docker stop <id> # graceful stop docker kill <id> # force stop docker start <id> # restart stopped container docker rm <id> # remove stopped container docker rm -f <id> # force remove running container # Access docker exec -it <id> bash # shell into running container docker exec <id> ls /app # run single command inside docker cp <id>:/app/log.txt ./ # copy file out of container
Note: Container IDs can be shortened — you only need enough characters to be unique. docker stop a3f works if no other container starts with a3f.
// Volumes
// NAMED VOLUME
Managed by Docker. Persists data across container restarts and removals. Best for databases and app data.
// BIND MOUNT
Maps a host directory directly into the container. Useful in development — changes on host reflect instantly inside.
// TMPFS MOUNT
Stored in host memory only. Not persisted to disk. Good for sensitive temporary data.
# Named volumes docker volume create mydata docker volume ls docker volume inspect mydata docker volume rm mydata # Mount a named volume docker run -d -v mydata:/var/lib/mysql mysql # Bind mount (dev workflow) docker run -d -v $(pwd):/app -p 3000:3000 myapp # Tmpfs mount docker run --tmpfs /tmp myapp
// Networking
| NETWORK TYPE | DESCRIPTION |
|---|---|
bridge | Default. Containers on same bridge can talk to each other. |
host | Container shares the host's network stack directly. |
none | No network access at all. |
overlay | Multi-host networking (Docker Swarm). |
macvlan | Container gets its own MAC address on the physical network. |
docker network ls # list networks docker network create mynet # create custom bridge network docker network inspect mynet # detailed info docker network rm mynet # Attach container to network docker run -d --network mynet --name app1 myapp docker run -d --network mynet --name app2 myapp # app1 and app2 can now reach each other by name # Connect running container to network docker network connect mynet <id> docker network disconnect mynet <id>
// Docker Compose
// WHAT IS COMPOSE
Compose lets you define and run multi-container applications in a single docker-compose.yml file. One command to start everything.
// WHEN TO USE IT
Any time you need multiple services together — e.g. a web app + database + cache. Compose wires them up automatically.
version: '3.9' services: web: build: . ports: - "3000:3000" volumes: - .:/app depends_on: - db environment: - DATABASE_URL=postgres://user:pass@db:5432/mydb db: image: postgres:15 volumes: - pgdata:/var/lib/postgresql/data environment: - POSTGRES_PASSWORD=pass - POSTGRES_USER=user - POSTGRES_DB=mydb volumes: pgdata:
docker compose up # start all services docker compose up -d # start detached docker compose up --build # rebuild images then start docker compose down # stop and remove containers docker compose down -v # also remove volumes docker compose logs -f # follow logs for all services docker compose ps # status of services docker compose exec web bash # shell into a service docker compose restart web # restart one service
// Cleanup
Warning: docker system prune -a removes ALL unused images, containers, networks and build cache. Make sure you know what you're deleting.
# Containers docker rm $(docker ps -aq) # remove all stopped containers docker container prune # same, with confirmation # Images docker image prune # remove dangling images docker image prune -a # remove all unused images # Volumes docker volume prune # remove unused volumes # Everything at once docker system prune # containers + networks + dangling images docker system prune -a # add unused images too docker system df # show disk usage breakdown