Container
A lightweight, isolated process running on a shared Linux kernel using namespaces and cgroups — providing filesystem, network, and process isolation without the overhead of a full virtual machine.
Container — The Fundamental Unit of Modern Infrastructure
What Is a Container in Simple Terms?
A container is a running process on a Linux host that has been given its own private view of the world. It thinks it has its own filesystem, its own network interface, its own process tree starting at PID 1, and its own hostname. In reality, it is sharing the host's Linux kernel with every other container on that machine.
The analogy that makes this click: a container is like a private office in a shared office building. Every office has its own lock, its own phone number, and its own nameplate. The people inside cannot see or hear the people in the other offices. But everyone is in the same building, using the same shared elevator, same electricity, and same internet connection. Containers share the host kernel the same way offices share the building's infrastructure.
This is fundamentally different from a virtual machine, which has its own complete operating system, its own kernel, and its own hardware emulation layer. That is like renting an entire separate building.
Why Containers Start in Milliseconds
When you start a VM, the hypervisor has to boot a complete operating system — BIOS initialization, kernel boot, init system startup, service initialization. This takes 30-60 seconds minimum.
When you start a container, there is no OS to boot. The Linux kernel is already running. Docker just creates a new set of namespaces (microseconds), sets up cgroup limits (microseconds), copies the container filesystem view using OverlayFS (milliseconds), and starts the application process. Total: under 1 second for most containers.
At Swiggy, when traffic spikes at 7pm during dinner rush, the autoscaler spins up new container instances in under 5 seconds. With VMs, that same scale-out takes 2-3 minutes. This speed difference changes how you design for capacity.
The Six Linux Namespaces That Make Containers Possible
Namespaces are a Linux kernel feature that creates isolated views of system resources. Docker uses six of them together:
PID namespace: Container sees PID 1 (nginx) Host sees PID 12345 (same process) NET namespace: Container has eth0, 172.17.0.2 Isolated from the host's network MNT namespace: Container sees /etc/nginx/nginx.conf That file does not exist on the host UTS namespace: Container hostname: payment-api-xyz Host hostname: mumbai-prod-node-1 IPC namespace: Container has its own shared memory Cannot access host's IPC resources USER namespace: Container root (UID 0) maps to unprivileged host UID 65534cgroups — Resource Limits That Actually Work
Namespaces provide isolation. cgroups (control groups) provide resource limits. Without cgroups, a container could use all the CPU and memory on the host. With cgroups, Docker enforces hard limits:
# Set a container to use at most 512MB memory and 1.5 CPU coresdocker run -d \ --name payment-api \ --memory=512m \ --cpus=1.5 \ registry.razorpay.in/payment-api:v3.1.0 # Verify the cgroup limits are set on the hostcat /sys/fs/cgroup/memory/docker/$(docker inspect --format '{{.Id}}' payment-api)/memory.limit_in_bytes# 536870912 = 512MB in bytes # If the container tries to use more than 512MB:# Kernel sends SIGKILL to the container process# Exit code: 137 (OOMKilled)# docker inspect shows OOMKilled: trueContainer vs Image — The Class and Instance Analogy
A container is a running instance of an image. An image is the template. This is exactly like the class/instance relationship in object-oriented programming:
Docker Image = Class definition (blueprint, static, on disk)Container = Instance (running, has state, in memory)# One image can create many containers:docker run -d --name api-1 nginx:1.25docker run -d --name api-2 nginx:1.25docker run -d --name api-3 nginx:1.25# Three separate containers, all running from the same nginx:1.25 image# Each container has its own read-write layer# Changes in api-1 do not affect api-2 or api-3# All three share the read-only image layers (no duplication on disk)What Containers Are NOT
Containers are not a full virtual machine — they share the host kernel. They are not completely secure isolation — kernel vulnerabilities affect all containers. They are not persistent storage — files written inside die with the container by default. And they are not a replacement for proper application security, since a compromised container process is still running on the host kernel.
Practical Container Commands
# Run a container and get a shell inside itdocker run -it ubuntu bash# -i = interactive (keep stdin open)# -t = pseudo-TTY (proper terminal) # See all containers (running and stopped)docker ps -a # See the actual processes on the host that containers areps aux | grep nginx# The container's nginx process has a real PID on the host # See that it is isolated by checking from inside the containerdocker exec -it my-nginx ps aux# You see: PID 1 = nginx master# On the host you see a different PID for the same processQuick Reference & Troubleshooting Commands
| Problem | Cause | Fix |
|---|---|---|
| Container exits immediately | Process inside container exited | docker logs container-name to see why |
| Container uses too much memory | No memory limit set | Add --memory=512m to docker run |
| Cannot see container from host network | No port published | Add -p 8080:80 to docker run |
| Container filesystem changes lost | Wrote to container filesystem, not a volume | Mount a volume: -v mydata:/app/data |
| Container and host share a file | Using bind mount | Normal: -v /host/path:/container/path |
TipRun
docker run --rm alpine cat /proc/1/cgroupand then runcat /proc/1/cgroupon your host. You will see different cgroup paths — this is the cgroup isolation that limits the container's resources. This is the same Linux feature Kubernetes uses for pod resource limits.
RememberContainers share the host kernel. A vulnerability in the Linux kernel affects all containers on that host. This is why privileged containers (
--privileged) are dangerous — they have access to most of the host's kernel features and can break out of their namespace isolation under certain conditions.
Common MistakeThinking containers are completely isolated from each other. They are isolated from each other's filesystems, networks, and processes — but they share the host kernel. A kernel exploit that works inside one container can potentially affect the entire host and all other containers. Container security is about reducing the attack surface, not achieving VM-level isolation.
SecurityNever run containers with
--privilegedunless absolutely necessary. A privileged container disables most of the namespace and capability isolation that makes containers safe. It can access host devices, load kernel modules, and modify network interfaces. If you think you need--privileged, first investigate whether you can achieve the same result by adding only specific capabilities with--cap-add.
Frequently Asked Questions
How is a container actually different from a lightweight VM under the hood?
A VM virtualizes hardware and runs its own full kernel via a hypervisor; a container is just a regular Linux process that the kernel makes think it's isolated, using namespaces (for filesystem, network, PID, and user isolation) and cgroups (for resource limits). Because there's no second kernel or hardware emulation layer, containers start in milliseconds instead of the tens of seconds a VM boot takes, and have near-zero memory/CPU overhead beyond the process itself.
What's a common misconception engineers have about container isolation?
Treating a container as an equivalent security boundary to a VM. Because all containers on a host share the same kernel, a kernel-level exploit or a serious misconfiguration (like running as root with `--privileged`) can potentially escape a container and affect the host or sibling containers — something not possible with proper VM isolation. Don't rely on containers alone as a hard multi-tenant security boundary for genuinely untrusted workloads without extra layers like gVisor or Kata Containers.