Docker Containers & Compose
Beginner-to-advanced Docker reference covering images, containers, Dockerfiles, BuildKit, cache, lifecycle, storage, networking, Compose, registries, multi-platform builds, security, diagnostics, and production practices.
Images, Containers & Lifecycle
Distinguish immutable image content from runtime process and writable state.
Image, Container & Registry Mental Model
An image is a content-addressed layer/config template; a container is an isolated process using that image plus runtime configuration and a writable layer; a registry distributes images.
A container's writable layer disappears with removal. Persist application data in volumes or external services and design processes to restart safely.
run, create, start, stop & remove
run creates and starts; create separates configuration from start; stop sends the configured stop signal then kills after timeout; rm deletes stopped containers.
Use exec-form ENTRYPOINT/CMD so the application receives SIGTERM. Avoid shell wrappers that fail to exec or reap children; use --init when a tiny init is appropriate.
inspect, exec, logs & stats
Inspect declared/runtime state, execute short diagnostics in a running container, stream logs, and observe resource usage.
exec changes are unrepeatable and disappear after replacement. Diagnose, then fix the image/configuration and redeploy; never treat a running container like a hand-maintained VM.
Dockerfiles & BuildKit
Build reproducible minimal images with intentional cache and secret boundaries.
FROM, WORKDIR, COPY, RUN, USER & CMD
Each instruction contributes config or a filesystem layer. Use a pinned, maintained base; stable workdir; narrow COPY; non-root runtime; and one foreground process.
It does not publish a host port. Use docker run -p or Compose ports; bind the application to 0.0.0.0 inside the container when it must accept external traffic.
Layer Cache & .dockerignore
Build cache reuses an instruction when its inputs match; once invalidated, following steps rebuild. Copy dependency manifests before frequently changing source.
Exclude secrets, VCS history, dependencies, and irrelevant artifacts. COPY . . can leak files into layers even if later deleted.
Multi-Stage Builds, Secrets & Cache Mounts
Build in a tool-rich stage and copy only runtime artifacts. BuildKit mounts provide temporary cache, secret, SSH, bind, or tmpfs data without committing it to layers.
They can appear in metadata, history, cache, logs, or final config. Use secret mounts during build and runtime secret injection outside the image.
Storage & Networking
Choose explicit persistence, sharing, and connectivity contracts.
Volumes, Bind Mounts & tmpfs
Named volumes are Docker-managed persistent data; bind mounts expose host paths; tmpfs keeps temporary data in memory.
| Mount Type | Data Location | Persists | Best For | Main Risk |
|---|---|---|---|---|
| Named volume | Docker-managed host storage | After container removal | Databases and application data | Must be backed up and lifecycle-managed separately |
| Bind mount | Explicit host path | As long as host files exist | Source code, local config, host integration | Host coupling and accidental file exposure |
| tmpfs | Host memory | No | Secrets or high-churn temporary data | Consumes memory and vanishes on stop |
| Container writable layer | Container storage driver | Only until container removal | Disposable runtime changes | Poor choice for important or high-write data |
Mounting over a non-empty container directory hides image files. Define ownership/UID, backup/restore, migration, and removal policy for named volumes.
Networks, DNS & Port Publishing
User-defined bridge networks provide service-name DNS and isolation. Container ports are internal; published ports bind host interfaces.
Use the other container's DNS/service name. Bind published development ports to 127.0.0.1 unless LAN exposure is intended.
Resource Limits, Health & Restart
Set memory/CPU/process limits, application-aware health checks, stop grace, and restart policy according to workload behavior.
A crash loop can amplify dependency load and hide corruption. Emit diagnostics, use backoff/orchestration, make startup idempotent, and distinguish alive from ready.
Docker Compose
Define a trusted multi-container application with reproducible service, network, volume, and dependency configuration.
Services, Networks, Volumes & Environment
Compose services describe container configuration. Service names are network DNS names; named volumes persist; environment interpolation and container environment are distinct.
Startup ordering/health can reduce races, but services must retry transient dependency loss after startup and shut down safely.
Compose CLI, Profiles & Overrides
Render effective configuration before applying; use profiles for optional tools and layered files carefully for environments.
They can mount host files, request privileges, and expose secrets during interpolation/config rendering. Review remote Compose sources before running them.
Development vs Production Compose
Development may bind source and expose ports; production should use immutable tagged/digest-pinned images, controlled secrets, resource/policy settings, and external observability.
See Kubernetes for reconciliation, replicas, rollout, Services, cluster scheduling, policy, and persistent-volume orchestration.
Registries, Platforms & Supply Chain
Publish immutable, verifiable artifacts for the target architecture.
buildx & Multi-Platform Images
Build a manifest list for target architectures using native builders, cross-compilation, or emulation; test runtime-native dependencies on each platform.
QEMU builds may be slow and do not replace tests on target architecture. Pin platform-specific base images and verify native addons/binaries.
SBOM, Provenance, Signing & Scanning
Generate attestations during build, scan packages/config, sign or verify artifacts using your supply-chain system, and define vulnerability policy with ownership.
New vulnerabilities appear after publication. Continuously rescan deployed digests and maintain a rebuild/patch cadence.
Container Security & Hardening
Minimize privileges, writable surface, secrets, attack tools, and daemon trust.
Non-Root, Capabilities & Read-Only Filesystem
Set a numeric non-root user, drop capabilities, avoid privileged mode/host namespaces/socket mounts, and make root filesystem read-only with explicit writable mounts.
Mounting /var/run/docker.sock generally grants control equivalent to root on the host. Use purpose-built restricted APIs/builders instead.
Minimal Images & Runtime Secrets
Ship only runtime files and libraries, omit shells/package managers when feasible, and mount/inject secrets at runtime with rotation and access controls.
Minimal images reduce surface but still need provenance, updates, compatible libraries, and usable diagnostics. Choose maintained bases and test operational needs.
Daemon, Desktop & Host Boundary
Anyone controlling the Docker daemon can usually control the host. Protect its API, groups, contexts, credentials, and build agents.
Containers share the host kernel. Use stronger sandbox/VM isolation for hostile multi-tenancy and enforce kernel, runtime, and orchestration security controls.
Diagnostics, Cleanup & Checklist
Debug layer-by-layer and remove only resolved, explicitly targeted resources.
Build & Runtime Troubleshooting
Inspect effective build stages, history, image config, mounts, networks, DNS, logs, health, and process signals.
Use an ephemeral debug image/container joined to the same network/volumes when the production image intentionally lacks a shell.
Disk Usage & Safe Cleanup
Measure images, layers, containers, volumes, and build cache before pruning; unused volumes may contain the only copy of data.
Confirm ownership, backup, and restore before docker volume rm, compose down -v, or volume prune. Prune commands are not routine harmless cleanup.
Production Checklist
Review reproducibility, runtime ownership, persistence, exposure, supply chain, privilege, and operations.