What is Docker — Simple Explanation with Examples
Docker is a platform for developing, shipping, and running applications inside containers — lightweight, standalone executable packages that include everything needed to run the software: code, runtime, system tools, libraries, and settings.
What You’ll Learn
This article covers the core Docker concepts, shows how to write a Dockerfile and use Docker Compose, compares containers to virtual machines, and explains why Docker is essential for modern development. Docker is used by millions of developers daily and is the de facto standard for containerization.
The Problem Docker Solves
“It works on my machine” is the oldest excuse in software. The problem is environment inconsistency:
- Your laptop runs macOS; production runs Linux.
- You have Python 3.11 installed; the server has 3.9.
- You installed a dependency globally; the new team member does not know which one.
- Your app needs a specific version of PostgreSQL; the server has a different one.
Docker solves this by bundling the application with its environment. A Docker container runs identically on your laptop, your teammate’s machine, a CI server, and a production cluster.
The Shipping Container Analogy
Before standardized shipping containers, cargo was loaded and unloaded piece by piece, with each port using its own format. It was slow, error-prone, and incompatible across transport modes.
Shipping containers changed everything: goods are packed once into a standard box (container), then moved seamlessly across trucks, trains, and ships regardless of the contents.
Docker containers are the same idea for software:
- You pack your app (goods) into a container (standard box).
- The container moves from dev laptop (truck) to CI server (train) to production (ship).
- It works everywhere without repacking because the container includes everything needed.
Container vs Virtual Machine
| Aspect | Virtual Machine | Docker Container |
|---|---|---|
| OS | Full guest OS per VM | Shares host OS kernel |
| Startup | Minutes | Seconds |
| Size | GBs per VM | MBs per container |
| Isolation | Hardware-level | Process-level (namespaces) |
| Performance | Near-native (with overhead) | Native |
| Portability | Hypervisor-dependent | Runs anywhere Docker runs |
Containers are not lightweight VMs. They share the host kernel and isolate processes using Linux namespaces and cgroups. This makes them much faster to start and more resource-efficient.
Dockerfile Example
A Dockerfile is a recipe for building a container image. Here is one for a simple Python web app:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]Build and run:
# Build the image
docker build -t my-web-app .
# Run a container from the image
docker run -d -p 5000:5000 --name my-app my-web-app
# Check running containers
docker ps
# Expected output:
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# a1b2c3d4e5f6 my-web-app "python app.py" 5 seconds ago Up 4 seconds 0.0.0.0:5000->5000/tcp my-appDocker Compose Example
Docker Compose lets you define and run multi-container applications. A web app with PostgreSQL:
version: "3.9"
services:
web:
build: .
ports:
- "5000:5000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/myapp
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:# Start all services
docker compose up -d
# Expected output:
# [+] Running 3/3
# ✔ Network myapp_default Created
# ✔ Container myapp-db-1 Started
# ✔ Container myapp-web-1 Started
# View logs
docker compose logs -f
# Stop everything
docker compose downImage Registry
Docker images are stored in registries. The default public registry is Docker Hub. You can also use private registries (AWS ECR, Google Artifact Registry, GitHub Container Registry).
# Tag an image for a registry
docker tag my-web-app ghcr.io/myusername/my-web-app:v1.0.0
# Push to registry
docker push ghcr.io/myusername/my-web-app:v1.0.0
# Pull and run on another machine
docker pull ghcr.io/myusername/my-web-app:v1.0.0
docker run -d -p 5000:5000 ghcr.io/myusername/my-web-app:v1.0.0Common Docker Commands
| Command | Purpose |
|---|---|
docker build -t name . | Build an image |
docker run -d -p 80:3000 image | Run a container in detached mode |
docker ps | List running containers |
docker ps -a | List all containers (including stopped) |
docker stop <id> | Stop a running container |
docker rm <id> | Remove a container |
docker rmi <image> | Remove an image |
docker logs -f <id> | Stream container logs |
docker exec -it <id> bash | Open a shell inside a running container |
docker compose up -d | Start all services in compose file |
docker compose down | Stop and remove all compose services |
Common Use Cases
Development environments — New team members clone the repo, run
docker compose up, and have a fully working development environment without installing databases, queues, or specific language versions.Microservices — Each service in a microservice architecture is packaged as a Docker image. Services run in containers orchestrated by Kubernetes.
CI/CD pipelines — CI runners build Docker images, run tests inside containers, and push images to registries. The same image flows through staging to production.
Isolated testing — Run integration tests against real databases, message queues, and caches — all spun up and torn down via Docker Compose in seconds.
Legacy application portability — Package legacy applications with their specific (often outdated) dependencies into containers and run them on modern infrastructure without conflicts.
FAQ
Related Terms
What is Kubernetes — What is a Microservice — What is CI/CD — What is an API
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro