Overview

Docker solves a classic problem: “It works on my machine, but not on yours.” This tutorial explains the core concepts, shows the most useful commands, and walks through containerizing a Python Flask application.

What Docker Solves

  • Environment inconsistency between development, testing, and production
  • Slow and error-prone manual server setup
  • Virtual machines waste resources because each one needs a full OS

Docker packages an application and all its dependencies into a standard container that runs consistently anywhere Docker is installed.

Core Concepts

ConceptDescriptionAnalogy
ImageA read-only template containing everything needed to run an appLike an ISO installer
ContainerA running instance of an image with its own filesystem, network, and process spaceLike a very lightweight VM
DockerfileA text file that defines how to build an imageLike a Makefile
RegistryA service for storing and distributing imagesLike GitHub for images

Install Docker

Ubuntu

sudo apt update
sudo apt install docker.io
sudo systemctl enable --now docker

CentOS

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo \
  https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io
sudo systemctl start docker

macOS and Windows

Download Docker Desktop from the Docker Desktop official site. Windows users should enable WSL2.

Verify Installation

docker --version
docker run hello-world

Essential Docker Commands

Image Commands

CommandPurpose
docker pull nginx:latestPull an image
docker imagesList local images
docker rmi image_idRemove an image
docker build -t myapp:v1 .Build an image

Container Commands

CommandPurpose
docker run -d -p 8080:80 nginxRun a container in the background with port mapping
docker psList running containers
docker ps -aList all containers, including stopped ones
docker stop container_idStop a container
docker rm container_idRemove a container
docker logs container_idView container logs
docker exec -it container_id bashOpen a shell inside a container

Build a Flask App with Docker

Step 1: Create the Application

# 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)

Step 2: Create a 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"]

Step 3: Create requirements.txt

flask==3.0.0

Step 4: Build the Image

docker build -t my-flask-app:v1 .

Step 5: Run the Container

docker run -d -p 5000:5000 --name myapp my-flask-app:v1

Visit http://localhost:5000 to see “Hello from Docker!”

Docker Compose Overview

When an app needs multiple services, Docker Compose defines them in a YAML file:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - db
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

Start all services with docker compose up -d and stop them with docker compose down.

Common Beginner Problems

ProblemSolution
Need sudo for every Docker commandsudo usermod -aG docker $USER && newgrp docker
Data disappears after container stopsUse a volume with -v
Code changes not reflected in imageReorder COPY steps in the Dockerfile or build with --no-cache
Port already in useChange the host port, for example -p 8080:5000