What is a Container?
A container is an isolated process running on a host OS. Unlike a VM which virtualises the entire hardware stack, a container shares the host OS kernel but has its own isolated filesystem, network, and process space. This makes containers extremely lightweight — they start in seconds, use megabytes of memory, and can run thousands on a single host.
Containers vs Virtual Machines
| Virtual Machine | Container | |
|---|---|---|
| Includes | Full OS + application | Application + dependencies only |
| Size | Gigabytes | Megabytes |
| Startup time | Minutes | Seconds (often milliseconds) |
| OS kernel | Own kernel per VM | Shared host kernel |
| Isolation | Strong — hardware-level | Good — process-level |
| Density | Tens per host | Hundreds or thousands per host |
| Best for | Full OS control, legacy apps, strong isolation | Microservices, scaling, consistent deployments |
Container Images and Layers
A container image is a read-only template used to create containers. Images are built in layers — each instruction in a Dockerfile adds a new layer. Layers are cached and shared between images, making storage efficient.
- Base layer — The OS foundation (e.g., Ubuntu, Alpine, Windows Server Core)
- Dependency layers — Runtime, packages, libraries
- Application layer — Your actual code
- Config layer — Environment variables, exposed ports
The Dockerfile
A Dockerfile is a text file with instructions to build a container image:
# Start from official Node.js base image
FROM node:20-alpine
# Set working directory inside container
WORKDIR /app
# Copy package files and install dependencies
COPY package*.json ./
RUN npm install --production
# Copy application code
COPY . .
# Expose port 3000
EXPOSE 3000
# Command to run when container starts
CMD ["node", "server.js"]
Container Lifecycle
| Stage | Command | Description |
|---|---|---|
| Build image | docker build -t myapp:v1 . | Create image from Dockerfile |
| Push to registry | docker push myregistry/myapp:v1 | Upload image to container registry |
| Pull image | docker pull myregistry/myapp:v1 | Download image from registry |
| Run container | docker run -p 3000:3000 myapp:v1 | Start a container from the image |
| Stop container | docker stop mycontainer | Gracefully stop a running container |
| Remove container | docker rm mycontainer | Delete a stopped container |
Why Containers Matter
- Consistency — Same image runs identically in dev, test, and production
- Speed — Start in milliseconds vs minutes for VMs
- Density — Pack hundreds of containers on one host
- Microservices — Each service in its own container, independently deployable
- CI/CD — Build once, deploy anywhere — perfect for automated pipelines
- Portability — Run on any cloud, any on-premises server, any developer machine
Key Terminology
| Term | Definition |
|---|---|
| Image | Read-only template — the blueprint for a container |
| Container | A running instance of an image |
| Dockerfile | Instructions to build an image |
| Registry | Storage for container images (Docker Hub, Azure Container Registry) |
| Tag | Version label for an image (e.g., myapp:v1, myapp:latest) |
| Docker | The most popular container runtime |
| Orchestrator | Tool to manage many containers (Kubernetes, Azure Container Apps) |