🐳Docker & Containers
Master container fundamentals that power modern platforms. Build lean, secure images. Orchestrate multi-service apps. Enforce security at every layer from development to production.
Architecture & How It Works 04.1
Docker sits on top of containerd and runc. Containers isolate processes using Linux namespaces and control resources via cgroups v2. Images are built from read-only layers using OverlayFS union mounts. The Docker daemon manages the lifecycle on the host.
pid,net,mnt,uts,ipc,user] CG[cgroups v2] OV[OverlayFS layers] end App --> Daemon DockerCLI --> Daemon Daemon --> containerd --> runc runc --> NS runc --> CG runc --> OV
Image Layers & Caching
Each instruction in a Dockerfile creates a layer. Docker reuses layers when possible. Order instructions from least-changing (base image, dependencies) to most-changing (source code) for best cache performance.
Networking Models
bridge (default isolated), host (shares host network), overlay (Swarm / Kubernetes), macvlan (direct L2). Always create custom bridge networks for multi-container apps instead of relying on default bridge.
Core Components & Concepts 04.2
| Concept | Key Primitives | Production Notes |
|---|---|---|
| Dockerfile | FROM, RUN, COPY --chown, CMD, ENTRYPOINT, USER, HEALTHCHECK | Multi-stage + non-root + read-only rootfs |
| Compose | services, volumes, networks, profiles, depends_on | Use compose v2, healthchecks, restart policies |
| Volumes | Named volumes vs bind mounts | Prefer named volumes in prod; backup with docker cp |
| Networking | docker network create mynet | Use DNS names between services inside custom networks |
| Security | Trivy, docker scout, cosign, --cap-drop, read-only | Scan in pipeline; sign images; run rootless |
docker buildx with --cache-from and --cache-to in CI for massive speed gains on subsequent builds.WSL Hands-On Lab 04.3
Full End-to-End: Install → Build → Optimize → Scan → Compose → Rootless
$ curl -fsSL https://get.docker.com | sh $ sudo usermod -aG docker $USER && newgrp docker $ docker run hello-world
Optimized Multi-Stage Dockerfile (Node example)
# syntax=docker/dockerfile:1
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
FROM node:20-alpine AS runner
RUN apk add --no-cache dumb-init
ENV NODE_ENV=production
USER node
WORKDIR /app
COPY --from=deps --chown=node:node /app/node_modules ./node_modules
COPY --chown=node:node . .
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s CMD node -e "require('http').get('http://localhost:3000/health', r => process.exit(r.statusCode === 200 ? 0 : 1))"
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "server.js"]$ docker build -t myapi:prod . $ docker images | grep myapi $ # Install trivy $ curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin $ trivy image --severity HIGH,CRITICAL myapi:prod
docker-compose.yml — 3-tier production-ready
version: '3.8'
services:
api:
build: .
environment:
DATABASE_URL: postgres://app:secret@db:5432/appdb
depends_on: { db: { condition: service_healthy } }
networks: [appnet]
read_only: true
security_opt: ["no-new-privileges:true"]
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: appdb
volumes: [pgdata:/var/lib/postgresql/data]
healthcheck: { test: ["CMD-SHELL", "pg_isready -U app"], interval: 10s }
networks: [appnet]
redis:
image: redis:7-alpine
networks: [appnet]
nginx:
image: nginx:alpine
ports: ["80:80"]
volumes: ["./nginx.conf:/etc/nginx/conf.d/default.conf:ro"]
depends_on: [api]
networks: [appnet]
volumes: { pgdata: {} }
networks: { appnet: { driver: bridge } }$ docker compose up -d --build $ docker compose ps $ docker compose logs -f api $ # Rootless experiment (requires Docker 20.10+) $ dockerd-rootless-setuptool.sh install
Lab Checklist — Track Progress
- Install Docker Engine in WSL2 and validate with hello-world
- Write naive Dockerfile and measure final image size
- Rewrite using multi-stage, alpine, non-root, HEALTHCHECK
- Scan final image with Trivy, document HIGH/CRITICAL fixes
- Create full docker-compose.yml for 3-tier app with healthchecks
- Run compose stack and validate inter-service networking
- Complete Play with Docker + Killercoda Docker fundamentals labs↗
Real-World Project — Startup → Enterprise 04.4
Containerize Express API for a single service
One Dockerfile, .dockerignore, basic CI build. Push to GHCR. Deploy manually or with simple compose on a VM.
Multi-service Compose with postgres, redis, nginx reverse proxy
Environment-specific compose overrides, named volumes, custom bridge networks, healthchecks, rolling updates via compose.
Rootless containers + read-only filesystems + distroless + OCI compliance
Run daemon rootless, drop all capabilities except NET_BIND_SERVICE, use chainguard or distroless images, sign every image with cosign, enforce image signing in admission controller.
Troubleshooting Guide 04.5
docker logs <id> docker inspect <id> | jq '.[0].State' docker run --rm -it --entrypoint sh myimage
Use dive tool. Combine RUN commands. Use alpine or distroless. Remove apt/yum caches in same layer.
Confirm they are on same custom network. Use service names for DNS. Check exposed vs published ports.
Match container UID/GID to host folder owner or use init container chown. Prefer named volumes managed by Docker.
Read logs. Increase restart policy grace. Add liveness/readiness probes. Check resource limits causing OOM.
30-Day Learning Roadmap 04.6
- Every instruction & cache rules
- Multi-stage patterns
- Small base images
- Non-root users
- Compose file deep dive
- Custom networks
- Volumes & secrets
- Healthchecks & depends
- Trivy + Grype + dockle
- Rootless + capabilities
- Distroless images
- Image signing
- GHCR / ECR / Harbor
- Buildx + cache export
- Cosign + SBOM
- Registry policies
Deep Dive: Image Optimization & Security Patterns 04.7
Layer Optimization Techniques
Combine RUN commands. Use .dockerignore aggressively. Copy only what is needed. Use build args for environment-specific layers. Leverage BuildKit cache mounts for npm/yarn/pip.
# syntax=docker/dockerfile:1
RUN --mount=type=cache,target=/root/.npm npm ciSecurity Hardening Checklist
- Non-root user in final stage
- Read-only root filesystem
- Drop all capabilities except required
- No package managers in prod image
- Signed images + SBOM