What Actually Is a Container?
If a container isn’t a tiny VM?
People will tell you it’s a process. That only helps if “process” means something concrete.
What is a process?
Take server.js sitting on disk. That’s a program: instructions that aren’t doing anything yet. It’s like a recipe sitting on the kitchen counter. The instructions are there, but nothing is being cooked.
Then you run node server.js. That’s like picking up the recipe and actually starting to cook. That activity is what we mean by a process.
Once you start cooking, you need things. A burner. A pot. Counter space. Ingredients. The recipe itself doesn’t need any of those things while it’s sitting there. The cooking does.

Once the program is actually running, it needs resources from the machine. CPU time to execute instructions. Memory to work with. Access to files. Often a network connection. The kernel manages how the process interacts with those resources.
Still a process on the host
Putting the application in a container doesn’t change that. We’re still cooking. We haven’t created another kitchen.
node server.js is still a process running on the host, using resources managed by the host’s kernel. We haven’t booted another operating system for it. Same machine. Same kernel. Still a process.
So where does the isolation come from?
What can the process see?
Here’s the weird part. The process is on the same machine, using the same kernel, and yet from inside the container it can look like it has its own little world. Its own process list. Its own view of the filesystem. Its own network setup. Sometimes even its own hostname.
That does not mean the machine was duplicated. It means the kernel can show different processes different views of the same underlying system.
Same host. Different picture of what “the system” looks like from inside that process.
Once you have that idea, Linux has a name for the mechanism: namespaces.
Isolation here starts as a different view, not a second computer.
Which leaves the other half of the problem sitting in plain sight. Even if we’ve controlled what the process can see, what stops it from eating all the CPU or memory on the shared host?
How much can the process use?
Changing what a process can see does not stop it from using the machine.
The host’s CPU and memory are still shared. If one process keeps allocating memory, or keeps burning CPU, a different view of the filesystem will not protect the other workloads on that box. From their side of the machine, things just get slow, or worse.
So isolation needs a second half. Not only “what does this process see?” but also “how much is this process allowed to consume?”
Linux answers that with cgroups (control groups). They let the system account for the resources a process is using, and control them. CPU. Memory. A way to put boundaries around how much of the shared host a process can use.
That’s the idea. Not the hierarchy, not the versions, not the flags. Just: shared machine, finite resources, and a way to put boundaries on how much one process can take.
So what actually is a container?
Namespaces change what the process can see. Cgroups change how much of the machine it can use.
So if a container isn’t a tiny VM, what actually is it?
A useful answer is this. The application is still a process on the host. It still uses the host kernel. What we call a container is that process with boundaries around it: a different view of the system, and limits on the shared resources it can consume.
That is the mental model. Not a complete inventory of every mechanism involved in real containers. Enough to stop thinking of them as small virtual machines.