Docker For Intermediate
The concepts that separate "I can run a container" from "I can build, secure, and operate containers responsibly" — for readers already comfortable with Docker basics.
This guide assumes you already know what images, containers, Dockerfiles, and basic Compose files are. It moves into the concepts that actually matter once you’re building images for a real team, running containers that need to stay healthy, and thinking about security and production readiness — still explained concisely, without going into full expert-level internals.
1Advanced Image Building & Optimization
Writing Dockerfiles that produce smaller, faster, more cacheable images.
Multi-Stage Builds
Uses multiple FROM statements in one Dockerfile so build tools and dependencies stay in an early stage, while only the final compiled output is copied into a slim final image.
.dockerignore
Excludes files (like node_modules or .git) from being sent to the build context, speeding up builds and avoiding accidentally baked-in files.
Build Cache Optimization
Ordering Dockerfile instructions so rarely-changing steps (like installing dependencies) come before frequently-changing steps (like copying source code) to maximize cache reuse.
ARG vs ENV
ARG defines build-time-only variables passed during docker build; ENV defines variables that persist into the running container.
Image Layer Optimization
Combining related commands into fewer RUN instructions and cleaning up temporary files in the same layer to avoid bloating the final image size.
Minimal Base Images (Alpine, Distroless)
Using smaller base images to reduce image size and attack surface, trading some compatibility and debugging convenience for efficiency and security.
2Docker Networking In Depth
Going beyond the default bridge network into how containers really communicate.
User-Defined Bridge Networks
Custom networks you create yourself, offering automatic DNS resolution between containers by name — something the default bridge network doesn’t provide.
Overlay Networks
Networks that span multiple Docker hosts, allowing containers on different physical machines to communicate as if on the same network — foundational for Swarm and multi-host setups.
Macvlan Networks
Assigns a container its own MAC address, making it appear as a physical device directly on the network, useful for legacy applications expecting direct network presence.
DNS Resolution Between Containers
On user-defined networks, Docker automatically resolves container names to their internal IP addresses, removing the need to hardcode IPs.
Network Aliases
Additional names a container can be reached by on a network, useful when migrating services or supporting multiple naming conventions.
3Storage, Volumes & Data Management
Managing state more deliberately than a beginner setup requires.
Volume Drivers
Plugins that let Docker volumes be backed by different storage backends, such as cloud block storage or network file systems, instead of just local disk.
tmpfs Mounts
Stores data directly in the host’s memory rather than on disk, useful for sensitive temporary data that shouldn’t persist anywhere.
Backup and Restore Volumes
Common patterns involve running a temporary container that mounts the volume and archives its contents to a tarball for safekeeping or migration.
Storage Drivers (overlay2, etc.)
The underlying mechanism Docker uses to manage image layers on disk; overlay2 is the modern default on most Linux systems, replacing older, less efficient drivers.
4Docker Compose — Intermediate Features
Moving past a single, simple docker-compose.yml file.
Multiple Compose Files (Override)
Layering a base docker-compose.yml with environment-specific override files (like docker-compose.override.yml) to avoid duplicating configuration across environments.
Environment Variables in Compose
Injecting values from a .env file or the shell into service definitions, keeping environment-specific settings out of the main configuration file.
depends_on and Service Dependencies
Controls the startup order of services, though it only waits for a container to start — not necessarily for the application inside it to be actually ready.
Compose Profiles
Lets you selectively enable groups of services (like optional debugging tools) without always starting every service defined in the file.
Healthchecks in Compose
Defines how Compose should verify a service is actually ready, which can be combined with depends_on conditions for more reliable startup ordering.
5Container Resource Management & Health
Making sure containers behave well under real load, not just on a laptop.
CPU and Memory Limits
Setting hard caps on how much CPU and memory a container can consume, preventing one misbehaving container from starving others on the same host.
Restart Policies (In Depth)
Options like on-failure, always, and unless-stopped control exactly when Docker should automatically restart a container after it exits.
HEALTHCHECK Instruction
Defined inside a Dockerfile, this tells Docker how to periodically check if the application inside a container is actually functioning, not just running.
Logging Drivers
Configurable backends (json-file, syslog, journald, and others) that determine where and how a container’s log output is captured and stored.
6Security Fundamentals for Containers
Baseline practices every intermediate Docker user should apply.
Running Containers as Non-Root
Specifying a non-root user in the Dockerfile so a compromised container process has fewer privileges to exploit on the host.
Docker Content Trust
A signing mechanism that verifies an image hasn’t been tampered with since it was published, helping prevent supply-chain attacks.
Scanning Images for Vulnerabilities
Using tools (like Docker Scout, Trivy, or Snyk) to check an image’s packages against known vulnerability databases before deploying it.
Secrets Management
Avoiding hardcoded passwords or API keys in images or environment variables in favor of dedicated secrets mechanisms.
Read-Only Filesystems
Running a container with its filesystem set to read-only, reducing the damage an attacker can do even if they gain code execution inside it.
7Environment Variables, Secrets & Configuration
Getting configuration into containers the right way for different environments.
Environment Variables
Passed into a container at runtime to configure behavior without rebuilding the image, commonly used for things like database connection strings.
.env Files
A convenient way to define default environment variables for Compose, keeping them out of version-controlled configuration files when they contain sensitive values.
Docker Secrets
A Swarm-native mechanism for securely distributing sensitive values to containers, kept encrypted at rest and only exposed to authorized services.
Config Files in Containers
Mounting configuration files into a container via volumes, letting the same image be reused across environments with different mounted configs.
8Debugging & Troubleshooting Containers
Diagnosing problems beyond just reading the logs.
docker inspect
Returns detailed low-level information (configuration, network settings, mounted volumes) about a container or image in JSON format.
docker stats
Shows a live, continuously updating view of CPU, memory, and network usage for running containers.
Attaching to a Running Container
Opening an interactive shell session inside an already-running container to investigate its state directly.
Debugging Failed Builds
Building up to the last successful layer and starting a container from it manually is a common technique for figuring out exactly where and why a build failed.
Container Exit Codes
Numeric codes returned when a container stops, where specific values (like 137 for out-of-memory kills) hint at the underlying cause of failure.
9Logging & Monitoring
Keeping visibility into containers once they’re no longer running on your own laptop.
Centralized Logging
Forwarding container logs to an external system (like the ELK stack or a cloud logging service) instead of relying on local log files that disappear with the container.
Structured Logging
Writing application logs in a consistent, machine-readable format (like JSON) to make them easier to search and analyze centrally.
Monitoring Container Metrics
Tools like cAdvisor or Prometheus exporters collect ongoing resource usage data from containers for dashboards and alerting.
Correlating Logs Across Services
Using a shared identifier (like a request ID) across multiple containers’ logs to trace a single request as it moves through a multi-container application.
10CI/CD Integration & Tagging Strategies
Making Docker part of an automated, repeatable delivery pipeline.
Docker in CI/CD Pipelines
Automatically building, testing, and pushing images as part of a pipeline triggered by code changes, rather than building images manually.
Automated Image Builds
Registries or CI tools that automatically rebuild an image whenever its source repository or base image changes.
Tagging Strategies (Semantic Versioning)
Using consistent, meaningful tags (like v1.2.0 alongside latest) so specific image versions can be tracked, rolled back, and referenced reliably.
Image Registries in Automation
Pipelines typically push built images to a registry and then reference that exact tag in deployment configuration, ensuring consistency between build and deploy stages.
11Introduction to Container Orchestration
What happens once a single Docker host isn’t enough.
What Is Container Orchestration?
Automatically managing container deployment, scaling, networking, and recovery across many machines, rather than manually running containers on a single host.
Docker Swarm Basics
Docker’s own built-in orchestration tool, letting you turn multiple Docker hosts into a single cluster (a “swarm”) that schedules containers automatically.
Services vs Containers in Swarm
In Swarm, you define a “service” (a desired state, like “run 3 copies of this image”) rather than starting individual containers by hand.
Introduction to Kubernetes (Compared)
Kubernetes is a more powerful, more complex orchestration platform than Swarm, and has become the industry standard for running containers at scale in production.
12Production Best Practices
Habits that separate a “works on my machine” setup from one ready for real users.
Immutable Infrastructure
Treating containers as disposable and unchangeable once deployed — instead of patching a running container, you build and deploy a new image.
Container Health Monitoring in Production
Combining health checks, restart policies, and external monitoring so unhealthy containers are detected and replaced automatically, not manually.
Zero-Downtime Deployments
Rolling out new container versions gradually while keeping old ones running until the new ones are confirmed healthy, avoiding a hard cutover that drops traffic.
Version Pinning
Avoiding the latest tag in production in favor of specific, immutable version tags, so deployments are predictable and reproducible.
Key Takeaways
- Multi-stage builds and careful layer ordering are the two highest-leverage habits for smaller, faster-building images.
- User-defined networks, not the default bridge, should be the norm — they provide automatic DNS resolution between containers by name.
- Security at this level means non-root users, image scanning, and proper secrets handling — not exotic tooling, just consistent basics.
- Health checks and restart policies together are what actually make a container “self-healing” — neither alone is enough.
- Once you’re managing more than one host, orchestration (Swarm or Kubernetes) becomes necessary rather than optional.
- Production readiness is mostly about discipline — pinned versions, immutable deployments, and centralized logging — more than advanced features.