Docker for Beginners: What, Why, and How
Docker packages your application and its dependencies into a lightweight, portable container.
Containers vs Virtual Machines
┌─────────────────────┐ ┌─────────────────────┐
│ App A │ App B │ │ App A │ App B │
├───────────┴─────────┤ ├─────────┴───────────┤
│ Guest OS │ Guest OS│ │ Docker Engine │
├─────────────────────┤ ├─────────────────────┤
│ Hypervisor │ │ Host OS │
├─────────────────────┤ ├─────────────────────┤
│ Host OS │ │ Hardware │
├─────────────────────┤ └─────────────────────┘
│ Hardware │
└─────────────────────┘
Virtual Machines ContainersKey differences:
| VMs | Containers | |
|---|---|---|
| Boot time | Minutes | Seconds |
| Size | GBs | MBs |
| OS per unit | Full OS | Shared host OS |
| Isolation | Strong | Process-level |
Installing Docker
# Ubuntu / Debian
sudo apt update
sudo apt install docker.io
# macOS / Windows
# Download Docker Desktop from docker.com
# Verify
docker --version
docker run hello-worldYour First Docker Container
# Run an interactive Ubuntu container
docker run -it ubuntu bash
# Run Nginx in the background
docker run -d -p 8080:80 nginx
# Visit http://localhost:8080Dockerfile
A Dockerfile tells Docker how to build your image:
FROM python:3.11-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 my-app .
docker run -p 8000:8000 my-appCommon Commands
# Images
docker images # list images
docker pull nginx # download image
docker rmi nginx # remove image
# Containers
docker ps # running containers
docker ps -a # all containers
docker run nginx # create + start
docker start CONTAINER_ID # start existing
docker stop CONTAINER_ID # stop
docker rm CONTAINER_ID # remove
# Logs and exec
docker logs CONTAINER_ID # view logs
docker logs -f CONTAINER_ID # follow logs
docker exec -it CONTAINER_ID bash # shell inside container
# Cleanup
docker system prune # remove unused containers, images, networks
docker system prune -a # remove everything unusedDocker Compose
Define multi-container applications in YAML:
# docker-compose.yml
services:
web:
build: .
ports:
- "8000:8000"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:docker compose up -d # start all services
docker compose down # stop and remove
docker compose logs -f # follow all logsUseful Dockerfile Instructions
FROM node:20-alpine AS builder # multi-stage build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html# Layer caching optimization
COPY requirements.txt . # COPY first, then RUN
RUN pip install -r requirements.txt # cached if requirements.txt unchanged
COPY . . # only then copy sourceBest Practices
- Use specific tags —
python:3.11-slim, notpython:latest - Use
.dockerignore— excludenode_modules,__pycache__,.git - Minimize layers — combine
RUNcommands with&& - Don’t run as root — use
USERinstruction - Multi-stage builds — keep final images small
- Scan for vulnerabilities —
docker scout quickview
Related: Fix docker-compose errors and learn Dockerfile best practices.