🐳

Docker Training

A Beginner-Friendly Guide

Use arrow keys or spacebar to navigate
← → between sections  |  ↑ ↓ within a section

Written by Christian W (christian.windi@elitery.com)
with help from GLM-5.1 by Z.ai 🤖
Intro

What is Docker?

Docker lets you package your app and everything it needs into a container.

Think of it like a lightweight box that runs your app the same way — on your laptop, on a server, or in the cloud.

Analogy — Shipping containers:
Standard-sized boxes that work on any ship, truck, or train. Docker containers work on any machine the same way.
Intro

Why Use Docker?

  • Runs the same on your laptop, staging, and production
  • Quick to start and stop — seconds, not minutes
  • Easy to share with your team
  • Keeps your host machine clean
  • Uses less resources than a virtual machine
↓ bonus joke
😎

Why did the developer start using Docker?

Because "it works on my machine" was getting old.
Now it breaks the same way everywhere!

There is no cloud. It's just someone else's Docker container.

Setup

Installing Docker (Step 1)

We are using Ubuntu 25.04. Run this in your terminal:

curl https://get.docker.com | bash
This downloads and installs Docker in one go. Easy!
Setup

Installing Docker (Step 2)

Add your user to the Docker group so you don't need sudo every time:

sudo usermod -aG docker $USER
Important: Log out and log back in for this to take effect.
Setup

Verify Your Installation

docker --version
docker run hello-world

If you see a welcome message from Docker — you're all set!

↓ bonus joke
🚀

Installing stuff the old way: dependencies, compile from source, pray to the dependency gods.

Installing Docker: curl | bash.
The dependency gods are unemployed now.

Junior dev: "I spent 3 days installing Node, Python, PostgreSQL, Redis and nginx."

Senior dev: "docker compose up -d"

Junior dev: "...what."

Basics

docker run — The Basics

docker run creates and starts a new container from an image.

  • Image = the template (like a recipe)
  • Container = the running app (like the cooked dish)
docker run nginx

This downloads the nginx image (if not local) and starts a container.

Basics

docker run — Useful Flags

# Run in background (detached)
docker run -d nginx

# Give it a name
docker run -d --name my-web nginx

# Map a port (host:container)
docker run -d --name my-web -p 8080:80 nginx

# Set an environment variable
docker run -d -e MYSQL_ROOT_PASSWORD=secret mysql
  • -d → run in the background
  • --name → give the container a friendly name
  • -p → port mapping: host port → container port
  • -e → set an environment variable
Basics

docker run --rm — Temporary Container

# Run once, auto-remove when done
docker run --rm alpine echo "Hello from Docker!"

The --rm flag removes the container automatically when it stops. Perfect for one-time tasks — no leftover containers to clean up!

# Quick test with Python
docker run --rm python:3.12 python -c "print('Python says hi!')"
Basics

docker exec — Run Commands Inside

# Start a container first
docker run -d --name my-web nginx

# Run a command inside it
docker exec my-web cat /etc/os-release

# Open a shell inside the container
docker exec -it my-web bash

docker exec lets you run commands inside a running container.

The -it flag gives you an interactive terminal. Think of it like SSH-ing into the container.
↓ bonus joke
🤫

docker run -d --rm -it -v -p -e --name my-container ...

If my mom saw my terminal, she'd think I'm hacking NASA.
I'm just starting a blog.

Nobody remembers all docker run flags. That's why Docker Compose was invented.

Compose

What is Docker Compose?

When your app needs multiple containers (e.g. web server + database), Docker Compose lets you define and run them all with a single YAML file.

  • One file to describe your whole setup
  • One command to start everything
  • Easy to share and version-control
Instead of typing long docker run commands, you write them in docker-compose.yml.
Compose

docker compose up

# docker-compose.yml
services:
  web:
    image: nginx
    ports:
      - "8080:80"
# Start everything in the background
docker compose up -d

# Watch the logs
docker compose logs -f

# Start and rebuild if needed
docker compose up -d --build

The -d flag runs in the background. Without it, you see logs in your terminal.

Compose

docker compose down & pull

# Stop and remove containers
docker compose down

# Stop and remove everything including volumes
docker compose down --volumes

# Pull latest images (no start)
docker compose pull

# Common workflow: pull then restart
docker compose pull && docker compose up -d

down stops and removes containers but keeps your data by default. pull grabs the latest images without starting anything.

Compose

Volumes — Keeping Your Data

Containers are temporary. When removed, their files are gone.

Volumes save data permanently outside the container.

Two main types:

  • Bind mounts — link a folder on your machine to the container
  • Named volumes — let Docker manage where data is stored
Compose

Bind Mount (./shared-drive)

services:
  web:
    image: nginx
    volumes:
      - ./html:/usr/share/nginx/html

Links a folder on your host machine to a folder inside the container.

Great for development — edit files on your machine, changes appear in the container instantly. The ./ means "current directory on your host".
Compose

Named Volumes (Docker Managed)

services:
  db:
    image: mysql
    volumes:
      - db-data:/var/lib/mysql

volumes:
  db-data:

Docker decides where to store the data on your host. Best for data you want to keep but don't need to edit directly (like database files).

Named volumes survive docker compose down. Your data is safe!
Compose

Port Mapping

services:
  web:
    image: nginx
    ports:
      - "8080:80"     # HOST:CONTAINER
      - "443:443"
  db:
    image: mysql
    ports:
      - "3306:3306"

The format is HOST_PORT : CONTAINER_PORT

  • Left side → what you type in your browser
  • Right side → what the app uses inside the container
↓ bonus joke
🙄

YAML: "Yet Another Markup Language"

In Docker Compose it means:
"You Always Mess up the Lines"

Before Compose I had 17 terminal tabs open. Now I have 18 — one more for docker compose logs -f.

Maintenance

docker ps — See What's Running

# Show running containers
docker ps

# Show ALL containers (including stopped)
docker ps -a

# Show just the container IDs
docker ps -q

docker ps shows running containers, their names, ports, and status.

Add -a to see stopped ones too.
Maintenance

Cleaning Up — docker system prune

Over time Docker collects stopped containers, unused images, and junk.

# Remove unused data (prompts for confirmation)
docker system prune

# Remove EVERYTHING unused, no confirmation
docker system prune -af

# Also remove volumes
docker system prune -af --volumes
  • -a → remove ALL unused images
  • -f → skip the "are you sure?" prompt
Maintenance

Quick Cleanup Commands

# Remove a specific container
docker rm my-container

# Remove a specific image
docker rmi nginx

# Stop all running containers
docker stop $(docker ps -q)

# Remove all stopped containers
docker container prune
↓ bonus joke
🧪

docker ps -a is like checking your fridge.

You find containers from 3 weeks ago and think...
"Should I keep this?"

Running docker system prune -af when you're stressed is cheaper than therapy. 47GB gone. Instant peace.

Cheat Sheet

Installation
curl https://get.docker.com | bashInstall Docker
sudo usermod -aG docker $USERAdd user to group
Running Containers
docker run nginxRun a container
docker run -d --name my-web -p 8080:80 nginxRun with options
docker run --rm alpine echo "Hi"Run once (auto-remove)
Managing
docker psList running
docker ps -aList all
docker exec -it my-web bashShell into container
Compose
docker compose up -dStart services
docker compose downStop services
docker compose pullUpdate images
Cleanup
docker system prune -afClean everything
docker system prune -af --volumesClean + volumes
🐳

Happy Dockering!

Practice makes perfect.
Try running different images, break things, and learn from it.

Docker is your friend!

Thank you!

Written by Christian W (christian.windi@elitery.com)
with help from GLM-5.1 by Z.ai 🤖
↓ one last joke
🍺

A DevOps engineer walks into a bar and orders 1 beer.

The bartender gives him 3 replicas,
a health check, and an auto-restart policy.

His friend orders 1 beer too. Kubernetes scales it to 50. The bar runs out of beer.