Where to Run Containers: Choosing a Runtime
Containerisation itself is a solved problem. If you still need the fundamentals - what a container is, and which container engine to use (Docker, LXC/LXD, OCI runtimes) - start there and come back. This article assumes you already have a Dockerfile and an image, and you are asking the next question: what should run it in production?
Getting this choice wrong is expensive in both directions. Reach for Kubernetes too early and you pay for cluster complexity you don’t need. Stay on a single Docker host too long and you hit scaling, availability, and deployment pain that an orchestrator would have solved. The goal here is to match the runtime to the actual shape of your workload.
The Four Runtime Models
Almost every way to run a container falls into one of four models. They form a ladder of increasing capability - and increasing operational cost.
1. Self-managed Docker host
A single VM (EC2, Azure VM, a droplet) running the Docker daemon, often with docker compose for multi-container apps. You own the OS, patching, backups, and uptime.
Good for: a side project, an internal tool, a staging box, or a genuinely small single-service app with no HA requirement.
Breaks down when: you need zero-downtime deploys, more than one node, or automatic restart of a failed host. There is no built-in scheduler - if the box dies, your app is down until someone intervenes.
2. Managed container service (ECS / Fargate / Container Apps / Cloud Run)
The cloud provider runs the control plane; you hand it a container image and a bit of config. Amazon ECS schedules containers; with the Fargate launch type you don’t manage servers at all. Azure Container Apps and Google Cloud Run occupy the same niche.
Good for: the large majority of production web apps and APIs - 1 to a handful of services, variable traffic, a team that wants containers in production without becoming cluster operators.
Breaks down when: you need fine-grained control over scheduling, a rich ecosystem of operators (service mesh, custom controllers), or portability across clouds at the orchestration layer.
3. Kubernetes (EKS / AKS / GKE or self-managed)
A full orchestrator. Enormous capability - declarative state, self-healing, horizontal/vertical/cluster autoscaling, a vast ecosystem - at the cost of real operational complexity. Managed control planes (EKS, AKS, GKE) remove the hardest part but not the learning curve.
Good for: 5+ microservices talking to each other, strict zero-downtime and elasticity requirements, GitOps workflows, or a deliberate multi-cloud strategy.
Breaks down when: you have 1-3 services and no growth plan, or the team has no container operations experience yet. The overhead outweighs the benefit. We cover the when-and-how in detail in our practical introduction to Kubernetes.
4. Serverless (Lambda / Cloud Functions, container-image based)
The container is an implementation detail; you deploy a function and the platform runs it on demand, scaling to zero when idle. AWS Lambda supports container images up to 10 GB.
Good for: event-driven work, scheduled jobs, spiky or low-volume APIs, glue code between services. You pay only for execution time.
Breaks down when: you have sustained high traffic (per-request pricing stops being cheap past a few million requests/month), long-running processes, or latency-sensitive workloads where cold starts hurt.
Decision Table
| Model | Ops effort | Scales to zero? | Best fit | Rough monthly floor |
|---|---|---|---|---|
| Self-managed Docker host | High (you own the OS) | No | Side projects, internal tools, staging | Cost of 1 VM (~$10-40) |
| Managed service (Fargate / Cloud Run / Container Apps) | Low | Cloud Run / Container Apps: yes; Fargate: no | Most production web apps and APIs | ~$15-50 for a small always-on service |
| Kubernetes (EKS / AKS / GKE) | High | Not by default (needs tuning) | 5+ microservices, HA, multi-cloud | ~$350-450 for a minimal 3-node cluster |
| Serverless (Lambda / Cloud Functions) | Very low | Yes | Event-driven, scheduled, spiky, low-volume | $0 at idle; pay per execution |
Figures are indicative baselines for planning, not quotes - real cost depends on instance sizes, traffic, storage, and data transfer.
A Simple Way to Choose
Work down this list and stop at the first “yes”:
- Is it event-driven, scheduled, or low-volume? → Serverless (Lambda / Cloud Functions). Let it scale to zero.
- Is it 1-3 services that need to be online, with variable traffic? → Managed container service. Fargate (AWS), Cloud Run (GCP), or Container Apps (Azure). This is the default answer for most teams.
- Do you have 5+ interconnected services, strict HA/elasticity needs, or a multi-cloud mandate? → Kubernetes. Managed control plane unless compliance forces self-managed.
- Is it a throwaway, internal, or staging workload where downtime is fine? → A single Docker host is honest and cheap.
The most common mistake we see is skipping straight to step 3. Kubernetes is a platform, not a default. If steps 1 or 2 fit, take them - you can always graduate to Kubernetes later, and the containerisation work you’ve already done carries over directly.
Picking Between Clouds
Once you’ve chosen a model, the specific service depends on your cloud. The mapping is close but not identical - AWS ECS/Fargate/EKS line up against Azure Container Apps/ACI/AKS and Google Cloud Run/GKE, with meaningful differences in pricing, networking, and ecosystem. We compare these side by side, including a full service-mapping table, in AWS vs Azure container deployment strategies.
Containers are also the foundation of microservices architecture and cloud native applications - if that’s where you’re heading, the runtime choice above is the first infrastructure decision on that path.
Summary
There is no single “best” place to run a container - there is a best fit for your workload’s shape. Serverless for event-driven and spiky work. A managed container service (Fargate, Cloud Run, Container Apps) for the majority of production apps. Kubernetes when scale and complexity genuinely justify it. A plain Docker host for the small and the disposable. Match the model to the workload, defer complexity until you need it, and let the containerisation work you’ve already done move with you as requirements grow.
Frequently Asked Questions
Do I need Kubernetes to run containers in production?
No. For 1-3 services, a managed container service like AWS Fargate, Google Cloud Run, or Azure Container Apps runs containers in production with far less operational overhead. Kubernetes becomes worthwhile at around 5+ interconnected services or when you need its ecosystem and multi-cloud portability.
What is the difference between ECS and Fargate?
ECS is Amazon’s container scheduler. Fargate is a launch type for ECS (and EKS) where AWS runs the underlying servers for you, so you don’t manage EC2 instances. You can run ECS on EC2 (you manage the hosts) or on Fargate (you don’t).
Can I run a container as a serverless function?
Yes. AWS Lambda, Google Cloud Functions, and Azure Functions all support deploying a container image as the function package. This suits event-driven and low-volume workloads that benefit from scaling to zero, but is a poor fit for sustained high traffic or long-running processes.
How do I move from a single Docker host to something more scalable?
The container image you already have is portable. The next step is usually a managed container service (Fargate, Cloud Run, Container Apps) - you supply the same image plus a small amount of config. Moving to Kubernetes is a larger step that adds manifests, Ingress, and config/secret management; see our Kubernetes introduction.