Docker logo

Cloud & DevOps

Official site

Docker

Docker — containerising applications and services for reproducible environments, portability, and smooth local-to-production parity.

Overview

Docker gives me a repeatable path from laptop to production: the same image runs in development, CI, and on the server. I write multi-stage builds that stay fast and small, and keep images immutable and versioned like any artifact.

Compose is my default for local and single-host environments — services, networks, volumes, and health checks declared as code. For multi-container architecture I hold an image hygiene standard: minimal bases, non-root users, pinned tags, and layers that cache well.

At the orchestration layer Docker is the foundation under both Kubernetes and Kamal. A well-built image makes everything above it simpler, so image design is where the discipline starts.

The Dockerfile is treated as deliverable code. Multi-stage builds separate the build environment from the runtime, so I do not ship compilers and package managers into production — only the artefacts the application actually needs.

Small images are a security and a performance win. A minimal base, only the needed files, and a non-root user reduce both the attack surface and the pull time across every environment and every deploy.

Layer order and caching are engineered deliberately. Dependencies that rarely change go early so they cache, and volatile application code goes late — which keeps rebuilds fast for developers and builds incremental in CI.

Pinned tags make history reproducible. I reference exact image digests or versions rather than floating `latest`, so the image that is verified today is the one that runs in production tomorrow.

Local and remote must agree. Compose defines the multi-container topology as code — services, networks, volumes, and health checks — so what works on a laptop is the same shape that deploys, collapsing the classic "works here" gap.

Docker does not replace orchestration; it feeds it. The disciplined image I build is what Kubernetes schedules and what Kamal deploys, so the care I put at the image boundary pays off across the whole delivery stack.

How I Work With Docker

The Dockerfile is deliverable code. Multi-stage builds separate the build environment from the runtime, so I ship only the artefacts the application needs — not compilers or package managers.

Images stay small and secure. A minimal base, only the needed files, and a non-root user reduce the attack surface and keep pulls fast.

Layer order is engineered for caching. Rarely-changing dependencies go early so they cache; volatile application code goes late, keeping rebuilds fast and CI incremental.

Tags are pinned, never floating. I reference exact versions or digests rather than `latest`, so the image verified today is the one that runs tomorrow.

Compose defines the topology as code. Services, networks, volumes, and health checks are declared, so local, CI, and single-host match the deployment shape.

Health checks gate readiness. A container only reports healthy when its service is actually ready, which keeps orchestration from routing traffic to a half-booted image.

I avoid baking secrets into images. Config and credentials come from env or the secrets store at run time, so the artifact stays safe to share and promote.

The image is the boundary between concern. It is what Kubernetes schedules and what Kamal deploys, so the care at the image edge pays off across the whole delivery stack.

Local and remote must agree. A reproducible image collapses the classic "works on my machine" gap into a single, versioned artifact.

Key Capabilities

Multi-stage Dockerfiles tuned for size, speed, and cache reuse.
Compose for local and single-host multi-service environments.
Minimal bases, non-root execution, and pinned, reproducible tags.
Immutable, versioned images moving through CI to production.
Foundation under Kubernetes and Kamal orchestration.