Infra, Illustrated.
FOUNDATIONS · PROCESS ISOLATION

Containers, Illustrated

Watch one Node process acquire its filesystem, isolation, resource controls, and lifecycle as it becomes a container.

HOST · buildbox-01DEEP DIVE · FOUNDATIONALPublished Sep 16, 2026 · Reviewed Sep 16, 2026
LIVE SCENARIOnode server.js · host PID 18472 · container PID 1READY
HOST PID18472
INSIDE PID—
NETNShost
ROOTFS/
01 / BUILD THE BOUNDARY

A container starts as an ordinary Linux process

What extra mechanisms turn node server.js into a container?

LINUX PROCESS LABCHECKPOINT 01 / 05
HOST PROCESS VIEW
1systemd
921sshd
18472node server.js

Same process is scheduled by the host kernel.

CONTAINER EXECUTION CONTEXT
NAMESPACES · isolated viewsPID 1 inside / PID 18472 on hostmount · network · PID · UTS · IPC
ROOT FILESYSTEMimage layers + writable state
CGROUPmemory / CPU accounting and limits
SECURITY POLICYcapabilities · seccomp · LSM
node server.jsone Linux process · two PID views
LINUX HOST KERNELshared by host processes and containers

Process: host PID 18472 runs node server.js

OBSERVABLE EVIDENCE
$ ps -o pid,ppid,cmd -p 18472
18472  1312 node server.js
Containers isolate and constrain processes while sharing the host kernel.

A container is not a small VM. The runtime starts a host process with namespaces, cgroup membership, a root filesystem, and configured security restrictions.

Boundary: The exact setup belongs to the runtime and host configuration. Namespaces and cgroups are Linux mechanisms; their security properties depend on configuration.

Failure state: The process now sees the host’s corresponding namespace. Isolation is not an all-or-nothing property supplied by the image.

02 / BUILD THE BOUNDARY

Namespaces change what the process can see

Why does PID 1 inside still have a different host PID?

LINUX PROCESS LABCHECKPOINT 01 / 04
HOST VIEWPID 18472 · node server.jsscheduled by Linux host kernel
PID LENSPID 1 insidesame process, different numbering
MOUNT LENS/srv/app rootfsdifferent mounts and root path
NETWORK LENSeth0 · container IPits own interfaces, routes, localhost
ONE SHARED HOST KERNEL

Host view: host PID 18472

OBSERVABLE EVIDENCE
Illustrative: host PID 18472 ↔ namespace PID 1
Namespace isolation is a set of separate views around ordinary host processes.

The process can have distinct PID, mount, network, UTS, and IPC views. The host still schedules it. A namespace alters a selected view; it does not create a second kernel.

Boundary: User namespaces and their mappings are optional and vary by runtime configuration. Namespaces alone are not a complete security boundary.

Failure state: With host networking selected, the process shares the host network namespace; localhost and port binding behave differently.

03 / BUILD THE BOUNDARY

A cgroup accounts for and can constrain resources

Does container isolation automatically reserve CPU and memory?

LINUX PROCESS LABCHECKPOINT 01 / 04
PROCESS GROUPnode server.js + workers
CPU USEaccounted
MEMORYcurrent / configured max
PRESSURE EVENTreclaim · throttle · possible OOMWhat happens depends on controller, kernel state, and configuration.

The container remains a container even if no runtime memory ceiling was configured.

Place: process joins its cgroup

OBSERVABLE EVIDENCE
Illustrative cgroup v2: memory.current < memory.max
Namespaces alter views; cgroups account for and constrain resource use.

The kernel charges work to the process’s cgroup. Limits can bound use; without a configured memory limit, a container is not magically assigned a fixed memory budget.

Boundary: Controllers and available limits depend on host cgroup configuration. An OOM event is a kernel decision, not a Docker retry policy.

Failure state: The container still exists, but this cgroup has no configured memory ceiling from the container runtime.

04 / IMAGE AND RUNTIME

A source edit should invalidate only the work it touches

Why does a Dockerfile sometimes reinstall dependencies after a tiny code edit?

LINUX PROCESS LABCHECKPOINT 01 / 04
DOCKERFILEFROM node:22COPY package*.json ./RUN npm ciCOPY server.js ./
AFTER EDITING server.js
BASECACHED
PACKAGE FILESCACHED
INSTALLCACHED
SOURCEREBUILT

Move COPY . . before install and a source edit can invalidate the expensive dependency step.

Base: FROM node:22 remains reusable

OBSERVABLE EVIDENCE
Illustrative Dockerfile: COPY package*.json . / RUN npm ci / COPY . .
Build cache is about inputs to build steps; it is separate from a running container’s writable state.

Build cache reuses a step when its instruction and relevant inputs still match. Copying package files before source files lets a source-only edit reuse the dependency-install result.

Boundary: Modern builders can use mounts and optimizations beyond a one-instruction-one-layer sketch. The diagram shows a useful Dockerfile order, not a storage-driver implementation.

Failure state: A source edit now affects the dependency-install inputs and can trigger avoidable work.

05 / BUILD THE BOUNDARY

An image is a template; a container adds runtime state

Why does a new container not keep the files from a previous one?

LINUX PROCESS LABCHECKPOINT 01 / 05
IMAGE · READ-ONLY INPUT
base runtime node:22
dependencies npm ci
application server.js
container writable state per container
THREE RUNNING INSTANCES
web-aits own writes
web-bseparate writes
web-cseparate writes
app-data volumelifecycle separate from web-a

Removing web-a removes its container-local writes. It does not mutate the image or the other containers; an explicitly managed volume can persist.

Base: node:22 runtime files

OBSERVABLE EVIDENCE
$ docker image history demo-api:1.0
… COPY server.js /srv/server.js
Build output becomes immutable image layers; container-local writes belong to that container’s writable layer.

Images contain ordered filesystem changes. Starting a container adds a writable layer and runtime configuration. A volume is a separately managed mount, not image content.

Boundary: “Immutable” describes image content after it is created. Registries, tags, layers, and storage drivers have their own implementation details.

Failure state: Container-local writable data is removed with the container. Data that must outlive it belongs in an explicit volume or external store.

06 / RUN AND COMMUNICATE

docker run creates, configures, then starts

What does the runtime do between a command and a listening service?

LINUX PROCESS LABCHECKPOINT 01 / 05
REQUESTdocker run -p 8080:3000 demo-api:1.0
DOCKER / RUNTIME

Resolve imageuse local image or pull manifest and layers

Createrecord config and writable layer

Networkattach interface and assign address

CONTAINER

Startexec node server.js as PID 1

Publishoptional host port → container port rule

HOST :8080CONTAINER :3000Port publication is configured; a container port alone does not publish a host listener.

Resolve image: use local image or pull manifest and layers

OBSERVABLE EVIDENCE
$ docker run -p 8080:3000 demo-api:1.0
Server listening on 3000
The image is input; the runtime creates the runnable container and starts its configured process.

Docker resolves an image, creates a container, supplies a writable layer and networking, then starts the configured process. The container remains running only while its main process runs.

Boundary: Docker’s daemon and default bridge are common examples, not the universal container architecture. Other runtimes expose the OCI lifecycle differently.

Failure state: When the main process exits, the container stops. A background child process does not automatically keep the intended workload healthy.

07 / RUN AND COMMUNICATE

Published traffic still crosses several boundaries

How does a client on host port 8080 reach node server.js on port 3000?

LINUX PROCESS LABCHECKPOINT 01 / 04
CLIENThost:8080
HOST RULE:8080 → :3000
ATTACHMENTcontainer network
PROCESSnode :3000
LISTENER SCOPE0.0.0.0:3000 inside containerLoopback-only 127.0.0.1:3000 inside the namespace is a different bind.

Client: connects to host :8080

OBSERVABLE EVIDENCE
Illustrative: host :8080 → container :3000
A published host port and an application listener are separate requirements.

A published port creates a host-side forwarding path into the container network namespace. In a common Linux bridge setup, traffic crosses host rules and a veth attachment before reaching the process listener.

Boundary: Bridge, veth, NAT, and rootless forwarding details depend on the runtime/network driver; the path is a common Linux example.

Failure state: If the app listens only on 127.0.0.1 inside its namespace, the published path to its container address may fail.

08 / OPERATE THE BOUNDARY

Resource limits and lifecycle signals are real boundaries

What happens when the process needs more memory or receives a stop request?

LINUX PROCESS LABCHECKPOINT 01 / 04
PID NAMESPACEPID 1 · node server.js
PID 8 · workerPID 9 · worker
CGROUP MEMORYusage compared with configured limit
01Pressurekernel reclaims or selects a victim
02Stopruntime sends configured termination signal
03ExitPID 1 exits; container stops

A running container is a running process lifecycle. Graceful exit depends on the application handling the configured stop signal and its children.

Limit: memory.max constrains cgroup use

OBSERVABLE EVIDENCE
$ docker stop demo-api
# runtime requests graceful termination
Isolation does not replace capacity planning, safe shutdown, or least-privilege configuration.

A cgroup can account for and limit resources. Container PID 1 receives lifecycle signals and must handle them appropriately; the runtime can later escalate if the process does not exit.

Boundary: Exact OOM selection, signal handling, and runtime stop behavior depend on kernel, runtime, and configured timeout.

Failure state: The process ignores or mishandles the graceful signal. After the configured grace period, the runtime may force termination.

09 / SECURITY AND DISTRIBUTION

Isolation and security controls address different risks

What can a compromised process still do if the container is poorly configured?

LINUX PROCESS LABCHECKPOINT 01 / 04
node server.jsuntrusted input can reach this process
NAMESPACE VIEWwhich resources are visible?
CAPABILITIESwhich privileged operations?
SECCOMP / LSMwhich syscalls and accesses?
HOST MOUNTSwhich host paths can be touched?
Privileged mode or broad writable host mounts can reopen paths these controls were meant to close.

Namespace: separate selected views

OBSERVABLE EVIDENCE
Illustrative controls: cap-drop, read-only rootfs, restricted mounts
Treat the container as a configured process boundary, and reduce privileges and host access deliberately.

Namespaces limit what the process sees; capabilities, seccomp, Linux security modules, user mappings, and mount policy reduce what it may do. Host mounts and privileged mode can reopen dangerous paths.

Boundary: No single switch makes a container fully secure. The effective boundary depends on kernel, runtime, user privileges, filesystem mounts, and workload needs.

Failure state: A broad writable host mount gives the process access outside its intended filesystem boundary.

10 / SECURITY AND DISTRIBUTION

An image digest travels from build to deployment

What gets pushed and pulled when this app moves to another host?

LINUX PROCESS LABCHECKPOINT 01 / 05
01Buildproduce manifest, config, and layers
02Tagname demo-api:1.0
03Pushpublish content to registry
04Pullresolve manifest/digest on target host
05Runstart a new container from that image
TAG · demo-api:1.0Digest · sha256:4ad7…91c2Tag can move; digest names content.

Build: produce manifest, config, and layers

OBSERVABLE EVIDENCE
Illustrative image reference: demo-api:1.0@sha256:4ad7…91c2
Use tags to discover versions and digests to identify exact image content.

The builder emits image metadata and content-addressed layers. A tag is a human-friendly pointer that can move; the digest identifies specific content. The runtime pulls the relevant manifest and layers before creating a container.

Boundary: Multi-platform indexes can point to platform-specific manifests. A pull selects content for the target platform rather than downloading every platform image.

Failure state: If a tag is repointed, two pulls at different times can resolve different content unless a digest is pinned.

11 / OPERATE AND COMPARE

Find the failing boundary before rebuilding the image

Why does the container show “running” while callers still fail?

LINUX PROCESS LABCHECKPOINT 01 / 05
01Processis PID 1 still running?
02Listeneris app bound to the container address?
03Publishdoes host :8080 map to :3000?
04Resourcecheck cgroup/OOM events
05Storagecheck mount paths and permissions
EXAMPLE TRAPContainer running · callers time outApplication bound only to 127.0.0.1 inside the namespace.

Process: is PID 1 still running?

OBSERVABLE EVIDENCE
Illustrative checks: docker ps / docker logs / ss -ltn / cgroup events
Inspect process, listener, network path, mounts, and resource events as separate claims.

A running PID 1 proves that a process exists. It does not prove that the app listens on the right address, that the port is published, or that the container has permission and memory to answer.

Boundary: Example commands and output vary by runtime and host network driver. Treat this as a diagnostic order, not a universal CLI transcript.

Failure state: The process is healthy but listens only inside its own loopback; traffic forwarded to the container address cannot reach that listener.

12 / OPERATE AND COMPARE

Containers and VMs isolate at different layers

Where does the kernel boundary sit in each model?

LINUX PROCESS LABCHECKPOINT 01 / 04
CONTAINERapp processnamespaces + cgroupsshared HOST KERNEL
VIRTUAL MACHINEapp processguest operating systemGUEST KERNEL
CLOUD HOST → VM → many containers → one guest kernel

The layers are often combined; this comparison shows kernel ownership, not a blanket security rating.

Container: app process shares host kernel

OBSERVABLE EVIDENCE
Model comparison: host kernel versus guest kernel
A container isolates a process context; a VM supplies a separate guest operating system and kernel.

A Linux container runs host-kernel-scheduled processes with isolated views. A VM runs a guest kernel over virtualized hardware. They are often stacked together in cloud environments.

Boundary: Strong isolation depends on implementation and configuration. This comparison is architectural, not a blanket security ranking.

Failure state: Broad host privileges can weaken the intended container boundary; the presence of a container label alone is not a security guarantee.