Docker

Docker Certified Associate (DCA)

From your first container to production-grade Swarm clusters. This course walks you through every domain on the DCA exam — images, networking, volumes, orchestration, and security — with hands-on commands and real-world scenarios.

Docker 6 Modules ~25 hours Intermediate 60 practice questions
01 Container Fundamentals & Docker Architecture ~3h

Understand what containers are, how they differ from VMs, and the components that make Docker work. This is the foundation everything else builds on.

Containers vs Virtual Machines

VMs virtualize hardware and each runs a full OS kernel. Containers share the host kernel and isolate at the process level using Linux namespaces and cgroups — they are faster to start, use less memory, and are more portable.

  • Namespaces — isolate PID, network, mount, UTS (hostname), IPC, and user spaces per container
  • cgroups (control groups) — limit and account for CPU, memory, I/O, and network usage
  • Union file system (OverlayFS) — layered filesystem where each image layer is read-only; a writable layer is added per container

Docker Architecture Components

  • dockerd — the Docker daemon (server process), listens on the Docker socket
  • Docker CLI — the docker command, communicates with dockerd via REST API over the Unix socket or TCP
  • containerd — the container runtime that dockerd delegates to; manages container lifecycle (pull, run, stop)
  • runc — the OCI-compliant low-level runtime that actually creates containers from bundles
  • Docker Registry — stores and distributes images (Docker Hub is the default public registry)

Core Object Types

  • Image — a read-only template for creating containers; built from a Dockerfile; identified by digest (SHA256) and tag
  • Container — a running instance of an image; adds a writable layer; ephemeral by default (data lost on removal)
  • Volume — managed persistent storage that survives container removal
  • Network — virtual network that connects containers; multiple drivers available

Essential CLI Commands

# Run a container interactively
docker run -it ubuntu bash

# Run detached with name and port mapping
docker run -d --name webserver -p 8080:80 nginx

# List running containers
docker ps

# List all containers (including stopped)
docker ps -a

# Stop and remove
docker stop webserver && docker rm webserver

# Pull image without running
docker pull alpine:3.19

# Show image layers
docker history nginx:latest
Key concept: docker run = docker create + docker start. Understanding this distinction matters — containers can exist in stopped state without consuming CPU or RAM, but still use disk space for their writable layer.
DCA Exam Tip: Know the difference between docker stop (sends SIGTERM, waits 10s, then SIGKILL) and docker kill (sends SIGKILL immediately). Also know that docker rm -f force-removes a running container.
02 Images & Dockerfile Mastery ~5h

Building images is a core DCA domain. Master Dockerfile instructions, layer caching, multi-stage builds, and image management from pull to push to registry.

Dockerfile Instructions Reference

  • FROM — base image; every Dockerfile must start with FROM (or ARG before FROM for multi-platform builds)
  • RUN — executes a command during build, creating a new layer; chain with && to minimize layers
  • COPY — copies files from build context to image; prefer over ADD for simple files
  • ADD — like COPY but also extracts tar archives and supports URLs; use only when you need these features
  • ENV — sets environment variables available at runtime; persisted in image metadata
  • ARG — build-time variables passed with --build-arg; not available at runtime (unlike ENV)
  • CMD — default command when container starts; overridden by arguments to docker run
  • ENTRYPOINT — configures the container as an executable; CMD arguments are appended to it
  • EXPOSE — documents which port the container listens on; does NOT publish the port
  • WORKDIR — sets working directory for subsequent RUN/COPY/CMD instructions
  • USER — sets the user for subsequent RUN/CMD/ENTRYPOINT instructions (security: never run as root in production)
  • HEALTHCHECK — command Docker runs to check if the container is healthy
  • VOLUME — declares a mount point; automatically creates an anonymous volume if not explicitly mounted
CMD vs ENTRYPOINT: Use ENTRYPOINT for the fixed executable and CMD for default arguments. With both: ENTRYPOINT ["nginx"] + CMD ["-g", "daemon off;"] — running docker run myimage -t replaces CMD but keeps ENTRYPOINT.

Multi-Stage Builds

Multi-stage builds drastically reduce final image size by using intermediate build stages that are discarded:

# Stage 1: build
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .

# Stage 2: minimal runtime image
FROM alpine:3.19
WORKDIR /app
COPY --from=builder /app/myapp .
USER nobody
CMD ["./myapp"]

Layer Caching Best Practices

  • Put frequently changing instructions (COPY source code) AFTER rarely changing ones (RUN apt-get install)
  • Copy dependency files first, install, then copy source: COPY package.json . → RUN npm install → COPY . .
  • Use .dockerignore to exclude node_modules, .git, test files from the build context
  • Use --no-cache flag to force a clean rebuild: docker build --no-cache .

Image Management

# Build with tag
docker build -t myapp:1.0 .

# Tag an existing image
docker tag myapp:1.0 registry.example.com/myapp:1.0

# Push to registry
docker push registry.example.com/myapp:1.0

# Inspect image layers
docker inspect myapp:1.0

# Remove dangling images (untagged)
docker image prune

# Remove all unused images
docker image prune -a

# Save image to tar archive
docker save myapp:1.0 | gzip > myapp.tar.gz

# Load image from tar
docker load < myapp.tar.gz
save vs export: docker save preserves image history and layers (use for image migration). docker export exports a container's filesystem as a flat tar (loses history). docker import creates a new image from a tar but without layer history.
03 Storage: Volumes, Bind Mounts & tmpfs ~3h

Containers are ephemeral — any data written inside is lost when the container is removed. Storage drivers and mount types solve this problem for different scenarios.

Three Mount Types

  • Named Volumes — managed by Docker, stored in /var/lib/docker/volumes/; best for persistent data, shareable between containers, portable
  • Bind Mounts — maps a host path directly into the container; best for development (live code reload), config files; tight coupling to host filesystem
  • tmpfs Mounts — stored in host memory only (never written to disk); best for sensitive data (secrets, session tokens) that must not persist
# Named volume (--mount syntax, preferred)
docker run -d \
  --mount type=volume,src=mydata,dst=/app/data \
  postgres:16

# Bind mount
docker run -d \
  --mount type=bind,src=/home/user/config,dst=/app/config,readonly \
  myapp

# tmpfs mount (Linux only)
docker run -d \
  --mount type=tmpfs,dst=/tmp \
  myapp

# Volume operations
docker volume create mydata
docker volume ls
docker volume inspect mydata
docker volume rm mydata
docker volume prune  # removes all unused volumes
DCA Exam Tip: Know both the old -v flag syntax and the new --mount flag syntax. The --mount flag is explicit, self-documenting, and preferred. A key difference: -v creates the host path if it doesn't exist; --mount type=bind requires the path to already exist.

Storage Drivers

Docker uses storage drivers to manage the image layers and writable container layer on the host. Common drivers:

  • overlay2 — default and recommended driver for Linux; uses OverlayFS kernel feature; efficient for most workloads
  • devicemapper — older driver, used on RHEL/CentOS without overlay support; generally being phased out
  • btrfs / zfs — filesystem-level drivers with snapshotting; require specific filesystems
Volume plugins: Docker supports storage volume plugins (like Portworx, NetApp Trident, or AWS EBS) that allow volumes to be backed by external storage systems. This is important in enterprise environments for persistent workloads.
🎧
Study smarter — listen while you learn Our podcast covers Docker, containers, cloud, and cert prep in short episodes you can queue between modules. Perfect for commutes and revision sessions.
Listen on Spotify
04 Docker Networking: Bridge, Overlay & Host ~4h

Docker networking isolates and connects containers. Understanding each driver's use case and behavior is tested heavily on the DCA exam.

Network Drivers

  • bridge — default for standalone containers; creates a virtual switch (docker0 or custom); containers on the same bridge network can communicate by IP; custom bridges enable DNS-based service discovery by container name
  • host — container shares the host's network stack directly; no isolation; useful for performance-sensitive workloads; Linux only
  • overlay — multi-host network used in Docker Swarm; uses VXLAN encapsulation; enables service-to-service communication across nodes
  • none — disables all networking; completely isolated container with only a loopback interface
  • macvlan — assigns a MAC address to the container, making it appear as a physical device on the network; useful for legacy applications that expect direct LAN access
Key DCA fact: On the default bridge network, containers cannot communicate by name — only by IP. On a custom bridge network, Docker's embedded DNS server resolves container names automatically. Always use custom bridge networks for production compose setups.

Common Networking Commands

# Create a custom bridge network
docker network create --driver bridge mynet

# Run containers on the same network
docker run -d --name db --network mynet postgres:16
docker run -d --name app --network mynet myapp

# app can reach db at hostname "db"
# Inspect a network
docker network inspect mynet

# Connect a running container to a network
docker network connect mynet existing_container

# List networks
docker network ls

# Remove unused networks
docker network prune

Port Publishing

  • -p 8080:80 — maps host port 8080 to container port 80 (TCP)
  • -p 127.0.0.1:8080:80 — binds to localhost only (more secure)
  • -p 8080:80/udp — UDP port mapping
  • -P — publishes all EXPOSE'd ports to random host ports
Overlay networks in Swarm: When you create an overlay network in Swarm mode (docker network create --driver overlay myoverlay), Swarm automatically manages the VXLAN tunnels between nodes. Services on the same overlay network can reach each other by service name, and Swarm handles load balancing across replicas.
05 Docker Swarm: Orchestration at Scale ~5h

Docker Swarm is Docker's native clustering and orchestration system. The DCA exam allocates 25% of its questions to Swarm — it's the heaviest domain.

Swarm Architecture

  • Manager nodes — maintain cluster state using the Raft distributed consensus algorithm; accept CLI commands and schedule services; recommended odd number (1, 3, 5)
  • Worker nodes — execute tasks (containers); report status back to managers
  • Raft quorum — to maintain cluster availability, more than half of managers must be reachable: for 3 managers, tolerate 1 failure; for 5 managers, tolerate 2 failures
  • Service — the desired state declaration: image, replicas, ports, constraints
  • Task — a single container running on a specific node; the atomic unit of scheduling
Quorum formula: A Swarm with N managers can tolerate ⌊(N-1)/2⌋ manager failures. 3 managers → tolerate 1. 5 managers → tolerate 2. Recommendation: 3 managers for most production clusters, 5 for high availability.

Initializing and Joining

# Initialize Swarm on the first manager
docker swarm init --advertise-addr 192.168.1.10

# Get join tokens
docker swarm join-token worker
docker swarm join-token manager

# Join as worker (run on worker node)
docker swarm join --token SWMTKN-1-xxx 192.168.1.10:2377

# List nodes
docker node ls

# Promote worker to manager
docker node promote node2

# Drain a node before maintenance
docker node update --availability drain node3

Services and Replicas

# Create a replicated service
docker service create \
  --name webapp \
  --replicas 3 \
  --publish published=80,target=8080 \
  --mount type=volume,src=appdata,dst=/data \
  myapp:1.0

# Scale a service
docker service scale webapp=5

# Update image with rolling update
docker service update \
  --image myapp:2.0 \
  --update-parallelism 1 \
  --update-delay 10s \
  --update-failure-action rollback \
  webapp

# Inspect service tasks
docker service ps webapp

# Remove a service
docker service rm webapp

Global vs Replicated Services

  • Replicated (default) — run a specified number of tasks spread across the cluster
  • Global — run exactly one task on every node (e.g., monitoring agents, log collectors): docker service create --mode global ...

Secrets and Configs

  • Secrets — sensitive data (passwords, TLS keys) encrypted at rest in Raft and mounted read-only at /run/secrets/<secret_name>
  • Configs — non-sensitive configuration files (nginx.conf) stored in the Raft log and mounted into containers
# Create a secret from stdin
echo "mysecretpassword" | docker secret create db_password -

# Use secret in a service
docker service create \
  --name mydb \
  --secret db_password \
  --env DB_PASSWORD_FILE=/run/secrets/db_password \
  postgres:16

# List secrets
docker secret ls

Ingress (Routing Mesh)

Docker Swarm's routing mesh allows any node in the cluster to accept requests on a published port, even if that node isn't running a service task. Incoming traffic is load-balanced across all healthy replicas using the ingress overlay network and IPVS.

Ingress vs Host mode publishing: Default Swarm port publishing uses the ingress routing mesh. Using mode=host in --publish bypasses the mesh and maps directly to the host port — only the node running the task can receive the traffic. Useful for performance-sensitive services that don't need load balancing.
06 Container Security & Production Best Practices ~5h

Security is 15% of the DCA exam. Master Linux capabilities, content trust, seccomp, namespaces, and image scanning to build a defense-in-depth container security posture.

Linux Kernel Security Mechanisms

  • Namespaces — provide isolation for PID, network, mount, IPC, UTS, and user spaces. Each container gets its own namespace view, preventing process leakage.
  • cgroups — resource limits: --memory 512m --cpus 1.5 prevents a single container from starving the host
  • Capabilities — Docker drops most Linux capabilities by default; containers run with a minimal set. Add: --cap-add NET_ADMIN; Drop: --cap-drop ALL. Never use --privileged in production.
  • seccomp — filters system calls; Docker applies the default seccomp profile which blocks ~44 dangerous syscalls. Custom profiles can be applied with --security-opt seccomp=profile.json.
  • AppArmor / SELinux — mandatory access control frameworks; Docker applies a default AppArmor profile (docker-default) on supported systems
Security hierarchy to remember: namespaces (isolation) → cgroups (resource limits) → capabilities (syscall privilege) → seccomp (syscall filtering) → AppArmor/SELinux (MAC policy). Each layer adds defense-in-depth.

Docker Content Trust (DCT)

DCT uses Notary (TUF — The Update Framework) to cryptographically sign and verify images. When enabled, Docker refuses to pull unsigned images.

# Enable DCT for the current shell session
export DOCKER_CONTENT_TRUST=1

# Sign an image when pushing (requires keys to be set up)
docker push myregistry.com/myapp:1.0

# Inspect image signature
docker trust inspect --pretty myapp:1.0

Running Containers Securely

# Run as non-root user
docker run --user 1000:1000 myapp

# Read-only root filesystem
docker run --read-only myapp

# Drop all capabilities, add only what's needed
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp

# No new privileges (prevents privilege escalation)
docker run --security-opt no-new-privileges myapp

# Resource limits
docker run --memory 512m --cpus 1 myapp

Image Security Best Practices

  • Use official base images from Docker Hub verified publishers
  • Scan images for vulnerabilities with docker scout or Trivy
  • Never run processes as root inside containers (use USER in Dockerfile)
  • Pin image versions with digests rather than mutable tags: nginx@sha256:abc123...
  • Minimize image size to reduce attack surface — use distroless or Alpine base images
  • Do not store secrets in images (use Docker Secrets or environment variables from a secrets manager)

Registry Security

  • Docker Trusted Registry (DTR) — enterprise registry with RBAC, image scanning, and content trust
  • Use TLS for all registry communication
  • Configure image access control: who can push to which namespace
  • Regularly rotate registry credentials and image signing keys
Namespace user mapping: User namespace remapping maps root inside the container to an unprivileged UID on the host. Enable with userns-remap in /etc/docker/daemon.json. Even if a container breakout occurs, the attacker gets an unprivileged shell on the host. High-security environments should enable this.

Ready to test your Docker knowledge?

Take the 60-question DCA practice exam — Swarm, security, networking, and images. Free, no signup, instant scoring with explanations.

← All study courses