Writing
Docker, and when a small team actually needs it
What Docker and containers are, when a small team actually needs them, when a managed platform makes them redundant, and the honest tradeoffs to weigh.
15 September 2026

TL;DR
- Docker packages an app with everything it needs to run, so the same build behaves the same way on your laptop, a teammate’s machine, CI, and production. That is the whole pitch, and it is a real one.
- For a small team the honest value is reproducibility and parity, not scale. Docker earns its place the moment “works on my machine” starts costing you hours.
- It is premature when a managed platform already gives you clean, repeatable builds, or when a single service has no environment drift worth collapsing.
- The real costs are operational: images to keep small and patched, a registry to manage, and the steady pull toward orchestration you may not need yet.
- Containers map neatly onto the twelve-factor ideas, which is a better reason to reach for them than “everyone uses Docker.”
Docker is one of those tools a small team is told it needs long before anyone can say why. It turns up in a job description, a tutorial, and a conference talk, and at some point someone opens a pull request that adds a Dockerfile and nobody quite remembers deciding to. We like Docker. We also think most teams who adopt it early would be fine without it for a while longer, and that the useful question is not whether to use containers but when the pain they solve has actually arrived. This post is our answer to that question.
What Docker actually is
Strip away the ecosystem and Docker is a way to package an application together with everything it needs to run: the runtime, the system libraries, the dependencies, and the configuration defaults, all of it, into a single image. That image is a build artifact. You build it once, and the container that runs from it behaves the same way wherever it runs, because it carries its environment with it instead of borrowing the host’s. The host needs to run containers and nothing else. It does not need the right version of your language installed, or the right system package, or the right anything.
That is the property that matters, and it has a plain name: parity. The thing you tested is the thing you ship. “Works on my machine” stops being a shrug and starts being a guarantee, because your machine, the CI runner, and the production host all run the same image rather than three hopeful approximations of the same setup. The official Docker getting-started guide walks through the mechanics of images, layers, and containers, and it is the right place to learn the moving parts. What it cannot tell you is whether your team needs them yet. That is a judgement call, and it is the part we get asked about.
The real value for a small team
For a large fleet, containers are about density and scheduling, packing many workloads onto shared hardware and moving them around. A small team almost never has that problem. The value for a small team is narrower and more human: it is the end of environment drift.
Environment drift is the slow divergence between the places your code runs. One developer upgraded a system library six months ago and forgot. CI is pinned to an older runtime than anyone’s laptop. Production has a package installed by hand during an incident that nobody wrote down. Each of these is small. Together they are the reason a deploy that passed every test falls over in production, and the reason onboarding a new developer eats a day of “try installing this, now try this.” Docker collapses that divergence into one artifact everyone shares. A new developer runs one command and has the whole environment. CI builds the same image you ship. The gap where drift used to live is simply not there.
That is worth real money to a small team, but only once the drift exists to be removed. Which brings us to the other half of the honest answer.
When it is premature, and when a platform hides the need
Docker is premature when there is no drift to collapse. A single static site, a small service with a handful of dependencies, a project where one person builds and deploys and the environment has never once surprised anyone: adding Docker to that buys you a Dockerfile to maintain and not much else. You have taken on a build step and a mental model in exchange for solving a problem you did not have.
It is also, often, unnecessary because a managed platform has already solved it for you. This is the part teams miss. When you deploy to a platform that builds your app from source in a clean, repeatable environment on every push, you are already getting most of what Docker’s parity gives you, without running Docker yourself. The platform’s build is the reproducible environment. We wrote about one such path in the shortest route from code to a running service, and the general point holds across that whole category: if your host rebuilds cleanly from your repository every time, the “works on my machine” problem is already mostly handled, and reaching for Docker on top of that can be redundant. There are good reasons to containerise anyway, which we will come to, but “the tutorial had a Dockerfile” is not one of them.
So the test we apply is simple. Is environment drift actually costing you time, in failed deploys, slow onboarding, or incidents that trace back to a mismatch between environments? If yes, containers are likely to pay for themselves quickly. If no, and especially if a managed platform is already giving you clean builds, we will usually tell you to wait. We do not sell Docker, and we have no reason to talk you into operational overhead you do not need yet.
The twelve-factor connection
There is a more principled reason containers tend to be a good fit, and it is worth understanding because it outlasts any particular tool. The twelve-factor app methodology is a widely cited set of principles for building services that are easy to deploy, scale, and reason about. It predates Docker’s popularity, but containers and twelve-factor pull in the same direction so consistently that adopting one tends to push you toward the other.
Twelve-factor says to treat configuration as something injected from the environment rather than baked into the code, to treat backing services like databases as attached resources you can swap, to keep build and run as distinct stages, and to keep processes stateless and disposable so they can start and stop freely. Every one of those reads like a description of how a well-made container behaves. An image that reads its config from the environment, holds no state of its own, and can be killed and restarted without ceremony is a twelve-factor process whether or not anyone used the phrase. This is why we treat “should we containerise” and “is this app built along twelve-factor lines” as nearly the same question. If the app already follows those principles, Docker fits it like a glove. If it does not, Docker will expose that, loudly, the first time you try to run two copies of a process that assumed it was the only one.
The honest tradeoffs
Containers are not free, and the costs are the kind that show up later rather than on day one. Three are worth naming.
The first is operational overhead. An image is a thing you now own and have to keep current. The base image you built on gets security updates, and if you never rebuild, you are shipping known-vulnerable libraries with a long shelf life. Container images and their dependencies are a real part of your attack surface, and the categories in the OWASP Top Ten, particularly around vulnerable components and misconfiguration, apply as much to what is inside your image as to your application code. A stale image running as root with a dozen unpatched packages is a liability dressed up as reproducibility. Someone has to own rebuilding and scanning, and on a small team that someone is already busy.
The second is image size. The easy Dockerfile is almost always the fat one: it pulls a large base image, installs build tools it only needs at build time, and ships all of it to production. Fat images are slow to pull, slow to deploy, and larger than they need to be in storage and in transfer. Keeping them lean takes deliberate work, multi-stage builds and careful base-image choices, and it is work that is easy to skip and expensive to have skipped.
The third, and the one we watch for most, is orchestration creep. Docker on one machine is simple. The moment you have containers you start hearing that you need something to schedule them, and the conversation drifts toward a cluster, a control plane, and a whole second system to operate. For many small teams that is a large step up in complexity for a problem they do not have yet. Containers do not require orchestration. Reaching for a cluster before the workload justifies it is one of the more common ways we see early teams spend their scarcest resource, attention, on infrastructure instead of on the product.
How we think about introducing it
Our bias is to introduce Docker when it solves a problem you can point at, and not before. If drift is costing you time, if you are standing up a service that genuinely needs the same environment across many machines, or if you are already building along twelve-factor lines and containers would simply formalise what you are doing, it is a good call and we will help you make it well: small images, nothing running as root, a sane registry, and a build that stays legible to the next person. If none of that is true yet, the honest advice is to keep the setup simple and revisit when the shape of the work changes.
This is the same approach we take to any infrastructure review. We start from what is actually hurting rather than from a list of tools you ought to have, which is also where our AWS account review begins. The goal is an environment you can reason about and rebuild, and sometimes that means Docker and sometimes it means noticing you already have reproducibility from somewhere else.
Where we can help
If your deploys keep breaking in ways that trace back to environment differences, or you are weighing whether to containerise and want a straight answer rather than a sales pitch, that is exactly what our DevOps help is for. We will tell you when Docker earns its place and when it would just be overhead, and if you want the work done well rather than done fashionably, we can do that too. See the full shape of the work on the services page, and when you are ready, start a DevOps engagement and tell us what you are running.