Every container shares the host's kernel (How Linux Isolates), so isolation is a stack of kernel features rather than a hardware boundary: namespaces limit what a process sees, cgroups what it consumes, capabilities and seccomp what it may ask the kernel to do, and an LSM such as AppArmor 454,622 or SELinux 1,634 what files it may touch. A kernel bug that one system call can reach bypasses all of them, which is why multi-tenant platforms add a sandbox (gVisor 482,968 ) or a micro-VM (Kata Containers 533,613 , Firecracker 126 ) beneath. The biggest single risk is simpler: UID 0 in a container is UID 0 on the host kernel unless user namespaces remap it (User Namespaces). Check who each of BookNest's images runs as:
for i in alpine:3 l3-booknest-api:latest l3-booknest-web:latest postgres:18; do
printf '%-24s %s\n' "$i" "$(docker run --rm --entrypoint id "$i" -un)"; donealpine:3 root l3-booknest-api:latest node l3-booknest-web:latest root postgres:18 root
Only the API image, with its USER 1000:1000 (Non-Root User), starts unprivileged. Nginx 75 and PostgreSQL 1,289 start as root and drop to their own users for the work, so their master processes still hold root's powers:

Each layer removes a class of attack even when another fails. The images are the other half of the model: their vulnerable packages and leaked secrets run with whatever privileges remain (Docker Scout to Secrets in Images).