Introduction to Docker
Docker is an open-source platform for building, shipping, and running applications inside containers — lightweight, isolated, portable units that bundle your app together with everything it needs to run (code, runtime, libraries, config). The promise: "build once, run anywhere."
The Problem It Solves
"It works on my machine" — an app runs in development but breaks in production because of different OS versions, missing libraries, or config drift. Docker eliminates this by packaging the app and its entire environment into a single image that runs identically everywhere.
Key Benefits
- Consistency — same environment from laptop to production.
- Isolation — each container is sandboxed; dependencies don't clash.
- Lightweight — containers share the host kernel, so they start in milliseconds and use far less than a VM.
- Portability — runs on any machine with a container runtime (laptop, server, cloud).
- Scalability — spin up many identical containers behind a load balancer.
Core Vocabulary
| Term | Meaning |
|---|---|
| Image | A read-only template (blueprint) used to create containers |
| Container | A running instance of an image |
| Dockerfile | A script of instructions to build an image |
| Registry | A store for images (e.g. Docker Hub) |
| Volume | Persistent storage that outlives a container |
Your First Container
Containers vs Virtual Machines
Both isolate workloads, but at very different layers. A VM virtualizes hardware and runs a full guest OS; a container virtualizes the operating system and shares the host kernel.
Side by Side — Visual
Comparison
| Virtual Machine | Container | |
|---|---|---|
| Isolation level | Hardware (full guest OS) | OS process (shared kernel) |
| Size | GBs | MBs |
| Startup | Minutes | Milliseconds–seconds |
| Overhead | High (each runs an OS) | Low |
| Isolation strength | Stronger (separate kernel) | Weaker (shared kernel) |
| Density per host | Tens | Hundreds–thousands |
Docker Architecture
Docker uses a client–server architecture. The Docker CLI (client) talks to the Docker daemon (server) over a REST API; the daemon does the heavy lifting of building, running, and managing containers, pulling images from registries as needed.
The Moving Parts — Visual
Components
Docker Client
The CLI you type into. Sends commands to the daemon via the REST API (local socket or remote).
Docker Daemon (dockerd)
The background service that builds images, runs containers, and manages networks/volumes.
Images & Containers
The daemon stores images and runs them as containers on the host.
Registry
Remote store of images. The daemon pulls images you don't have and can push your own.
Under the Hood
The daemon delegates to containerd (high-level runtime) which uses runc (low-level runtime) to actually create containers using Linux namespaces (isolation) and cgroups (resource limits).
docker run, the client just sends an API request — all the real work (pull image, create namespaces, start process) happens in the daemon.Docker Engine
Docker Engine is the core product — the client-server application that creates and runs containers. It is what you install on a machine to "have Docker."
Three Parts
- Docker Daemon (dockerd) — long-running server process managing Docker objects.
- REST API — the interface programs use to talk to the daemon.
- Docker CLI (docker) — the command-line client that calls the API.
Editions
| Edition | For |
|---|---|
| Docker Engine (CE) | The free open-source engine — typically on Linux servers |
| Docker Desktop | Mac/Windows GUI bundling the engine in a lightweight VM + extras (Compose, Kubernetes) |
Checking It
Docker Images
A Docker image is a read-only template that contains everything needed to run an application — filesystem, dependencies, and metadata (default command, env, exposed ports). Containers are running instances of images.
Image Naming
Format: [registry/]repository[:tag] — e.g. docker.io/library/nginx:1.27. If no tag is given, Docker assumes :latest.
Working with Images
Images Are Immutable
You never edit an image — you build a new one. Each image is identified by a content digest (sha256:...), guaranteeing the exact same bytes everywhere.
nginx:1.27, not nginx:latest). latest is just a default tag, not "the newest" — relying on it makes builds non-reproducible.Docker Image Layers
Images are built in layers — each instruction in a Dockerfile creates a new read-only layer stacked on the previous one. Layers are cached and shared between images, which makes builds fast and storage efficient.
Layered Filesystem — Visual
How Layers Help
- Build cache — unchanged layers are reused; only changed layers and those after them rebuild.
- Storage sharing — ten images on the same base share that base layer once on disk.
- Faster pulls — only missing layers are downloaded.
- The running container adds a thin writable layer on top (copy-on-write).
Inspecting Layers
COPY pom.xml + dependency download before COPY src — your dependency layer stays cached across code changes.Docker Hub
Docker Hub is the default public registry — a cloud library of images. It hosts official images (nginx, postgres, node, eclipse-temurin), verified publisher images, and personal/team repositories.
Common Operations
Image Trust Tiers
| Tier | Meaning |
|---|---|
| Official Images | Curated by Docker (e.g. nginx, postgres) — best starting point |
| Verified Publisher | From trusted vendors |
| Community | Anyone — vet before using in production |
toomanyrequests errors.Docker Registry
A registry is a storage and distribution system for Docker images, organized into repositories (each holding tagged versions of an image). Docker Hub is the best-known public registry; many others exist.
Registry vs Repository vs Tag
- Registry — the server hosting images (Docker Hub, ECR, GHCR).
- Repository — a named collection of related images (
yourusername/myapp). - Tag — a specific version within a repo (
:1.0,:latest).
Popular Registries
| Registry | Provider |
|---|---|
| Docker Hub | Docker (default public) |
| Amazon ECR | AWS |
| GitHub Container Registry (GHCR) | GitHub |
| Google Artifact Registry | GCP |
| Azure Container Registry (ACR) | Azure |
123.dkr.ecr.us-east-1.amazonaws.com/myapp for ECR).Private Docker Registries
A private registry stores images that shouldn't be public — proprietary apps, internal base images. You can run your own or use a managed cloud registry.
Run Your Own Registry
Production Considerations
- TLS — registries must use HTTPS (or be configured as an insecure registry — avoid in prod).
- Authentication — token/basic auth; integrate with SSO for teams.
- Storage backend — back it with S3/GCS for durability.
- Managed options — ECR, GHCR, ACR, Harbor (adds scanning, RBAC, replication).
Docker Containers
A container is a running (or stopped) instance of an image — an isolated process with its own filesystem, network, and resource limits, sharing the host kernel. You can run many containers from the same image.
Running Containers
Key Run Flags
| Flag | Purpose |
|---|---|
-d | Detached (run in background) |
-it | Interactive + TTY (shell access) |
-p host:container | Publish a port |
-e KEY=val | Set an environment variable |
-v vol:/path | Mount a volume |
--name | Give the container a name |
--rm | Auto-remove when it exits |
docker run ubuntu exits immediately — bash with no TTY has nothing to do.Container Lifecycle
A container moves through well-defined states. Understanding them is key to debugging "why did my container exit?"
State Machine — Visual
Commands by Transition
| Command | Transition |
|---|---|
docker create | → Created (not started) |
docker start / run | → Running |
docker pause / unpause | Running ↔ Paused |
docker stop (SIGTERM→SIGKILL) | Running → Stopped (graceful) |
docker kill (SIGKILL) | Running → Stopped (forced) |
docker rm | Stopped → Removed |
docker stop sends SIGTERM, waits (default 10s), then SIGKILL — so your app can shut down gracefully. docker kill skips straight to SIGKILL. Handle SIGTERM in your app to finish in-flight work.Docker Restart Policies
Restart policies tell Docker how to react when a container exits or the daemon restarts — essential for keeping services running without an external orchestrator.
The Four Policies
| Policy | Behavior |
|---|---|
no | Never restart (default) |
on-failure[:max] | Restart only on non-zero exit, optionally capped |
always | Always restart; also starts on daemon boot |
unless-stopped | Like always, but not if you manually stopped it |
Usage
unless-stopped is the pragmatic default for long-running services. In Kubernetes/Swarm the orchestrator handles restarts instead, so policies matter less there.Dockerfile
A Dockerfile is a text file of instructions that Docker reads to build an image automatically and reproducibly. Each instruction adds a layer.
Core Instructions
| Instruction | Purpose |
|---|---|
FROM | Base image to start from |
WORKDIR | Set the working directory |
COPY / ADD | Copy files into the image |
RUN | Execute a command at build time (creates a layer) |
ENV | Set environment variables |
EXPOSE | Document the listening port |
ENTRYPOINT | The fixed executable to run |
CMD | Default args / command (overridable) |
Example — Spring Boot
ENTRYPOINT vs CMD
- ENTRYPOINT — the executable that always runs.
- CMD — default arguments, easily overridden at
docker run. - Common combo:
ENTRYPOINT ["java","-jar","app.jar"]+CMD ["--spring.profiles.active=prod"].
COPY over ADD (ADD has surprising behavior with URLs/tar extraction). Use the exec form ["cmd","arg"] not shell form — it handles signals correctly so SIGTERM reaches your app.Docker Build Process
docker build reads the Dockerfile, sends the build context (the directory) to the daemon, and executes each instruction, caching layers along the way.
Build Flow — Visual
Commands
The .dockerignore File
Like .gitignore — exclude files from the build context (target/, .git, node_modules) to speed up builds and shrink images.
.dockerignore is the easiest build speedup.Multi-Stage Builds
A multi-stage build uses multiple FROM statements. You build the app in a heavy "builder" stage (with the full JDK/Maven), then copy only the final artifact into a slim runtime stage — leaving build tools behind. Result: dramatically smaller, more secure images.
Two Stages — Visual
Example
Docker Image Optimisation
Smaller images pull faster, deploy faster, and have a smaller attack surface. Several techniques compound.
Techniques
- Slim/distroless base —
eclipse-temurin:21-jreover:21(JDK);alpineor distroless for minimal footprint. - Multi-stage builds — leave build tools behind.
- Layer ordering — copy dependencies before source so the dep layer caches.
- Combine RUN steps — chain with
&&and clean up in the same layer (rm -rf /var/lib/apt/lists/*). - .dockerignore — keep junk out of the context.
- Specific tags — reproducible and cacheable.
Cleaning in One Layer
Measure It
Docker Best Practices
Battle-tested rules for building production-grade images and containers.
✓ Do
- Use official, minimal, pinned base images
- Use multi-stage builds
- One process / concern per container
- Run as a non-root user
- Externalize config via env vars
- Add a
HEALTHCHECK - Use
.dockerignore+ good layer order - Handle SIGTERM for graceful shutdown
✗ Avoid
:latestin production- Running as root
- Storing secrets in the image/ENV in the Dockerfile
- Multiple services in one container
- Storing persistent data inside the container
- Huge build contexts
- Installing unnecessary packages
Run as Non-Root
Docker CLI Commands
The docker CLI is your main interface. Here's the everyday toolkit grouped by what you're working with.
Images
Containers
System & Cleanup
docker container ls, docker image ls, docker volume ls. The short forms (docker ps, docker images) are aliases.Docker Logs
Docker captures whatever a container writes to stdout/stderr and exposes it via docker logs. This is why 12-factor apps log to stdout rather than files.
Commands
Logging Drivers
By default Docker uses the json-file driver. For production, ship logs centrally with drivers like journald, fluentd, awslogs, or gelf.
json-file driver grows unbounded — a chatty container can fill the host disk. Always set max-size/max-file or use a centralized driver in production.Docker Exec
docker exec runs a new command inside a running container — the primary way to debug a live container (open a shell, inspect files, check processes).
Usage
exec runs in an already-running container; run starts a new one. If a container has already exited you can't exec into it — check docker logs instead, or start it with an overridden command.Docker Inspect
docker inspect returns detailed low-level JSON metadata about any Docker object — containers, images, networks, volumes. Indispensable for debugging configuration.
Usage
What You Can Find
- State (running, exit code, start/finish time, restart count)
- Network settings (IP, ports, networks)
- Mounts (volumes, bind mounts)
- Config (env vars, entrypoint, command, labels)
docker inspect -f '{{.State.ExitCode}}' <c> tells you why a container died — exit code 137 = SIGKILL (often OOM), 143 = SIGTERM, 1 = app error.Docker Stats
docker stats streams live resource usage per container — CPU, memory, network, and disk I/O — a quick way to spot a runaway container.
Usage
What to Watch
| Metric | Watch for |
|---|---|
| CPU % | Sustained 100% → CPU-bound or a loop |
| MEM USAGE / LIMIT | Near the limit → risk of OOM kill (137) |
| NET I/O | Unexpected spikes |
| BLOCK I/O | Heavy disk reads/writes |
docker stats is great for ad-hoc checks but isn't historical. For trends and alerts, use cAdvisor + Prometheus + Grafana (see Container Monitoring).Docker Health Checks
A HEALTHCHECK tells Docker how to test that a container is actually working — not just running. Orchestrators use health status to restart or stop routing traffic to unhealthy containers.
In a Dockerfile
Parameters
| Option | Meaning |
|---|---|
--interval | Time between checks |
--timeout | Max time a check may take |
--retries | Consecutive failures → unhealthy |
--start-period | Grace window during slow startup |
States & Checking
A container is starting → healthy or unhealthy.
/actuator/health (enable spring-boot-starter-actuator). Use --start-period generously — JVM apps take seconds to warm up and you don't want false "unhealthy" flaps at boot.Docker Volumes
Containers are ephemeral — when removed, their writable layer is gone. Volumes provide persistent storage that lives independently of containers, so data (databases, uploads) survives container restarts and replacements.
Three Storage Options — Visual
Working with Named Volumes
Volumes vs Bind Mounts vs tmpfs
| Type | Stored | Use for |
|---|---|---|
| Named Volume | Docker-managed area | Databases, app data (production) |
| Bind Mount | Any host path | Local dev (live code), config files |
| tmpfs | Host RAM | Secrets/scratch, never persisted |
Bind Mounts
A bind mount maps a specific host directory or file directly into a container. Changes on either side are instantly visible on the other — perfect for development.
Usage
Pros & Cons
✓ Good for
- Live code editing in dev
- Injecting host config files
- Sharing build output
✗ Watch out
- Ties container to host paths (not portable)
- Permission/ownership mismatches
- Security: container can touch host files
:ro suffix mounts read-only — use it for config and secrets so a compromised container can't modify host files.Named Volumes
Named volumes are persistent storage fully managed by Docker (under /var/lib/docker/volumes). You refer to them by name, not by host path — making them portable and the recommended choice for stateful data.
Lifecycle
Backing Up a Volume
docker rm of the container — that's the point. They're only deleted when you explicitly docker volume rm them (or docker run --rm -v with anonymous volumes).Docker Storage Drivers
Storage drivers control how Docker stacks and manages image layers and the container's writable layer on disk, using a copy-on-write (CoW) strategy.
Common Drivers
| Driver | Notes |
|---|---|
overlay2 | Default & recommended on modern Linux — efficient, stable |
fuse-overlayfs | For rootless Docker |
btrfs / zfs | Used when the host filesystem is btrfs/zfs |
devicemapper (legacy) | Older systems — avoid for new setups |
Copy-on-Write
Image layers are read-only and shared. When a container modifies a file, the driver copies it up into the container's writable layer first — so the underlying image stays intact and is shared across containers.
overlay2 is the right default almost everywhere. Knowing CoW matters because heavy writes to the container layer are slower than writing to a volume — another reason databases belong on volumes.Docker Networking
Docker networking lets containers talk to each other, to the host, and to the outside world. Docker creates virtual networks and connects containers to them; containers on the same user-defined network can reach each other by name via built-in DNS.
Network Types — Visual
Built-in Network Types
| Type | Use |
|---|---|
| bridge | Default — isolated network on a single host |
| host | Container shares the host's network (no isolation) |
| none | No networking |
| overlay | Multi-host networking (Swarm/Kubernetes) |
| macvlan | Container gets its own MAC/IP on the physical network |
Commands
Bridge Network
The bridge is the default network driver. Docker creates a private internal network on the host (docker0); containers attached to it get an internal IP and communicate through the bridge, isolated from the host's other networks.
Default vs User-Defined Bridge
Default bridge | User-defined bridge | |
|---|---|---|
| DNS by name | No (IP only / legacy --link) | Yes (container names resolve) |
| Isolation | Shared by all default containers | Scoped to attached containers |
| Recommended | No | Yes |
Example
redis:6379) — no need to publish ports to the host for internal traffic. Only publish (-p) what the outside world needs.Host Network
With --network host, the container shares the host's network stack directly — no isolation, no NAT, no port mapping. The container's ports are the host's ports.
Usage
Trade-offs
✓ Pros
- Best network performance (no NAT overhead)
- Useful for high-throughput / many-ports apps
✗ Cons
- No network isolation
- Port conflicts with the host
- Linux-only (behaves differently on Docker Desktop)
Overlay Network
An overlay network connects containers running on different Docker hosts as if they were on one network. It's the foundation of multi-host orchestration (Docker Swarm), encapsulating traffic (VXLAN) across the physical network.
How It Works
- Spans multiple Docker daemons in a Swarm cluster.
- Containers/services on the same overlay communicate by name across hosts.
- Traffic is encapsulated and optionally encrypted.
Creating One (Swarm)
Port Mapping
By default a container's ports are only reachable inside its network. Port mapping (publishing) exposes a container port on the host so the outside world can reach it.
Syntax: -p host:container
EXPOSE vs -p
EXPOSEin a Dockerfile is documentation — it doesn't publish anything.-pat runtime actually publishes the port to the host.
127.0.0.1: (e.g. -p 127.0.0.1:5432:5432) so they're reachable locally for debugging but not exposed to the whole network/internet.Environment Variables
Environment variables are the standard way to configure containers without rebuilding the image — the 12-factor "config in the environment" principle.
Setting Them
In Dockerfile vs Runtime
ENVin the Dockerfile = build-time defaults baked into the image.-e/--env-fileat runtime = override per environment (dev/staging/prod).
ENV — they're visible in docker history and to anyone who pulls the image. Inject secrets at runtime (env-file, Docker/K8s secrets) — see Secrets Management.Docker Network Drivers
A network driver is the plugin that implements a network type. Docker ships several built-in drivers and supports third-party plugins for advanced setups.
| Driver | Scope | Use case |
|---|---|---|
bridge | Single host | Default app networking |
host | Single host | Max performance, no isolation |
none | Single host | Fully disable networking |
overlay | Multi-host | Swarm services across nodes |
macvlan | Single host | Container appears as a physical device on the LAN |
ipvlan | Single host | Like macvlan, shares MAC; L2/L3 modes |
Docker Compose
Docker Compose defines and runs multi-container applications with a single YAML file. Instead of many docker run commands, you describe all services, networks, and volumes declaratively and bring them up together.
Example: Spring Boot + Postgres
Commands
db, app). depends_on + condition: service_healthy waits for the DB to be ready before the app starts.Multi-Container Applications
Real applications are rarely one container. A typical stack separates concerns into collaborating containers, each independently scalable and replaceable.
A Typical Stack — Visual
Design Principles
- One concern per container — web, app, db, cache, queue separately.
- Communicate over the network by service name, not localhost.
- Stateful services use volumes; stateless app containers can be replaced freely.
- Scale independently —
docker compose up --scale app=3.
Docker Compose vs Kubernetes
Both run multi-container apps, but at different scales. Compose orchestrates containers on one host for simplicity; Kubernetes orchestrates containers across a cluster of hosts with self-healing, scaling, and rolling updates.
Comparison
| Docker Compose | Kubernetes | |
|---|---|---|
| Scope | Single host | Multi-host cluster |
| Complexity | Low — one YAML | High — many resource types |
| Auto-scaling | No | Yes (HPA) |
| Self-healing | Limited (restart) | Yes (reschedules pods) |
| Rolling updates | Basic | Built-in, advanced |
| Best for | Dev, demos, small apps | Production at scale |
Docker Security
Containers share the host kernel, so a misconfigured container is a real risk. Security is layered — image, runtime, and host all matter.
Key Practices
- Run as non-root — use a dedicated
USER; never run app processes as root. - Minimal base images — fewer packages = smaller attack surface (distroless/alpine).
- Drop capabilities —
--cap-drop ALLthen add only what's needed. - Read-only filesystem —
--read-only+ tmpfs for writable paths. - No new privileges —
--security-opt no-new-privileges. - Scan images for vulnerabilities (see Image Scanning).
- Manage secrets outside images (see Secrets Management).
- Keep Docker & base images patched.
Hardened Run Example
Image Scanning
Image scanning detects known vulnerabilities (CVEs) in the OS packages and libraries baked into your image. Run it in CI so vulnerable images never reach production.
Tools
| Tool | Notes |
|---|---|
docker scout | Built into Docker — CVE analysis & recommendations |
| Trivy | Popular open-source scanner |
| Grype | Anchore's scanner |
| Snyk | Commercial, dev-friendly |
| Registry-native | ECR/GHCR/Harbor scan on push |
Usage
Secrets Management
Secrets (passwords, API keys, certs) must never be baked into images or committed to Git. Docker provides mechanisms to inject them at runtime, kept out of the image layers and docker history.
Options (worst → best)
| Method | Verdict |
|---|---|
ENV in Dockerfile | ❌ Baked into image, visible in history |
-e at runtime | ⚠️ OK-ish, visible in inspect/process list |
| Docker/Swarm secrets | ✓ Mounted as files in /run/secrets, encrypted at rest |
| External vault (Vault, AWS Secrets Manager) | ✓✓ Best — rotation, audit, central control |
Docker Swarm Secrets
BuildKit Build Secrets
-e DB_PASSWORD=... leaks into docker inspect and the host process list. For anything sensitive, use file-based secrets or an external secret manager and read at startup.Resource Limits
By default a container can consume all host CPU and memory. Limits (enforced via Linux cgroups) prevent one container from starving others — essential for stability and a "noisy neighbour" defense.
Setting Limits
In Compose
-XX:MaxRAMPercentage=75 respects the cgroup memory limit) — otherwise the JVM may size the heap to the host RAM and get OOM-killed (exit 137).Container Orchestration
Running a few containers by hand is easy; running hundreds across many machines reliably is not. Orchestration automates deployment, scaling, networking, health, and recovery of containers across a cluster.
What Orchestrators Do
- Scheduling — place containers on suitable nodes.
- Scaling — add/remove replicas on demand.
- Self-healing — restart/reschedule failed containers.
- Service discovery & load balancing — route traffic to healthy instances.
- Rolling updates & rollbacks — deploy without downtime.
- Config & secret management.
The Main Options
| Tool | Notes |
|---|---|
| Kubernetes | Industry standard, powerful, complex |
| Docker Swarm | Simple, built into Docker |
| Managed (EKS/GKE/AKS) | Kubernetes run by a cloud provider |
| Nomad | HashiCorp's lightweight scheduler |
Docker Swarm
Docker Swarm is Docker's native, built-in orchestrator. It turns a group of Docker hosts into a single virtual cluster managed with familiar Docker commands — far simpler than Kubernetes, if less powerful.
Concepts
- Node — a Docker host in the swarm (manager or worker).
- Service — the definition of a containerized task (image + replicas).
- Task — a single running container of a service.
- Stack — a multi-service app defined in a compose file.
Usage
Docker & Kubernetes
Kubernetes (K8s) is the dominant container orchestrator. A key clarification: Docker builds images; Kubernetes runs them. They're complementary — you Dockerize your app, then deploy that image to K8s.
How They Relate
- You build images with Docker (or any OCI builder) and push to a registry.
- Kubernetes pulls those images and runs them in Pods.
- K8s dropped the Docker runtime (dockershim) in 1.24, now using containerd/CRI-O — but Docker-built images still run fine (they're OCI-standard).
Core K8s Objects
| Object | Role |
|---|---|
| Pod | Smallest unit — one or more containers |
| Deployment | Manages replica Pods + rolling updates |
| Service | Stable network endpoint + load balancing |
| ConfigMap / Secret | Config & secrets injection |
| Ingress | HTTP routing into the cluster |
Dockerizing Spring Boot Applications
Spring Boot produces a self-contained fat jar, which makes it a natural fit for Docker. There are three common approaches — from simplest to most optimized.
Approach 1 — Simple Dockerfile
Build & run:
Approach 2 — Multi-Stage (build inside Docker)
Approach 3 — Buildpacks (no Dockerfile)
Container-Friendly Config
-XX:MaxRAMPercentage so the JVM heap respects the container memory limit.CI/CD with Docker
Docker makes CI/CD pipelines reproducible: build an image once, scan and test it, then promote that same image through environments to production.
Pipeline Flow — Visual
GitHub Actions Example
latest) so every deploy is traceable and rollbacks are exact. Build once, promote the same artifact — never rebuild per environment.Container Monitoring
Production containers need continuous visibility into resource usage, health, and application metrics — well beyond ad-hoc docker stats.
The Monitoring Stack
| Layer | Tool |
|---|---|
| Container metrics | cAdvisor → Prometheus |
| Host metrics | node-exporter |
| App metrics | Micrometer / Actuator → Prometheus |
| Dashboards | Grafana |
| Logs | Loki / ELK / Fluentd |
| Alerts | Alertmanager |
Spring Boot → Prometheus
Container Troubleshooting
A systematic toolkit for the common "my container won't work" situations.
Diagnostic Commands
Common Issues & Fixes
| Symptom | Likely cause |
|---|---|
| Exits immediately | Main process ended / crashed → check logs |
| Exit code 137 | OOM-killed → raise --memory or fix a leak / JVM heap |
| Exit code 143 | SIGTERM (normal stop) |
| Port not reachable | Missing -p, app bound to 127.0.0.1, wrong port |
| Can't reach other container | Not on the same user-defined network |
| Permission denied on volume | UID mismatch between container user & host files |
| Image too big / slow build | No .dockerignore / no multi-stage |
docker ps -a (state + exit code) → docker logs (why) → docker inspect (config) → docker exec (inside). 90% of issues are revealed by the first two.Docker in Cloud Environments
Every major cloud runs Docker/OCI containers. You typically push images to a managed registry, then run them on a managed compute service — from "serverless containers" to full Kubernetes.
Where to Run Containers
| Cloud | Registry | Run options |
|---|---|---|
| AWS | ECR | ECS, Fargate (serverless), EKS, App Runner |
| GCP | Artifact Registry | Cloud Run (serverless), GKE |
| Azure | ACR | Container Apps, AKS, Container Instances |
Typical Flow (AWS Fargate)
Production Deployment with Docker
A consolidated checklist that ties the whole tutorial together — what "production-ready" actually means for containerized apps.
Production Checklist
Image
Minimal pinned base · multi-stage · non-root · scanned · pinned tags (git SHA).
Config & Secrets
Env-based config · secrets via vault/secret store · nothing sensitive in the image.
Reliability
Health checks · restart/replica policy · graceful shutdown (SIGTERM) · resource limits.
Observability
Logs to stdout (centralized) · Prometheus metrics · alerts · tracing.
Orchestration
Run on K8s/Swarm/managed service · rolling updates · autoscaling.
Pipeline
CI builds + scans + tests · promote one immutable image · automated rollback.
Zero-Downtime Deploys
- Rolling update — replace replicas gradually behind a load balancer (default in K8s/Swarm).
- Blue/green — stand up the new version, switch traffic, keep old for rollback.
- Canary — route a small % to the new version, ramp up if healthy.
- Health checks gate traffic — only ready containers receive requests.