Skip to content

Comparison

Docker vs Kubernetes

These two are compared constantly and they are not competing products. The question hiding behind the search is whether your containers need an orchestrator at all, and if they do, whether it has to be Kubernetes.

What the choice is actually between

Let us clear up the comparison itself before anything else, because the framing is wrong and it sends people towards the wrong decision. Docker and Kubernetes are not alternatives. Docker is how you build a container image and run containers on a machine. Kubernetes is how you schedule containers across a fleet of machines, keep the declared number of them running, replace them when a host dies, roll out new versions gradually and give them a stable network identity while the individual containers come and go. They sit at different layers. You do not choose one instead of the other, and it is worth adding that Kubernetes has not used Docker as its container runtime for years, since it now speaks to containerd and other runtimes through a standard interface, while still running the images Docker builds without any translation at all.

So what is the question people are actually asking when they type this? Almost always one of two things. The first is a vocabulary question: they have heard both names constantly, cannot tell what each one does, and want the boundary drawn. The second, and the more consequential one, is a decision question: they have containerised something, it works, and they are trying to work out whether the next step is Kubernetes, whether it is something simpler, or whether they need anything more at all. That second question is the one worth answering properly, because getting it wrong is expensive in a way that persists for as long as the system exists.

Our position on it is the same one we take everywhere else on this site, and it is not the one a consultancy is expected to take: most teams that adopt Kubernetes do not need it. What they actually need is a way to run a handful of containers reliably, deploy without dropping requests, and get a bit more capacity under load. There is a large and under-discussed middle ground between one machine running Docker and a Kubernetes cluster, and for a great many organisations something in that middle ground is the correct answer for years. Kubernetes is excellent technology and it is genuinely the right choice for a real minority of teams. The rest are paying a permanent operational cost for a consistency problem they do not yet have.

The short answer

If you are running a small number of services with modest traffic and a small team, Docker plus something simple is enough, and it will stay enough for longer than the industry conversation suggests. That might be a single well-provisioned host running Docker Compose with a process supervisor and tested backups, which is a legitimate production architecture rather than something to apologise for. More often it should be a managed container service such as ECS with Fargate, Cloud Run or Azure Container Apps, or a platform-as-a-service, which will take your image and handle scheduling, health checks, scaling, rollouts and load balancing without you operating a cluster at all.

You genuinely need Kubernetes when several specific conditions hold at once rather than one of them holding loosely. Many services, on the order of dozens rather than a handful, that deploy and scale and fail independently. Multiple teams sharing the same infrastructure and needing guardrails, quotas and boundaries between them. A real portability requirement across clouds or into your own hardware, driven by residency, regulation, an acquisition or a customer contract rather than by a preference. Bursty or batch workloads that need a great deal of capacity briefly and nothing the rest of the time. And, non-negotiably, a named person or team who owns the platform as their job rather than as a side responsibility.

That last condition is the one that decides more of these than any technical factor. Kubernetes assumes an engineering function exists to run it, permanently. Upgrades arrive on a cycle you do not control, deprecated APIs break manifests between versions, add-ons each have their own release cadence, security policy has to be maintained and cost has to be reviewed. A cluster with no owner does not stay as it is, it degrades quietly, and the first real incident finds nobody who understands the networking. If you cannot name the owner, the answer is no regardless of how well the rest of the criteria fit.

Whichever way that goes, you almost certainly want Docker. It is the packaging layer underneath all of these options, the image format is an open standard, and building good images is what makes every runtime above them behave predictably. The genuinely useful property is that the packaging decision and the runtime decision are separate: you can containerise now, run on one host or a managed service, and adopt an orchestrator years later without redoing the packaging.

Side by side

DimensionDockerKubernetes
What it actually isA build tool and a runtime for containers on a machine. It produces an image and runs containers from it.A container orchestrator. It schedules containers across many machines and continuously reconciles what is running against what you declared.
The layer it occupiesPackaging and single-host execution. The artefact and how it starts.Fleet management. Placement, replacement, rollout, scaling and networking across hosts. It runs the artefact Docker built.
Are they alternativesNo. Docker is used with orchestrators, not instead of them, and its images run on every one of them.No. Kubernetes needs images built by something, and it has not used Docker as its runtime for years while still running Docker-built images unchanged.
Scheduling across machinesNone. Docker runs containers on the host you ran the command on. Deciding which host is your problem, or somebody else’s.This is its core function. The scheduler places pods on nodes based on resource requests, affinities and taints, and reschedules them when a node goes away.
Self-healingRestart policies bring a container back on the same host. If the host is gone, nothing happens.Control loops replace failed containers and reschedule workloads off dead nodes without anybody being paged. This is the benefit people correctly get excited about.
Rollouts and rollbackYou stop the old container and start the new one, or you script something more careful. There is no gradual rollout watching health checks.Rolling updates as configuration, with canary and blue-green where needed, surge limits, pod disruption budgets and automatic rollback when readiness probes fail.
Service discovery and load balancingContainer networking on one host, with names resolvable inside a Compose project. Nothing stable across a fleet.Services give a stable identity in front of ephemeral pods, with ingress or Gateway resources routing external traffic and terminating TLS.
ScalingRun more containers until the host runs out of CPU or memory. Beyond that you add machines and something has to decide what goes where.Horizontal pod autoscaling on CPU, memory or custom metrics such as queue depth, with cluster autoscaling adding nodes underneath.
Time to productiveAn afternoon. A Dockerfile and a Compose file give a team reproducible environments almost immediately, which is rare for infrastructure tooling.Getting a service running takes an afternoon. Becoming genuinely comfortable diagnosing scheduling, networking and probe failures takes months of real exposure.
Standing operational costModest and mostly build-side: registries, credentials, base image updates and a rebuild cadence. Somebody owns it, but not full time.A permanent engineering commitment. Upgrades on a cycle you do not control, deprecated APIs, add-on maintenance, security policy and cost review. It never finishes.
Who it suitsEvery team that ships software in containers, which is nearly all of them, whatever they eventually run it on.Organisations with many independently deploying services, several teams on shared infrastructure, real portability requirements, or bursty batch work, and a platform owner.
The main failure modeBeing stretched into a production platform it was never meant to be, held together by deployment scripts, a cron job and an undocumented convention about which server runs what.Adoption far too early. The complexity is permanent, it is paid weekly, and it is very rarely reversed once production depends on it.
What sits between themCompose on a single host for small systems, and it is honest about being a development and small-system tool rather than an orchestration story.Managed container services, ECS with Fargate, Cloud Run, Azure Container Apps, or a platform-as-a-service, which cover most teams’ requirements without a cluster to operate.

Choose Docker when

  • You run one service, or a small handful, with modest and reasonably predictable traffic. A managed container service or a well-configured host will meet the requirement, and the orchestration layer would be answering a question you do not have.
  • Your team is small and nobody will own a platform as their actual job. Without a named owner, a cluster does not stay still: upgrades are deferred until the version is unsupported, certificates expire, and the first serious incident finds nobody who can help. This one condition is enough to settle it.
  • Your services do not need to deploy independently of each other in any meaningful way. The strongest argument for Kubernetes is coordinating many independently released services, and if you release together, you are buying the solution to a problem you do not have.
  • You want reproducible environments, an end to environment-specific bugs and a one-command local stack. That is Docker and Compose doing what they are genuinely excellent at, and it delivers most of the value teams associate with containers on day one.
  • You are packaging services to hand to a managed container service, a platform-as-a-service or somebody else’s runtime. Docker is the packaging step, and getting the image right, small, hardened, honest about its health, well behaved on shutdown, is what makes the runtime above it behave predictably.
  • You want to keep the decision open. Containerising now and choosing the runtime later is a genuinely good position, because the image format is an open standard and the packaging work is not wasted whichever way you go.
  • You are stabilising something fragile. Wrapping an older application in a container pins its runtime and dependencies in place and makes it movable, which is often the right first step of a modernisation programme and has nothing to do with orchestration.

Choose Kubernetes when

  • You genuinely run many services, on the order of dozens rather than a handful, that need to deploy, scale and fail independently. This is the condition that actually justifies a cluster, and it is the one most often assumed rather than met.
  • Several teams ship onto the same infrastructure and you need a paved road: namespaces with quotas, role-based access, shared conventions and admission policy, so teams move quickly without reinventing deployment or reaching into each other’s workloads. The value here is organisational rather than technical.
  • You have a hard requirement to run the same platform identically across clouds, or across a cloud and hardware in your own building, driven by data residency, a regulator, an acquisition or a customer contract. Portability of this kind is one of the few things no simpler platform can offer.
  • Your workloads are genuinely bursty or batch-heavy in a shape simpler platforms handle badly: jobs that need a great deal of capacity for twenty minutes and nothing afterwards, or queue consumers that should scale on queue depth rather than CPU, with node pools that scale to zero when idle.
  • You have somebody who will own the platform, and own it as their job. Not a side responsibility for whoever is least busy. Kubernetes assumes an engineering function exists to run it, and that assumption is the real cost of entry rather than the compute bill.
  • You will encode real operational knowledge as software. If the operator pattern lets you turn failover, backup and upgrade procedures into controllers rather than wiki pages, that is a durable asset which outlives the person who wrote it.
  • You have already outgrown the alternatives in a way you can describe concretely, rather than anticipating that you will. Hitting a real limit is a good reason to move. Expecting to hit one within two years usually is not, because you can adopt an orchestrator later and the packaging work carries across.

Where the boundary actually falls

Docker takes your application, its libraries, its runtime and its configuration, and produces an image: a specific, addressable artefact that behaves the same on a laptop, on a build runner and on a server. It will then run containers from that image on the machine you asked. That is a genuinely large amount of value, and for most teams it removes an entire category of problems on the first day, which is why containerisation is close to universal now regardless of what anybody runs on top.

What Docker does not do is decide which machine a container should run on, notice that a machine has died and start the workload somewhere else, roll a new version out gradually while watching health checks and stop if something looks wrong, give a service a stable network identity while individual replicas come and go, or balance traffic across instances. Every one of those is a fleet concern. When a team tries to cover that ground with Docker alone, the result is recognisable: a set of shell scripts, a cron job, an undocumented convention about which server runs what, and an arrangement that works right up until the evening a host disappears and nobody has ever tested what happens next.

Kubernetes exists precisely to cover that ground, and it does it through one idea applied consistently: you declare the state you want, and control loops work continuously to make reality match. You do not instruct it to restart something, you change what should be true and controllers close the gap. That is why a manual change to a running resource is quietly reverted and why deleting a pod produces a new one. Once that model lands, the platform is predictable. Until it does, it feels capricious, and that gap is where a great deal of early Kubernetes frustration lives.

The point of drawing the boundary this precisely is that it shows the two things are complementary rather than competing. Kubernetes runs images. Docker builds them. The quality of the image determines how well the orchestration layer behaves, and most orchestration pain we are called in to diagnose traces back to an image that was never designed to be orchestrated: bloated so every pull and every scale-up event is slow, with a health check that reports success before the application is ready, or started through a shell wrapper that swallows the termination signal so the process is killed abruptly with requests in flight. Those are Docker-layer problems presenting as Kubernetes problems.

The middle ground nobody mentions

The reason this comparison misleads people is that it presents two options when there are at least five, and the useful ones sit between them. Naming them concretely is the most valuable thing this page can do, because most teams considering Kubernetes have never seriously evaluated the alternatives and assume the choice is a cluster or chaos.

The simplest is a single well-provisioned host running Docker Compose, with a process supervisor to bring things back after a reboot, resource limits so containers do not starve each other, and backups that somebody has tested by restoring from them. This is a legitimate production architecture for a small internal system or an early product, and it is considerably more reliable than the same system spread across infrastructure nobody understands. Its honest limits are that a host failure is downtime and a deployment is a brief interruption unless you put effort into it, so it suits systems where those are acceptable and it stops suiting them the moment they are not.

The next step up, and the one that fits the largest number of teams, is a managed container service. Amazon ECS with Fargate, Google Cloud Run and Azure Container Apps all take an image and handle scheduling, health checking, scaling, rolling deployments and load balancing, without you operating a control plane, upgrading nodes, maintaining add-ons or learning a large vocabulary of objects. You get most of what teams actually want from Kubernetes and you skip nearly all of the standing operational cost. We recommend this more often than any other answer in this area, and it is consistently the option that surprises teams who arrived expecting a cluster.

Further along, a platform-as-a-service such as Render, Fly.io or Vercel takes your code rather than your image and handles more still, which suits teams who want to think about infrastructure as little as possible. It gives up some control in exchange, and for a product team shipping a conventional application that is frequently a good trade.

Only past all of that does a cluster start to earn its place, and when it does the recommendation is nearly always a managed control plane, EKS, GKE or AKS, rather than running the API server and etcd yourself. That removes a category of thankless, high-consequence work while leaving you with workloads, networking, security, storage, upgrades above the control plane and cost, which is more than enough to be getting on with.

The reason to walk the ladder deliberately is that each rung costs more to operate than the one below it, permanently, and the increment is paid whether or not you are using the capability it buys. Pick the lowest rung that meets your requirements, and be honest that "we might need more later" is not a requirement. You can move up a rung later, and because the image is the same artefact at every level, moving up is a smaller piece of work than it sounds.

The conditions that genuinely justify a cluster

It is worth being precise about what makes Kubernetes the right answer, because the usual justifications are vaguer than they should be and vagueness is how teams talk themselves into it. There are five conditions we look for, and the strongest signal is several of them holding at once rather than one holding loosely.

The first is service count with independent release. Not how much traffic you serve, and not how many repositories you have, but how many services genuinely need to be deployed, scaled and rolled back independently of each other by different people. Dozens of them, released on their own schedules, is the canonical case, because at that point the alternative to Kubernetes is not simplicity, it is a growing collection of bespoke deployment scripts that only their authors understand. Replacing that with one declarative model everyone can read is where the complexity starts paying for itself.

The second is multiple teams sharing infrastructure. When several teams ship onto the same platform, you need boundaries that hold: namespaces with quotas so one team cannot consume everything, role-based access so identities reach only what they should, network policy so a compromised workload cannot explore freely, and admission policy enforcing standards centrally rather than by convention. Kubernetes has genuinely strong primitives for this, and building the equivalent yourself is a large project. If you are one team, none of this applies to you.

The third is a real portability requirement. The same manifests running on managed Kubernetes at any of the major providers, on OpenShift and on hardware in your own building is a capability nothing simpler offers, and for organisations with a residency obligation, a regulator, an acquisition to absorb or a customer contract specifying where things run, it is the strongest single argument available. The word doing the work is real. Portability as insurance against a hypothetical future is not the same thing, and it is usually a way of paying now for an option nobody exercises.

The fourth is workload shape. Bursty and batch-heavy work fits Kubernetes well: jobs and cron jobs, custom autoscaling metrics such as queue depth rather than CPU, and node pools that scale to zero so idle capacity costs almost nothing. If your system needs a hundred pods for twenty minutes a day and nothing otherwise, that shape is handled better here than by most simpler platforms and it can be substantially cheaper than keeping capacity warm.

The fifth is ownership, and it is the one that vetoes everything else. Somebody must own the platform as their job. If the honest answer to "who runs this" is that the busiest engineer will look after it alongside their other work, the answer to the whole question is no, regardless of how well the first four conditions fit. An unowned cluster is not a neutral outcome, it is a liability that accumulates quietly and presents its bill during your first serious incident.

What each layer costs you to run

Docker has a modest standing cost and it is mostly build-side. Somebody owns the registry and its credentials, keeps base images current on a rebuild cadence because an image that was clean when it was built is not clean months later, maintains the build pipeline and its caching, and watches image size because every megabyte is pulled on every deployment and every scale-up event. For larger organisations there is also Docker Desktop licensing to be aware of, which is a procurement question rather than a technical one but catches teams by surprise often enough to mention. None of this is a full-time role, and it is work you will do regardless of what runs your containers.

A managed container service adds a modest amount on top: the platform’s own configuration model, its scaling and health check behaviour, and its integration with networking and identity. There is a learning curve and it is measured in days rather than months, because the surface you are exposed to is deliberately small. You do not upgrade a control plane, you do not maintain add-ons, and you are not exposed to deprecated APIs breaking your configuration between releases.

Kubernetes adds a permanent engineering commitment, and this is the honest centre of the comparison. Control plane and node upgrades arrive on a cycle you do not control. Deprecated APIs break manifests between versions, so upgrades are a real piece of work rather than a button. Every ecosystem add-on you install, ingress controller, secrets integration, observability stack, delivery tooling, has its own release cadence and its own upgrade path. Security policy has to be maintained rather than configured once, because the defaults are permissive by design. Resource requests drift from reality unless somebody revisits them. And somebody has to be on call who understands the networking well enough to diagnose why a pod will not schedule at an inconvenient hour.

The compute bill deserves a mention too, though it is rarely the dominant number. Clusters are almost always over-provisioned, because resource requests are set generously when a service is new and never revisited, so the scheduler reserves capacity that nothing uses across every replica of every service. Correcting that is usually the largest single cost improvement available in an inherited cluster and it is straightforward once there is data. But the dominant cost across the life of the system is human, and it does not decrease once the platform is built. That is the number to put in the comparison when you are weighing a cluster against a managed service, and it is the one most often left out.

Building images that behave, whatever runs them

Because the image is the contract between the build and whatever runtime you choose, it is worth stating what a good one looks like. This applies identically whether you end up on a single host, a managed container service or a cluster, which is another reason the packaging decision is safe to make before the runtime decision.

Use a multi-stage build so the final image contains the application artefact and nothing else: no compilers, no package manager, no build caches, no source. Choose the base deliberately and pin it to a digest rather than a mutable tag, so a build is reproducible and the base cannot shift under you between two builds of the same commit. Order the instructions so the layer cache actually works, which usually means installing dependencies from a lockfile before copying the source. Keep a strict ignore file so a large local directory is not sent to the build context on every run.

Then harden it, because the defaults do not. Run as a non-root user. Mount the root filesystem read-only and give the process a writable volume only where it genuinely needs one. Drop the Linux capabilities the workload does not use. Never pass a secret as a build argument or copy one into a layer, because it stays in the image history permanently and rebuilding without it does not remove it from images already distributed. Scan in the pipeline so a known critical vulnerability fails the build, and rebuild on a cadence rather than waiting for an audit.

And make it well behaved at runtime, because this is where orchestration problems are actually born. Give it a health check that reflects whether the application can serve traffic rather than whether a process exists, and distinguish readiness from liveness so a slow start is not mistaken for a failure. Make sure the process receives the termination signal rather than a shell wrapper swallowing it, and drain in-flight requests before exiting. Keep the image small, because pull time is deployment latency and it is scale-up latency too. Get these right and any runtime you choose will do its job easily. Get them wrong and you will spend your first months blaming the orchestrator for problems the image created.

Moving up the ladder, and occasionally back down

Going from Docker on a host to a managed container service is usually the easiest move in this whole area, and it is the one we recommend most often. The image is already the artefact, so the work is defining the service in the platform’s model, moving configuration and secrets to the platform’s mechanisms, putting a load balancer in front, sorting out networking and identity, and pointing traffic at it. The thing that most often needs fixing first is state: anything written to a container filesystem or a local volume has to move to object storage or a managed database, because the platform will replace your containers whenever it likes. That is a healthy piece of work to do at this point rather than later.

Going from a managed container service or a single host to Kubernetes is a bigger step and it should be taken incrementally. Establish the platform before anybody deploys onto it: managed control plane, node pools, default-deny network policy, role-based access federated to your identity provider, external secrets, admission policy, delivery through a repository as the source of truth, and observability wired in before the first real workload lands. Then move services one at a time, stateless first, shifting traffic gradually with a route back at every step. Resource requests, health checks and shutdown behaviour get corrected as each workload arrives rather than in a tidy-up phase that never happens. Stateful systems are designed deliberately or, more often, pointed at managed data services outside the cluster.

The mistake to avoid is a big-bang cutover onto a platform your team has not operated. The point at which people learn Kubernetes should not be the point at which production traffic depends on it, and teams that go live on day one start learning during their first incident, which is the most expensive classroom available.

Moving down the ladder happens more than people admit, and it is not a failure. An inherited cluster running three services that would be happier and cheaper on a managed container service is a common finding. The move is mostly a simplification: take the same images, express the workloads in the target platform’s model, move secrets and configuration, replicate the networking and ingress arrangement, migrate anything stateful to a managed service, run both in parallel and shift traffic. The genuine work is usually in untangling cluster-specific dependencies that accumulated quietly, in-cluster service discovery patterns, sidecars, custom resources, and anything relying on cluster-internal networking. Budget for discovering those rather than assuming an inventory exists.

One honest note before any of this. If you are considering a move because deployments are painful or unreliable, find out where the pain actually comes from first. A surprising share of it lives in the image and the pipeline rather than in the runtime: slow builds from poor layer ordering, large images that take an age to pull, health checks that lie, processes that ignore the termination signal and drop requests on every deployment. Those problems follow you to a new platform, and fixing them is a fraction of the cost of a migration. If deployment speed and reliability are the problem you are solving, look at your build and your image before you look at your orchestrator.

Technologies involved

How we help

Further reading

Common questions

Is it Docker or Kubernetes? Which should we pick?

Neither, because it is not that kind of choice. Docker builds container images and runs containers on a machine. Kubernetes schedules containers across many machines, keeps the declared number running, replaces them when a host fails, rolls out new versions and gives them stable networking. They occupy different layers, and Kubernetes runs the images Docker builds. It is worth knowing that Kubernetes has not used Docker as its container runtime for years, since it speaks to containerd and other runtimes through a standard interface, and this changed nothing about your images because the image format is an open standard. The real question behind this one is whether your containers need an orchestrator at all, and if so, whether it has to be Kubernetes rather than something considerably simpler.

Do we need Kubernetes?

Probably not, and we would rather say so plainly than design you a cluster. Kubernetes earns its complexity when several conditions hold together: many services, on the order of dozens, that deploy and scale independently; multiple teams sharing infrastructure and needing quotas, access boundaries and a paved road; a genuine requirement to run identically across clouds or into your own hardware, driven by residency, regulation, an acquisition or a contract; workloads that are bursty or batch-heavy in a shape simpler platforms handle badly; and somebody who owns the platform as their job. That last one is a veto. If nobody will own it permanently, the answer is no however well the others fit, because an unowned cluster degrades quietly and the first serious incident finds nobody who understands it.

What are the alternatives if we skip Kubernetes?

More than most teams realise, and they are good. A managed container service takes your image and handles scheduling, health, scaling, rollouts and load balancing without a cluster to operate: Amazon ECS with Fargate, Google Cloud Run, Azure Container Apps. These cover the requirements of a great many teams who assumed they needed Kubernetes, and the difference in standing operational load is enormous. A platform-as-a-service such as Render, Fly.io or Vercel goes further and takes your code rather than your image, which suits teams who want to think about infrastructure as little as possible. And for a genuinely small system, a single well-provisioned host running Docker Compose with a process supervisor, resource limits and tested backups is a legitimate production architecture. Choose the lowest rung that meets your actual requirements, not the one that meets the requirements you imagine having in three years.

Can we run Docker Compose in production?

For a small internal system on a single server, it can be adequate, and we have seen it used sensibly with a process supervisor, resource limits and backups that somebody has tested by restoring from. Be clear about what you are accepting: no scheduling across hosts, so a machine failure is downtime; no gradual rollout watching health checks, so a deployment is a brief interruption unless you put work into it; and no self-healing beyond restarting a container on a host that is still alive. For anything customer-facing with a real availability expectation, a managed container service is a small step up in cost and a large step up in reliability, and it is usually the right next move rather than a cluster.

Kubernetes dropped Docker support. Do our images still work?

Yes, completely, and the headlines at the time caused more alarm than the change warranted. What Kubernetes removed was the shim that let it use the Docker Engine as its container runtime; it now talks to containerd and other runtimes through a standard interface. Your images are unaffected because the image format is standardised under the Open Container Initiative, so an image built with Docker runs on Kubernetes, on Podman, on managed container services and on any other compliant runtime without translation. This is one of the genuinely good properties of the container ecosystem: your dependency is on an open format rather than on one vendor’s tool, and it is what lets you build with one tool and run on anything.

We have containers and one server. What is the natural next step?

Almost always a managed container service rather than a cluster, and the reason is that it solves the problems you actually have. You get scheduling across capacity you do not manage, health checking and replacement when something fails, rolling deployments, load balancing and scaling, and none of it requires you to operate a control plane, upgrade nodes, maintain add-ons or learn a large vocabulary. The preparatory work is worth doing carefully: move anything stateful out of container filesystems into object storage or a managed database, make sure configuration and secrets come from the environment rather than from the image, and give the containers honest health checks and correct signal handling. Do that, and the move is a matter of days rather than a project. Adopt an orchestrator later if the conditions for one genuinely arrive.

How long does it take a team to become productive on Kubernetes?

Longer than the proof of concept suggests, and that gap is where projects get into difficulty. Getting a service running on a cluster takes an afternoon. Becoming genuinely comfortable takes months of real exposure for a capable team: knowing why a pod will not schedule, whether it is an image pull failure, a resource request no node can satisfy, a failing probe, a missing secret, a node taint or a network policy; understanding what readiness failure actually means; handling an upgrade without anxiety. Plan for that rather than pretending otherwise. Build the paved road first so the common path is simple, migrate incrementally while the stakes are low, and rehearse operational procedures with the team rather than writing them down and leaving.

Should we containerise before we have decided on a runtime?

Yes, and it is one of the few sequencing decisions in this area that is unambiguously safe. The image format is an open standard, so the artefact you build runs unchanged on a single host, on any managed container service, on any cloud and on any orchestrator. That means the packaging work is not wasted whichever way the runtime decision goes, and it delivers immediate value on its own: reproducible environments, an end to environment-specific bugs, a one-command local stack for new engineers, and a clean disposable environment for every build. Containerise now, run it in the simplest way that meets your requirements, and keep the orchestration decision for when you have evidence rather than expectations.

Our deployments drop requests. Will Kubernetes fix that?

Probably not on its own, because the cause is usually in the image rather than in the runtime. The two most common reasons are signal handling and health checks. If the application is started through a shell wrapper, the shell receives the termination signal and the application never does, so it is killed abruptly after the grace period with requests in flight. If the health check reports success before the application is genuinely ready, or does not distinguish readiness from liveness, traffic arrives too early or a slow start is treated as a failure. Kubernetes will expose these problems more visibly because it stops and starts containers constantly, but it will not cure them. Run the process directly or under a proper init, handle the termination signal and drain connections before exiting, and write health checks that reflect whether the application can actually serve. Those fixes help on every platform.

Weighing Docker against Kubernetes?

Tell us the volumes, the compliance position and who would run it day to day. We will tell you which one we would choose for your case, and say so plainly when it is not the one we sell.

  1. 01A senior engineer reads it. Not a form queue, and not an account manager.
  2. 02We reply either with questions or with a straight answer that we are not the right fit.
  3. 03If it looks like a fit, a technical call with the person who would actually run the delivery.
  4. 04Then scope, effort and risk in writing, before anyone signs anything.

Two fields required. We reply to real enquiries. No list, no sequence.