Overview
A container packages an application with its dependencies (runtime, libraries, config) into an isolated unit that runs the same way everywhere. Unlike a virtual machine, a container shares the host's operating system kernel and isolates processes using Linux namespaces (what it can see) and cgroups (what it can use), so it starts in milliseconds and uses far less overhead.
Containers solved 'works on my machine' and made microservices practical: each service ships as an image, is versioned, and can be deployed, scaled, and rolled back independently. Orchestrators like Kubernetes run and manage thousands of containers across clusters.
Before standard shipping containers, every cargo type needed special handling. Standard boxes fit any ship, train, or truck. Software containers are standard boxes for applications: any host with a container runtime can run them.
When to use it
- Consistent environments from development to production.
- Microservices and independent deployments.
- Dense packing of many services on shared hosts.
- Reproducible CI builds and tests.
Where it shows up in interviews
Recognize it when: how do services get packaged and deployed?
- Design a CI/CD pipeline
- Design a microservices platform
Where it is used in real software
Popularized containers in 2013 with a simple image format and tooling.
Google has run everything in containers for over a decade, launching billions per week; Kubernetes grew from these ideas.
The Open Container Initiative defines image and runtime specs used by Docker, containerd, and Podman.
Key terms
- Image
- Immutable layered template of filesystem and metadata.
- Container
- A running instance of an image.
- Namespaces
- Isolate process IDs, network, mounts, users.
- cgroups
- Limit CPU, memory, and I/O per container.
- Registry
- Stores and distributes images.
How it works, step by step
- 1Write a Dockerfile
Base image, dependencies, app code, start command.
- 2Build the image
Layers are cached for fast rebuilds.
- 3Push to a registry
Tagged with a version or commit SHA.
- 4Run anywhere
Laptop, CI, Kubernetes, ECS.
- 5Limit and observe
Set CPU and memory limits, collect logs and metrics.
Containers vs virtual machines
Isolation models
| Aspect | Container | Virtual machine |
|---|---|---|
| Isolation boundary | Process (shared kernel) | Hardware virtualization (own kernel) |
| Startup time | Milliseconds to seconds | Tens of seconds to minutes |
| Size | MBs | GBs |
| Density per host | Hundreds | Tens |
| Security isolation | Weaker (shared kernel) | Stronger |
NOWAspect: Isolation boundary | Container: Process (shared kernel) | Virtual machine: Hardware virtualization (own kernel)
Many clouds combine both: containers run inside lightweight VMs (Firecracker, gVisor) for stronger isolation.
Implementation
# Base images from the internal registry mirrorFROM containers.artifactory.tools.bestbuy.com/node:22-alpine AS buildWORKDIR /appCOPY package*.json ./RUN npm ciCOPY . .RUN npm run build FROM containers.artifactory.tools.bestbuy.com/node:22-alpineWORKDIR /appENV NODE_ENV=productionCOPY --from=build /app/package*.json ./RUN npm ci --omit=devCOPY --from=build /app/dist ./dist# Do not run as rootUSER nodeEXPOSE 3000CMD ["node", "dist/server.js"]Complexity and performance
Depends on image and app.
No guest OS.
Trade-offs
Sharing a kernel is efficient but a kernel exploit can affect all containers; sandboxed runtimes add isolation.
Containers are ephemeral; state must live in volumes or external services.
Variants and related techniques
Alternative runtimes and tools.
Firecracker powers Lambda and Fargate with VM-level isolation and fast startup.
Common mistakes
- Running as root.
Fix: Use a non-root user and read-only filesystems.
- Storing data inside the container filesystem.
Fix: It disappears on restart; use volumes or external storage.
- Using the latest tag in production.
Fix: Pin versions or digests for reproducibility.
Interview questions
How do containers differ from VMs?
Containers isolate processes on a shared host kernel using namespaces and cgroups, so they are lightweight and start quickly; VMs virtualize hardware and run a full guest OS, giving stronger isolation at more overhead.
Why are containers good for microservices?
Each service is packaged with its dependencies into an immutable image that can be versioned, deployed, scaled, and rolled back independently and run consistently in every environment.
Practice problems
| Problem | Difficulty | What it trains |
|---|---|---|
| Containerize a Node API | Easy | Dockerfile. |
| Harden a container image | Medium | Non-root, minimal base, scanning. |