A Beginner-Friendly Guide
Use arrow keys or spacebar to navigate
← → between sections | ↑ ↓ within a section
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.
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.
We are using Ubuntu 25.04. Run this in your terminal:
curl https://get.docker.com | bash
Add your user to the Docker group so you don't need sudo every time:
sudo usermod -aG docker $USER
docker --version
docker run hello-world
If you see a welcome message from Docker — you're all set!
↓ bonus jokeInstalling 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."
docker run creates and starts a new container from an image.
docker run nginx
This downloads the nginx image (if not local) and starts a container.
# 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
# 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!')"
# 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.
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.
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.
docker run commands,
you write them in docker-compose.yml.
# 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.
# 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.
Containers are temporary. When removed, their files are gone.
Volumes save data permanently outside the container.
Two main types:
./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.
./ means "current directory on your host".
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).
docker compose down.
Your data is safe!
services:
web:
image: nginx
ports:
- "8080:80" # HOST:CONTAINER
- "443:443"
db:
image: mysql
ports:
- "3306:3306"
The format is HOST_PORT : CONTAINER_PORT
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.
# 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.
-a to see stopped ones too.
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
# 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.
| Installation | |
|---|---|
curl https://get.docker.com | bash | Install Docker |
sudo usermod -aG docker $USER | Add user to group |
| Running Containers | |
|---|---|
docker run nginx | Run a container |
docker run -d --name my-web -p 8080:80 nginx | Run with options |
docker run --rm alpine echo "Hi" | Run once (auto-remove) |
| Managing | |
|---|---|
docker ps | List running |
docker ps -a | List all |
docker exec -it my-web bash | Shell into container |
| Compose | |
|---|---|
docker compose up -d | Start services |
docker compose down | Stop services |
docker compose pull | Update images |
| Cleanup | |
|---|---|
docker system prune -af | Clean everything |
docker system prune -af --volumes | Clean + volumes |
Practice makes perfect.
Try running different images, break things, and learn from it.
Docker is your friend!
Thank you!
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.