Docker for long-life services
Docker is no longer interesting technology. That's the point. It's stable enough, supported enough, and understood enough that you can put a 10-year-old container in a 2026 production environment and have a reasonable expectation it will run.
That kind of dependability is undervalued by anyone shipping a startup web app and overwhelmingly valued by anyone running a regulator. Here's how we use Docker for systems that have to last.
Pinned everything
Every base image is pinned to an explicit version, not :latest. Every dependency is pinned to a specific version, with hashes where possible. Every build is reproducible: given the same Dockerfile and lockfile in 2030, you get a functionally identical image to 2026.
This sounds obvious. Inspect any production Dockerfile in the wild and most of them violate this principle. "FROM python:3" today, breaks in 2030 when 3 means 3.15 and your code was written for 3.11.
Multi-stage builds keep the surface small
Build stages have your compilers and dev tools. The final image has only what runs in production. This isn't just about image size; it's about attack surface. Every binary in the production image is a binary you've signed up to keep patched.
Don't run as root
Container's userspace runs as root by default. Five minutes of Dockerfile work fixes that. Worth doing every time.
Externalise everything stateful
The container is ephemeral. Databases, file uploads, secrets, logs all live outside it. Replacing a container means pulling the new image; no data migration. Restoring after an outage means starting the same image elsewhere; no rebuild.
The discipline this enforces — separating what changes (config, data, secrets) from what doesn't (code, dependencies) — is half of operational reliability.
Image scanning in CI
Every image we publish runs through a vulnerability scanner (Trivy, Snyk, Grype) on build. Findings are tracked and prioritised. We don't fail builds on every CVE — most are noise — but we do not deploy untriaged.
Where we don't use Docker
Single-process workloads where the container adds nothing — small Python scripts, scheduled jobs that complete in seconds, one-shot data migrations. Containers add a deployment pipeline; sometimes that's overhead the work doesn't need.
Embedded targets where the kernel is the kernel and the rootfs is the rootfs. Different world.
The boring conclusion
Docker isn't the right answer because it's exciting. It's the right answer because in 2026 it's the substrate, and the substrate works. Our oldest Docker-based production deployments are now 8 years in service. That's the bar; everything we run on it is judged against it.