Docker Crash Course

Written by

Docker Foundations

📌 What is Docker?

Docker is a platform for developing, shipping, and running applications in lightweight, isolated environments called containers.

Think of containers like mini-virtual machines—but way faster and more efficient.


🛠️ Basic Concepts

  • Image: A snapshot of your application + environment (code, dependencies, OS).
  • Container: A running instance of an image.
  • Dockerfile: Script to build Docker images.
  • Docker Hub: A public registry of images (like GitHub for Docker).

📦 Installing Docker


🧪 Your First Commands

# Check Docker is installed
docker --version

# Run a container
docker run hello-world

# List running containers
docker ps

# List all containers (even stopped)
docker ps -a

# Stop a container
docker stop <container_id>

# Remove a container
docker rm <container_id>

🏗️ Building Your First Image

Create a app.py file

print("Hello")
  1. Create a Dockerfile:
Use official Python image
FROM python:3.10-slim

# Set working directory
WORKDIR /app

# Copy your code from where is run docker build to working directory
COPY . .

# Install dependencies
RUN pip install -r requirements.txt

# Run the app
CMD ["python", "app.py"]
  1. Build the image:
docker build -t my-python-app .
  1. Run it:
docker run -p 4000:5000 my-python-app .  # create a mapping from host 4000 to guest 5000, will look for Dockerfile in current folder

📁 Docker Compose (for multi-container apps)

docker-compose.yml example:

version: "3.8"
services:
  web:
    build: .
    ports:
      - "4000:5000" # create a mapping from host 4000 to guest 5000
    volumes:
      - .:/app
  redis:
    image: "redis:alpine"

Run with:

docker-compose up

You can also use:

docker-compose up -d

🧼 Useful Tips

  • Volumes = share data between host and container.
  • Environment variables: -e VAR=value or use .env files.
  • Logs: docker logs <container_id> -f

🧽 Cleanup

docker stop $(docker ps -q)           # Stop all
docker rm $(docker ps -a -q)         # Remove all containers
docker rmi $(docker images -q)       # Remove all images

🧠 Next Steps

  • Learn about Docker networks (connecting containers)
  • Use Docker volumes for persistent data
  • Explore Docker Compose for orchestrating complex apps
  • Try deploying your container to a cloud service (like Heroku, AWS ECS, or DigitalOcean)

Docker compose

Docker Compose is a tool for defining and running multi-container Docker applications using a simple YAML file (docker-compose.yml).

  • Manage multiple containers (like app + database) easily.
  • Simplify configuration and orchestration.
  • One command to build and run everything.

Docker volume

A Docker volume is a way to store data outside of a container’s lifecycle. Volumes are used for persistent storage, data sharing, and backups.

  • Keep data even if the container is deleted
  • Share data between multiple containers
  • Separate data from container logic

A bit of practice

https://github.com/blancheta/django-vite-boilerplate/tree/main

# docker-compose.yaml
services:
  backend:
    build:
      context: backend
      dockerfile: Dockerfile
    expose:
      - 8000
    volumes:
      - static_volume:/app/static
  frontend:
    build:
      context: frontend
      dockerfile: Dockerfile
    volumes:
      - frontend_volume:/frontend/dist
  nginx:
    build: ./nginx
    ports:
      - 1337:80
    depends_on:
      - backend
      - frontend
    volumes:
      - static_volume:/app/static # shared between backend and nginx
      - frontend_volume:/frontend/dist # shared between frontend with nginx
volumes:
  static_volume:
  frontend_volume:
# Nginx.conf

upstream django {
    server backend:8000;
}

server {

    sendfile on;

    listen 80;

    location / {
       root /frontend/dist;
       index index.html;
       try_files $uri $uri/ /index.html;
    }

    location /api {
        proxy_pass http://django;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
    }

    location /static/ {
        alias /app/static/;  # redirect static to /app/static
    }
}

 Nginx documentation recommends it for efficiency, except for large files. What can occur is that large file transfers can block connections overlong. The solution, found at the same link as above, it to use sendfile_max_chunk.