Docker is the most popular containerization tool in the world. According to the 2025 Stack Overflow Developer Survey, Docker is one of the most widely used tools among professional developers, with usage continuing to grow year-over-year.

But what is Docker? And how is it different from a virtual machine?

In this tutorial, you will learn what Docker is, how containers work, and why developers use Docker for everything from local development to production deployments.

The Problem Docker Solves

You have probably heard this before:

“It works on my machine.”

A developer builds an app on their laptop. It runs fine locally. But when they deploy it to the server, it breaks. Maybe the server has a different version of Python. Maybe a library is missing. Maybe the environment variables are different.

This is a very common problem. Docker solves it.

What is a Container?

A container is an isolated environment that packages your application and everything it needs to run: code, libraries, environment variables, and configuration files.

When you run your app in a container, it behaves the same way everywhere — your laptop, your colleague’s laptop, the CI/CD server, and the production server.

Think of a container like a shipping container. A shipping container holds goods and can be loaded onto any ship, truck, or train. It does not matter what vehicle carries it. The goods inside stay safe and intact.

What is Docker?

Docker is the tooling layer that makes containers easy to create, run, and manage.

Docker has three main parts:

  • Docker Engine — the runtime that creates and runs containers. Runs on Linux, macOS, and Windows.
  • Docker CLI — the command-line tool you use to interact with Docker (docker run, docker build, etc.)
  • Docker Desktop — a GUI app for macOS and Windows that includes Docker Engine, Docker CLI, and extra tools.

In 2026, Docker Engine is at version 29+. A key change in v29: it now uses the containerd image store by default for fresh installs. Containerd is the industry-standard container runtime, and this change makes Docker more compatible with Kubernetes and other tools.

Containers vs Virtual Machines

This is the most important concept to understand.

Virtual Machines (VMs)

A virtual machine simulates an entire computer. It has its own operating system, kernel, and hardware. A hypervisor (like VMware or VirtualBox) runs on the host machine and manages the VMs.

Host Machine
├── Host OS
└── Hypervisor
    ├── VM 1: Guest OS + App A
    ├── VM 2: Guest OS + App B
    └── VM 3: Guest OS + App C

VMs are isolated and secure. But they are heavy. Each VM can use gigabytes of RAM just for the guest OS. Starting a VM takes minutes.

Containers

A container does not have its own operating system. It shares the host kernel directly. This makes containers much lighter than VMs.

Host Machine
├── Host OS (Linux kernel)
└── Docker Engine
    ├── Container 1: App A (no OS)
    ├── Container 2: App B (no OS)
    └── Container 3: App C (no OS)

The key difference: containers share the host kernel. VMs have their own kernel.

This is why containers start in milliseconds instead of minutes. And why a container might use 50 MB of RAM instead of 1 GB.

Side-by-Side Comparison

FeatureContainerVirtual Machine
Startup timeMillisecondsMinutes
SizeMegabytesGigabytes
OS overheadNone (shared kernel)Full guest OS
IsolationProcess-levelHardware-level
PortabilityVery highHigh but heavier
Use caseApp deployment, dev environmentsFull OS isolation, legacy apps

How Docker Works: The Core Workflow

Docker has three main concepts: Dockerfile, image, and container.

Dockerfile → docker build → Image → docker run → Container
  1. Dockerfile — a text file with instructions to build your app’s environment
  2. Image — a read-only template built from the Dockerfile (like a class in OOP)
  3. Container — a running instance of an image (like an object created from a class)

Here is a simple example. This Dockerfile packages a Python web app:

# Start from the official Python base image
FROM python:3.13-slim

# Set the working directory inside the container
WORKDIR /app

# Copy dependency list first (for layer caching)
COPY requirements.txt .

# Install dependencies
RUN pip install -r requirements.txt

# Copy the rest of the code
COPY . .

# Start the app
CMD ["python", "app.py"]

You build this into an image:

docker build -t myapp:1.0 .

Then run a container from that image:

docker run -p 8080:8080 myapp:1.0

Your app is now running in an isolated container. It will behave the same way on every machine that has Docker installed.

Where Docker is Used

Docker is used everywhere in modern software development:

  • Local development — run databases, message queues, and services locally without installing them
  • CI/CD pipelines — build and test code in a clean, reproducible environment on every commit
  • Microservices — each service runs in its own container, isolated from others
  • Cloud deployment — container images deploy to AWS, Google Cloud, Azure, or any cloud
  • Kubernetes — K8s orchestrates hundreds of containers across many machines (covered later in this series)

Docker’s 2026 Landscape

Docker has evolved a lot in recent years:

  • Docker Engine v29 — containerd image store as default, nftables firewall support (opt-in)
  • Docker Desktop 4.64+ — includes built-in Kubernetes 1.34.3, Docker Scout for image scanning
  • Docker MCP Toolkit — launched in beta 2025, lets AI agents interact with Docker containers
  • Docker Hardened Images — pre-hardened base images with minimal attack surface

Docker vs Podman

Docker is not the only containerization tool. Podman is a popular alternative, especially on Red Hat/Fedora Linux systems.

Key differences:

  • Podman is daemonless — no background service required. Docker runs a daemon (dockerd).
  • Podman runs containers rootless by default. Docker traditionally required root (though rootless Docker is now available).
  • Podman is Docker-compatible — most docker commands work with podman by aliasing.

For this series, we use Docker. But if you are on RHEL/Fedora or prefer a daemonless setup, Podman is a solid choice with the same concepts.

Common Mistakes

Thinking containers are “lightweight VMs”

They are not. VMs virtualize hardware. Containers virtualize the OS process layer. Containers share the host kernel. This is why they are so fast and lightweight — and also why a Linux container needs a Linux kernel to run.

Confusing Docker with containers

Docker is the toolset. Containers are the technology. You can run containers without Docker (using containerd directly, or Podman). But Docker makes it easy.

Forgetting that containers are ephemeral

When a container stops, any data written inside it is lost. To persist data, you need volumes. We cover this in Docker Tutorial #6: Volumes and Networking.

What’s Next?

Now you understand what Docker is. The next step is to install it.

Next: Docker Tutorial #2: How to Install Docker (Desktop + Engine)