Learning Guides
Menu

Introduction to Docker

8 min readDocker for Developers

Introduction to Docker

Docker has revolutionized how developers build, ship, and run applications. Before diving into commands and configurations, it's essential to understand what containers are, how they differ from virtual machines, and why Docker became the dominant containerization platform.

What Is a Container?

A container is a lightweight, standalone, executable package that includes everything needed to run a piece of software: code, runtime, system tools, libraries, and settings. Containers isolate software from its environment, ensuring consistent behavior across different computing environments.

Note

Think of a container as a shipping container for software. Just like physical shipping containers standardized global trade by providing a consistent way to transport goods, software containers standardize application deployment.

The Problem Docker Solves

"It Works on My Machine"

Before containers, developers faced a common frustration: code that worked perfectly on their development machine would fail in staging or production. This happened because environments differed in:

  • Operating system versions
  • Library versions and dependencies
  • Configuration settings
  • Runtime environments
BASH
# The classic developer excuse
"But it works on my machine!"

Environment Inconsistency

Consider a Node.js application that requires:

  • Node.js 20.x
  • npm packages with specific versions
  • Environment variables for configuration
  • System libraries like ImageMagick

Getting all of this exactly right across development, staging, and production machines was error-prone and time-consuming.

Traditional Deployment Challenges

EnvironmentNode Versionnpm VersionImageMagickResult
Developer A20.11.010.2.47.1.1✅ Works
Developer B18.19.09.8.17.0.0❌ Fails
Staging20.10.010.2.3Not installed❌ Fails
Production20.11.010.2.46.9.12⚠️ Partial

Docker solves this by packaging the application with its environment, guaranteeing identical behavior everywhere.

Containers vs Virtual Machines

While both containers and virtual machines (VMs) provide isolation, they work fundamentally differently.

Virtual Machines

VMs run a complete operating system on top of a hypervisor. Each VM includes:

  • Full guest operating system (GB of storage)
  • Virtualized hardware
  • Complete system resources allocation
PLAINTEXT
┌─────────────────────────────────────────────────────────┐
│                    Host Operating System                 │
├─────────────────────────────────────────────────────────┤
│                       Hypervisor                         │
├─────────────┬─────────────┬─────────────┬───────────────┤
│    VM 1     │    VM 2     │    VM 3     │    VM 4       │
│  ┌───────┐  │  ┌───────┐  │  ┌───────┐  │  ┌───────┐    │
│  │ App A │  │  │ App B │  │  │ App C │  │  │ App D │    │
│  └───────┘  │  └───────┘  │  └───────┘  │  └───────┘    │
│  ┌───────┐  │  ┌───────┐  │  ┌───────┐  │  ┌───────┐    │
│  │ Bins/ │  │  │ Bins/ │  │  │ Bins/ │  │  │ Bins/ │    │
│  │ Libs  │  │  │ Libs  │  │  │ Libs  │  │  │ Libs  │    │
│  └───────┘  │  └───────┘  │  └───────┘  │  └───────┘    │
│  ┌───────┐  │  ┌───────┐  │  ┌───────┐  │  ┌───────┐    │
│  │Guest  │  │  │Guest  │  │  │Guest  │  │  │Guest  │    │
│  │  OS   │  │  │  OS   │  │  │  OS   │  │  │  OS   │    │
│  └───────┘  │  └───────┘  │  └───────┘  │  └───────┘    │
└─────────────┴─────────────┴─────────────┴───────────────┘

Containers

Containers share the host OS kernel and run as isolated processes. They include:

  • Only the application and its dependencies
  • Minimal filesystem layers (MB instead of GB)
  • Shared kernel resources
PLAINTEXT
┌─────────────────────────────────────────────────────────┐
│                    Host Operating System                 │
├─────────────────────────────────────────────────────────┤
│                      Docker Engine                       │
├─────────────┬─────────────┬─────────────┬───────────────┤
│ Container 1 │ Container 2 │ Container 3 │ Container 4   │
│  ┌───────┐  │  ┌───────┐  │  ┌───────┐  │  ┌───────┐    │
│  │ App A │  │  │ App B │  │  │ App C │  │  │ App D │    │
│  └───────┘  │  └───────┘  │  └───────┘  │  └───────┘    │
│  ┌───────┐  │  ┌───────┐  │  ┌───────┐  │  ┌───────┐    │
│  │ Bins/ │  │  │ Bins/ │  │  │ Bins/ │  │  │ Bins/ │    │
│  │ Libs  │  │  │ Libs  │  │  │ Libs  │  │  │ Libs  │    │
│  └───────┘  │  └───────┘  │  └───────┘  │  └───────┘    │
└─────────────┴─────────────┴─────────────┴───────────────┘

Containers vs VMs Comparison

CharacteristicVirtual MachineContainer
SizeGigabytesMegabytes
Startup TimeMinutesSeconds
PerformanceOverhead from hypervisorNear-native
IsolationStrong (hardware-level)Process-level
OS FlexibilityAny OSSame kernel family
Resource UsageHigherLower
DensityTens per hostHundreds per host

Docker Architecture

Docker uses a client-server architecture with several key components:

Docker Daemon (dockerd)

The Docker daemon runs on the host machine and manages Docker objects:

  • Images
  • Containers
  • Networks
  • Volumes
BASH
# The daemon listens for Docker API requests
# Usually runs as a background service
sudo systemctl status docker

Docker Client (docker)

The Docker client is the primary way users interact with Docker. When you run commands like docker run, the client sends them to the daemon:

BASH
# The client communicates with the daemon via REST API
docker run hello-world

Docker Registry

Registries store Docker images. Docker Hub is the default public registry, but you can run private registries:

BASH
# Pulling an image from Docker Hub
docker pull nginx:latest
 
# Pulling from a private registry
docker pull myregistry.example.com/myapp:1.0

Docker Objects

Docker manages several types of objects:

Images: Read-only templates used to create containers. Images are built in layers, where each layer represents a set of filesystem changes.

Containers: Runnable instances of images. You can create, start, stop, move, or delete containers using the Docker API or CLI.

Networks: Enable containers to communicate with each other and the outside world.

Volumes: Persist data generated by containers.

Warning

Containers are ephemeral by default. When a container is deleted, any data stored inside it is lost. Always use volumes for data that needs to persist.

The Container Lifecycle

Understanding the container lifecycle is crucial for working effectively with Docker:

PLAINTEXT
┌─────────┐   create   ┌─────────┐   start   ┌─────────┐
│ Image   │ ─────────▶ │ Created │ ─────────▶│ Running │
└─────────┘            └─────────┘           └────┬────┘

                    ┌─────────────────────────────┤
                    │         stop                │ pause
                    ▼                             ▼
              ┌─────────┐                  ┌──────────┐
              │ Stopped │                  │  Paused  │
              └────┬────┘                  └──────────┘
                   │ remove

              ┌─────────┐
              │ Deleted │
              └─────────┘

Container States

StateDescription
CreatedContainer exists but hasn't been started
RunningContainer is executing with an active process
PausedContainer processes are suspended
StoppedContainer has exited (process completed/killed)
DeletedContainer has been removed from the system

Why Docker for Development?

Docker offers several compelling benefits for developers:

Reproducible Environments

DOCKERFILE
# This Dockerfile defines exactly what your app needs
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["npm", "start"]

Every developer, CI server, and production environment uses the same image.

Isolation

Run multiple projects with different (even conflicting) dependencies simultaneously:

BASH
# Project A needs Node 18
docker run -d --name project-a node:18-alpine tail -f /dev/null
 
# Project B needs Node 20
docker run -d --name project-b node:20-alpine tail -f /dev/null
 
# Both coexist happily on the same machine

Microservices Architecture

Docker makes it practical to decompose applications into services:

YAML
# docker-compose.yml
services:
  frontend:
    image: myapp-frontend:1.0
  api:
    image: myapp-api:1.0
  database:
    image: postgres:16
  cache:
    image: redis:7

Quick Onboarding

New team members can get a development environment running in minutes instead of hours or days:

BASH
# Instead of a 10-page setup document...
git clone https://github.com/company/project.git
cd project
docker compose up
# Done! The entire stack is running.

Docker Ecosystem

Docker has a rich ecosystem of tools and services:

Docker Desktop

A desktop application for Mac and Windows that includes:

  • Docker Engine
  • Docker CLI
  • Docker Compose
  • Kubernetes
  • GUI for managing containers

Docker Hub

The default public registry with millions of images:

  • Official images maintained by Docker and vendors
  • Community images contributed by developers
  • Automated builds from GitHub repositories

Docker Compose

A tool for defining multi-container applications:

BASH
# Start all services defined in docker-compose.yml
docker compose up -d
 
# View running services
docker compose ps
 
# Stop everything
docker compose down

Container Orchestration

For production deployments at scale:

  • Kubernetes: The industry-standard orchestrator
  • Docker Swarm: Docker's native clustering solution
  • Amazon ECS: AWS's container service
  • Azure Container Apps: Microsoft's serverless container platform

Note

While this guide focuses on Docker, the skills you learn here transfer directly to Kubernetes and other orchestrators—they all run containers built with Docker.

What You'll Learn

This guide covers the complete Docker development workflow:

  1. Getting Started: Installing Docker and running your first containers
  2. Images: Building and managing Docker images
  3. Dockerfile Mastery: Writing efficient, secure Dockerfiles
  4. Networking: Connecting containers and exposing services
  5. Data Persistence: Managing volumes and persistent storage
  6. Docker Compose: Orchestrating multi-container applications
  7. Development Workflows: Hot reloading, debugging, and productivity
  8. Security: Best practices for secure containers
  9. Production: Deploying containers in production environments
  10. CI/CD: Integrating Docker into your development pipeline

By the end, you'll have the skills to containerize any application and run it confidently from development to production.