The "It Works on My Machine" Problem
Every developer has experienced it: code that runs perfectly locally crashes in staging. The culprit is usually an environment difference — a different OS, a different version of a runtime, a missing environment variable. Docker solves this by packaging your application and everything it needs into a single, portable unit called a container.
What Is Docker?
Docker is a platform for building, running, and sharing containers. A container is a lightweight, isolated process that includes the application code, runtime, libraries, and configuration — but shares the host OS kernel. This makes containers:
- Portable: Runs the same everywhere — laptop, CI server, cloud
- Fast to start: Seconds, not minutes like a VM
- Consistent: Eliminates environment drift between machines
- Lightweight: Multiple containers share one OS
Core Concepts You Need to Know
- Image: A read-only blueprint for a container (think: a recipe)
- Container: A running instance of an image (think: the dish you cooked)
- Dockerfile: A text file with instructions to build an image
- Registry: A storage service for images (Docker Hub is the public default)
- docker-compose: A tool for running multiple containers together
Step 1: Install Docker
Download and install Docker Desktop from docker.com. It includes the Docker engine, CLI, and Docker Compose. Verify the install:
docker --version
docker run hello-world
If hello-world prints a success message, Docker is working.
Step 2: Write a Dockerfile
Create a simple Python Flask app and a Dockerfile side by side:
# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello from Docker!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
# Dockerfile
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"]
Your requirements.txt should contain: flask
Step 3: Build and Run Your Container
# Build the image, tag it "my-flask-app"
docker build -t my-flask-app .
# Run it, mapping port 5000 on host to 5000 in container
docker run -p 5000:5000 my-flask-app
Visit http://localhost:5000 — your app is running inside a container.
Step 4: Use Docker Compose for Multi-Container Apps
Real apps often need a database alongside the app. Docker Compose manages this with a single file:
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
Start everything with: docker compose up. Tear it down with: docker compose down.
Essential Docker Commands
docker ps— List running containersdocker images— List local imagesdocker logs <container>— View container outputdocker exec -it <container> bash— Open a shell inside a containerdocker stop <container>— Stop a running container
Next Steps
Once you're comfortable with the basics, explore multi-stage builds for smaller images, Docker volumes for persistent data, and orchestration with Kubernetes for production deployments. Docker is a foundational skill in modern DevOps — invest time here and it pays dividends across every project.