Skip to main content

๐Ÿ“ฆ Docker Basics

๐Ÿ’ก What is Docker?

Docker packages applications and their dependencies into containers - lightweight, portable units that run consistently across different environments. Think of containers as self-contained boxes that have everything an application needs to run.

Key Concepts

๐Ÿงฉ Core Components
  • Image: A blueprint/template for containers (like a recipe)
  • Container: A running instance of an image (like a meal made from the recipe)
  • Volume: Persistent storage that survives container restarts
  • Network: How containers communicate with each other and the outside world
  • Docker Compose: Tool for defining multi-container applications

Basic Commands

Check Docker Version
Verify Docker is installed and see version info
docker --version
docker version
docker info
Test Docker Installation
Run a test container to verify everything works
docker run hello-world
Pull an Image
Download an image from Docker Hub
docker pull ubuntu:22.04
docker pull nginx:latest
Run a Container
Create and start a container from an image
# Basic run
docker run nginx

# Run with custom name
docker run --name my-nginx nginx

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

# Run with port mapping
docker run -d -p 8080:80 nginx

# Run with environment variables
docker run -d -e "MY_VAR=value" nginx

๐ŸŽผ Docker Compose

๐Ÿ’ก What is Docker Compose?

Docker Compose lets you define and run multi-container applications using a YAML file. Instead of managing each container separately, you describe your entire application stack in docker-compose.yaml and control everything with simple commands.

Essential Compose Commands

Start Services (Detached)
Start all services defined in docker-compose.yaml in the background
docker compose up -d
Start Services (Foreground)
Start services and see logs in real-time (Ctrl+C to stop)
docker compose up
Stop Services
Stop running containers but keep them for restart
docker compose stop
Start Stopped Services
Restart previously stopped services
docker compose start
Restart Services
Stop and start services in one command
docker compose restart

# Restart specific service
docker compose restart backend
Stop and Remove Containers
Stop services and remove containers (volumes remain intact)
docker compose down
Stop and Remove Everything (INCLUDING DATA!)
โš ๏ธ Nuclear option - removes containers AND volumes (all data lost)
docker compose down -v
๐Ÿšจ Critical Warning

docker compose down -v deletes ALL data stored in volumes. Only use this when you want a complete reset or are removing an application permanently.

View Service Status
See which containers are running
docker compose ps
View Logs
See output from all services
# All logs
docker compose logs

# Follow logs (real-time)
docker compose logs -f

# Last 100 lines
docker compose logs --tail=100

# Specific service
docker compose logs backend

# Follow specific service
docker compose logs -f backend
Pull Latest Images
Download updated versions of images
docker compose pull
Build Images
Build custom images defined in docker-compose.yaml
# Build all images
docker compose build

# Build without cache
docker compose build --no-cache

# Build specific service
docker compose build backend
Execute Command in Service
Run a command inside a running container
# Get shell access
docker compose exec backend bash

# Run single command
docker compose exec backend ls -la

# Run as different user
docker compose exec -u postgres postgres psql

Compose File Validation

Validate Configuration
Check if docker-compose.yaml is valid
docker compose config

๐Ÿ”„ Container Lifecycle Management

Starting & Stopping

Start Container
docker start <container_name_or_id>
Stop Container
Gracefully stop (sends SIGTERM, waits, then SIGKILL)
docker stop <container_name_or_id>

# Stop with timeout (seconds)
docker stop -t 30 <container_name_or_id>
Restart Container
docker restart <container_name_or_id>
Kill Container
Force stop immediately (sends SIGKILL)
docker kill <container_name_or_id>
Remove Container
Delete stopped container
# Remove stopped container
docker rm <container_name_or_id>

# Force remove running container
docker rm -f <container_name_or_id>

# Remove with volumes
docker rm -v <container_name_or_id>

Listing & Inspection

List Running Containers
docker ps
List All Containers
Including stopped containers
docker ps -a
Inspect Container
Get detailed information about a container
docker inspect <container_name_or_id>

# Get specific field
docker inspect --format='{{.State.Status}}' <container>
View Container Logs
# All logs
docker logs <container_name_or_id>

# Follow logs (real-time)
docker logs -f <container_name_or_id>

# Last 100 lines
docker logs --tail 100 <container_name_or_id>

# With timestamps
docker logs -t <container_name_or_id>
Execute Command in Running Container
# Interactive shell
docker exec -it <container_name> bash

# Or sh if bash not available
docker exec -it <container_name> sh

# Run single command
docker exec <container_name> ls -la /app

# As different user
docker exec -u postgres <container_name> psql
Copy Files To/From Container
# Copy from container to host
docker cp <container>:/path/to/file /local/path

# Copy from host to container
docker cp /local/file <container>:/path/to/destination

๐Ÿ“Š Monitoring & Performance

View Resource Usage
Real-time stats for all running containers
docker stats

# Specific container
docker stats <container_name>

# No streaming (one-time)
docker stats --no-stream
View Running Processes
See processes inside container
docker top <container_name>
View Port Mappings
docker port <container_name>
System-Wide Information
# Disk usage
docker system df

# Detailed disk usage
docker system df -v

# System information
docker info
Monitor Events
Real-time events from Docker daemon
docker events

# Filter by type
docker events --filter 'type=container'

# Filter by event
docker events --filter 'event=start'

๐Ÿ’พ Volumes & Data Management

๐Ÿ’ก What are Volumes?

Volumes are Docker's way of persisting data beyond container lifecycles. When you delete a container, volumes remain intact unless explicitly removed. This is how your data survives updates and restarts.

List Volumes
docker volume ls
Create Volume
docker volume create my_volume
Inspect Volume
See volume details including mount point
docker volume inspect my_volume
Remove Volume
โš ๏ธ This deletes data permanently
docker volume rm my_volume

# Force remove
docker volume rm -f my_volume
Backup Volume
Create a tarball backup of volume data
docker run --rm \
  -v my_volume:/data \
  -v $(pwd):/backup \
  ubuntu tar czf /backup/backup.tar.gz /data
Restore Volume
Restore from backup tarball
docker run --rm \
  -v my_volume:/data \
  -v $(pwd):/backup \
  ubuntu tar xzf /backup/backup.tar.gz -C /

Volume Usage in Containers

Mount Volume to Container
# Named volume
docker run -d -v my_volume:/app/data nginx

# Bind mount (host directory)
docker run -d -v /host/path:/container/path nginx

# Read-only mount
docker run -d -v my_volume:/app/data:ro nginx

๐ŸŒ Networks

๐Ÿ’ก Docker Networks

Networks allow containers to communicate with each other and the outside world. Docker creates isolated networks where containers can find each other by name.

List Networks
docker network ls
Create Network
# Bridge network (default type)
docker network create my_network

# Custom subnet
docker network create --subnet=172.20.0.0/16 my_network
Inspect Network
docker network inspect my_network
Connect Container to Network
docker network connect my_network <container_name>
Disconnect Container from Network
docker network disconnect my_network <container_name>
Remove Network
docker network rm my_network

๐Ÿ“ฆ Image Management

List Images
docker images

# With digests
docker images --digests

# Show all (including intermediate)
docker images -a
Pull Image
# Latest version
docker pull nginx

# Specific version
docker pull nginx:1.25

# From different registry
docker pull ghcr.io/user/image:tag
Search Images
Search Docker Hub
docker search nginx

# Limit results
docker search --limit 10 nginx
Remove Image
docker rmi <image_name_or_id>

# Force remove
docker rmi -f <image_name_or_id>

# Remove multiple
docker rmi image1 image2 image3
Tag Image
Create alias for image
docker tag source_image:tag target_image:tag

# Example
docker tag nginx:latest myregistry.com/nginx:v1
Build Image from Dockerfile
# Build from current directory
docker build -t my-image:tag .

# Build without cache
docker build --no-cache -t my-image:tag .

# Build with build args
docker build --build-arg VERSION=1.0 -t my-image:tag .
Save & Load Images
Export/import images as tar files
# Save image to file
docker save -o my-image.tar my-image:tag

# Load image from file
docker load -i my-image.tar
View Image History
See image layers and how it was built
docker history <image_name>

๐Ÿงน Cleanup & Maintenance

โš ๏ธ Before Cleanup

Always check what will be removed with docker system df first. Pruning operations are permanent!

Remove Stopped Containers
docker container prune

# Without confirmation prompt
docker container prune -f
Remove Unused Images
Removes dangling images (not tagged and not used)
docker image prune

# Remove ALL unused images
docker image prune -a
Remove Unused Volumes
โš ๏ธ This deletes data in unused volumes!
docker volume prune

# Without confirmation
docker volume prune -f
Remove Unused Networks
docker network prune
Complete System Cleanup
Remove all unused containers, networks, images (both dangling and unreferenced)
# Safe cleanup (keeps volumes)
docker system prune

# Aggressive cleanup (includes volumes)
docker system prune -a --volumes

# Without confirmation
docker system prune -af
๐Ÿšจ Nuclear Option

Complete Docker Reset:

# Stop all containers
docker stop $(docker ps -aq)

# Remove all containers
docker rm $(docker ps -aq)

# Remove all images
docker rmi $(docker images -q)

# Remove all volumes
docker volume rm $(docker volume ls -q)

# Remove all networks
docker network rm $(docker network ls -q)

This removes EVERYTHING. Only use if you want a complete fresh start!

๐Ÿ”ง Troubleshooting

Common Issues

โš ๏ธ Port Already in Use

Error: Error starting userland proxy: listen tcp 0.0.0.0:9001: bind: address already in use

Solution:

# Find what's using the port
sudo lsof -i :9001
sudo netstat -tulpn | grep :9001

# Kill the process or change port in docker-compose.yaml
โš ๏ธ Container Keeps Restarting

Check logs for errors:

docker logs --tail 100 <container_name>
โš ๏ธ Out of Disk Space
# Check Docker disk usage
docker system df

# Clean up
docker system prune -a
docker volume prune
โš ๏ธ Permission Denied

Error: Got permission denied while trying to connect to the Docker daemon socket

Solution:

# Add user to docker group
sudo usermod -aG docker $USER

# Log out and back in for changes to take effect
# Or start new shell
newgrp docker
โš ๏ธ Network Issues

Container can't reach internet or other containers

# Restart Docker daemon
sudo systemctl restart docker

# Or recreate network
docker network rm <network_name>
docker network create <network_name>

๐ŸŽฏ Common Patterns

Complete Application Reset

Reset Application (Delete All Data)
cd ~/project
docker compose down -v  # Remove containers + volumes
docker compose pull     # Get latest images
docker compose up -d    # Start fresh

Update Application

Update to Latest Version (Keep Data)
cd ~/project
docker compose pull     # Download latest
docker compose up -d    # Recreate containers with new images

Backup and Restore

Backup Before Changes
# Stop services
docker compose stop

# Backup volumes
docker run --rm -v project_data:/data -v $(pwd):/backup \
  ubuntu tar czf /backup/backup-$(date +%Y%m%d).tar.gz /data

# Restart
docker compose start

Development vs Production

Multiple Compose Files
# Development
docker compose -f docker-compose.yaml -f docker-compose.dev.yaml up

# Production
docker compose -f docker-compose.yaml -f docker-compose.prod.yaml up -d

Debugging Running Container

Interactive Shell Access
# Get shell in running container
docker exec -it <container_name> bash

# Or sh if bash isn't available
docker exec -it <container_name> sh

# Run single command
docker exec <container_name> ls -la /app

โœ… Best Practices

Project Organization

๐Ÿ“‚ Directory Structure
~/projects/
  โ”œโ”€โ”€ penpot/
  โ”‚   โ”œโ”€โ”€ docker-compose.yaml
  โ”‚   โ”œโ”€โ”€ .env
  โ”‚   โ””โ”€โ”€ README.md
  โ”œโ”€โ”€ nextcloud/
  โ”‚   โ”œโ”€โ”€ docker-compose.yaml
  โ”‚   โ””โ”€โ”€ data/
  โ””โ”€โ”€ ...

Docker Compose Best Practices

  • Always use named volumes instead of anonymous volumes
  • Use .env files for sensitive data (passwords, API keys)
  • Pin image versions - use postgres:15 not postgres:latest
  • Add restart policies - restart: unless-stopped
  • Use depends_on to manage service startup order
  • Document your setup in README.md
  • Use health checks to ensure services are actually running
  • Limit container resources (memory, CPU) in production

Maintenance Routine

Weekly Cleanup
# Remove unused images, containers, networks
docker system prune

# Remove unused volumes (be careful!)
docker volume prune
Check Updates
# Check for new images
docker compose pull

# View what would change
docker compose up --no-start

# Apply updates
docker compose up -d

Security Tips

๐Ÿ”’ Security Checklist
  • Never store passwords in docker-compose.yaml - use .env files
  • Add .env to .gitignore
  • Use official images from trusted sources
  • Keep images updated regularly
  • Don't run containers as root unless necessary
  • Limit container resources (memory, CPU) in production
  • Use read-only file systems where possible
  • Scan images for vulnerabilities with docker scan

When Things Go Wrong

๐Ÿšจ Emergency Recovery

If everything is broken:

# 1. Stop everything
docker compose down

# 2. Check logs for errors
docker compose logs --tail=100

# 3. Try starting with verbose output
docker compose up

# 4. If still broken, nuclear option:
docker compose down -v
docker system prune -a
docker compose up -d

โšก Quick Reference Card

Task Command
Start services docker compose up -d
Stop services docker compose stop
Restart services docker compose restart
View logs docker compose logs -f
Update images docker compose pull && docker compose up -d
Remove containers (keep data) docker compose down
Complete reset docker compose down -v
Check status docker compose ps
Clean unused resources docker system prune
Shell into container docker exec -it <name> bash
View resource usage docker stats
Copy files to container docker cp file <name>:/path
List all containers docker ps -a
List all images docker images
List volumes docker volume ls