What Is a Container? Isolation Without a Full VM
A container is an isolated process: your app plus its dependencies, sharing the host kernel but with its own filesystem, network, and resource limits.
Containers solve the "works on my machine" problem by bundling code and everything it needs into one portable unit. Unlike a virtual machine, a container does not ship a whole operating system - it borrows the host kernel and isolates only what it needs to. That makes containers small, fast to start, and ideal for the throwaway environments CI depends on.
What isolation actually means
On Linux, a container is just a normal process that the kernel has fenced off using namespaces (its own view of the filesystem, process tree, network, and users) and cgroups (limits on CPU, memory, and I/O). Inside, the process believes it has the machine to itself; outside, it is one process among many.
Containers vs virtual machines
A VM virtualizes hardware and runs a full guest OS with its own kernel, so it is heavy and boots in seconds to minutes. A container shares the host kernel, so it is lightweight and starts in milliseconds. The trade-off: VMs give stronger isolation; containers give density and speed.
What goes inside a container
- Your application binary or interpreted code.
- Runtime and system libraries it links against.
- Config files and environment defaults baked into the image.
- Nothing else - no kernel, ideally no shell or package manager you do not need.
Why CI loves containers
Every CI job wants a clean, identical environment. A container gives you exactly that: the same image runs the same way on a laptop, a runner, and production. Builds become reproducible, and a job cannot leave state behind to poison the next one.
A quick example
Running docker run --rm -it python:3.12 python -c "print(1+1)" pulls a Python image, starts a container, prints 2, and removes the container - all without touching your host Python. The --rm flag makes it ephemeral, exactly the property CI wants.
Containers in CI
CI providers run each job in a fresh container or VM and tear it down afterward, which is why your pipeline starts clean every time. Building those container images can be slow on cold runners; managed runners (like Latchkey) speed image builds with warm layer caches and retry transient registry blips automatically.
Key takeaways
- A container is an isolated process sharing the host kernel, not a mini-VM.
- Namespaces provide isolation; cgroups provide resource limits.
- Containers start fast and are reproducible, which is why CI relies on them.