Containers vs Virtual Machines
Both run your application in isolation. They isolate at different layers, and that difference explains everything else.
A virtual machine virtualises hardware and runs its own kernel. A container shares the host kernel and isolates processes. Every practical difference follows from that one distinction.
The comparison
| Virtual machine | Container | |
|---|---|---|
| Isolation boundary | Hardware, via hypervisor | Kernel namespaces and cgroups |
| Own kernel | Yes | No — shares the host |
| Start time | Tens of seconds | Under a second |
| Size | Gigabytes | Tens to hundreds of megabytes |
| Density per host | Tens | Hundreds |
| Overhead | A few per cent | Almost none |
| Different OS | Yes | Same kernel family only |
| Isolation strength | Stronger | Strong, with a shared kernel |
Why containers changed deployment
The technical advantages matter less than one practical one: a container image bundles the application with its dependencies, so what runs in production is bit-for-bit what ran in testing.
- No more environment drift between machines.
- Deployment becomes pulling an image and starting it.
- Rollback becomes starting the previous image.
- Local development can run the same image as production.
- The build is reproducible from a Dockerfile in version control.
That reproducibility is the actual reason containers won, not density or startup time.
Where virtual machines remain the right answer
- You need a different kernel, or kernel modules the host does not provide.
- You need a different operating system entirely.
- Stronger isolation is required between untrusted workloads.
- The software expects a full system — a traditional database, some enterprise applications.
- Licensing is tied to a machine or physical cores.
- The team has no container experience and the workload is simple.
It is also worth saying that containers run on virtual machines almost everywhere. This is rarely an either-or choice in practice.
Container security, specifically
A shared kernel means a kernel vulnerability is a shared risk. Reasonable practice:
- Run as a non-root user inside the container.
- Drop unnecessary Linux capabilities.
- Use read-only root filesystems where the application allows it.
- Scan images for known vulnerabilities and rebuild on base image updates.
- Keep images minimal — fewer packages, fewer vulnerabilities.
- Never run privileged containers unless there is no alternative.
- Keep the host kernel patched, since it is shared by everything.
For genuinely untrusted workloads — running other people’s code — use VM-level isolation, or a sandboxed runtime that gives each container its own lightweight kernel.
The middle ground
MicroVMs give each workload a real kernel while booting in milliseconds. Serverless platforms use them to combine container-like agility with VM-level isolation, which is why running arbitrary tenant code on those platforms is safe.
You rarely choose this directly; it is what sits under managed container and serverless platforms.
Practical guidance
- Containerise the application. The reproducibility benefit applies regardless of where it runs.
- Run containers on virtual machines for a small estate — Docker Compose on one or two servers.
- Move to a managed container platform when operations become the constraint.
- Use Kubernetes when you have many services and someone to operate it.
- Keep databases on virtual machines or managed services rather than in containers for production data.
Common questions
Are containers less secure?
The isolation boundary is thinner. Configured properly — non-root, minimal images, patched host — they are appropriate for the great majority of workloads. Untrusted multi-tenant code is the exception.
Can I run Windows containers on Linux?
No. Containers share the host kernel, so the kernel family must match. Running Windows containers requires a Windows host.
Should databases run in containers?
For development, absolutely. For production data, a managed service or a VM is usually preferable, mostly because the operational stakes of a mistake are higher.
Do containers save money?
Through higher density and faster scaling, yes. The larger saving is usually in deployment reliability and reduced time spent on environment problems.
Where to go next
See running Docker on a cloud server and what happens when you launch an instance.