🐳 Week 4: Containers & Docker

Day 3: Container Management

⏱ Duration: 5 Hours

📚 Learning Objectives

  • Master Docker volumes for data persistence
  • Understand Docker networking concepts
  • Work with container logs effectively
  • Execute commands in running containers
  • Monitor container resources

📖 Core Concepts (2 Hours)

Docker Volumes

Containers are ephemeral - data inside is lost when they're removed. Volumes provide persistent storage that survives container lifecycle.

Volume Types: ┌─────────────────────────────────────────────────┐ │ 1. Named Volumes (Recommended) │ │ docker volume create mydata │ │ docker run -v mydata:/app/data image │ ├─────────────────────────────────────────────────┤ │ 2. Bind Mounts (Host path) │ │ docker run -v /host/path:/container/path │ │ docker run -v $(pwd):/app image │ ├─────────────────────────────────────────────────┤ │ 3. tmpfs Mounts (Memory only) │ │ docker run --tmpfs /app/temp image │ └─────────────────────────────────────────────────┘

Volume Commands

# Create a named volume docker volume create mydata # List volumes docker volume ls # Inspect volume docker volume inspect mydata # Remove volume docker volume rm mydata # Remove all unused volumes docker volume prune # Run container with named volume docker run -d -v mydata:/var/lib/mysql --name db mysql:8 # Run with bind mount (current directory) docker run -d -v $(pwd):/app -p 3000:3000 node-app # Read-only mount docker run -v /config:/app/config:ro image

Docker Networking

Docker networking allows containers to communicate with each other and the outside world.

Network Types: ┌────────────────────────────────────────────────┐ │ bridge (default) │ │ - Containers on same bridge can communicate │ │ - Use container names as hostnames │ ├────────────────────────────────────────────────┤ │ host │ │ - Container shares host's network │ │ - No port mapping needed │ ├────────────────────────────────────────────────┤ │ none │ │ - No network access │ │ - Completely isolated │ ├────────────────────────────────────────────────┤ │ custom bridge │ │ - User-defined network │ │ - Better DNS resolution between containers │ └────────────────────────────────────────────────┘

Network Commands

# List networks docker network ls # Create custom network docker network create mynetwork # Inspect network docker network inspect mynetwork # Run container on specific network docker run -d --network mynetwork --name web nginx docker run -d --network mynetwork --name api node-app # Containers can reach each other by name # From web: curl http://api:3000 # Connect running container to network docker network connect mynetwork existing-container # Disconnect from network docker network disconnect mynetwork container # Remove network docker network rm mynetwork

Container Logs

# View logs docker logs container_name # Follow logs (like tail -f) docker logs -f container_name # Show last N lines docker logs --tail 100 container_name # Show logs since timestamp docker logs --since 2024-01-01 container_name docker logs --since 10m container_name # Last 10 minutes # Show timestamps docker logs -t container_name # Combine options docker logs -f --tail 50 -t container_name

Docker Exec

# Execute command in running container docker exec container_name ls -la # Interactive shell docker exec -it container_name bash docker exec -it container_name sh # Alpine uses sh # Run as specific user docker exec -u root container_name whoami # Set environment variable docker exec -e MY_VAR=value container_name env # Set working directory docker exec -w /app container_name pwd

Resource Monitoring

# Real-time stats docker stats docker stats container_name # Container resource limits docker run -d --memory=512m --cpus=1.5 nginx # Inspect container docker inspect container_name docker inspect --format='{{.State.Status}}' container_name # View running processes docker top container_name # Container filesystem changes docker diff container_name

🔬 Hands-on Lab (2.5 Hours)

Lab 1: Data Persistence with Volumes

  • Create volumes for database containers
  • Verify data persists after container removal
  • Use bind mounts for development
# Lab 1: MySQL with persistent data docker volume create mysql-data docker run -d \ --name mydb \ -e MYSQL_ROOT_PASSWORD=secret \ -e MYSQL_DATABASE=testdb \ -v mysql-data:/var/lib/mysql \ -p 3306:3306 \ mysql:8 # Wait for MySQL to start sleep 30 # Create some data docker exec -it mydb mysql -uroot -psecret -e " CREATE TABLE testdb.users (id INT, name VARCHAR(50)); INSERT INTO testdb.users VALUES (1, 'Alice'), (2, 'Bob'); SELECT * FROM testdb.users; " # Remove container docker rm -f mydb # Recreate - data should persist! docker run -d \ --name mydb \ -e MYSQL_ROOT_PASSWORD=secret \ -v mysql-data:/var/lib/mysql \ -p 3306:3306 \ mysql:8 sleep 20 docker exec -it mydb mysql -uroot -psecret -e "SELECT * FROM testdb.users;" # Data is still there! # Cleanup docker rm -f mydb docker volume rm mysql-data

Lab 2: Container Networking

  • Create a custom network
  • Connect multiple containers
  • Test container-to-container communication
# Lab 2: Multi-container networking docker network create app-network # Start backend API docker run -d \ --name backend \ --network app-network \ -e PORT=8080 \ nginx # Start frontend docker run -d \ --name frontend \ --network app-network \ -p 80:80 \ nginx # Test connectivity from frontend to backend docker exec frontend sh -c "apt-get update && apt-get install -y curl" docker exec frontend curl -s http://backend:80 # Containers can reach each other by name! # View network details docker network inspect app-network # Cleanup docker rm -f frontend backend docker network rm app-network

Lab 3: Debugging with Logs and Exec

  • Troubleshoot container issues with logs
  • Debug inside running containers
  • Monitor resource usage
# Lab 3: Debugging containers docker run -d --name web -p 8080:80 nginx # View logs docker logs web docker logs -f web & # Follow in background # Generate traffic and watch logs curl http://localhost:8080 curl http://localhost:8080/notfound # Press Ctrl+C to stop following # Debug inside container docker exec -it web bash # Inside container: cat /etc/nginx/nginx.conf nginx -t # Test config cat /var/log/nginx/access.log exit # Monitor resources docker stats web --no-stream # Check processes docker top web # View filesystem changes docker diff web # Cleanup docker rm -f web

Lab 4: Development with Bind Mounts

  • Set up live code reloading
  • Edit files on host, see changes in container
# Lab 4: Development workflow mkdir dev-app && cd dev-app # Create a simple HTML file echo '<h1>Hello Docker!</h1>' > index.html # Run nginx with bind mount docker run -d \ --name dev-web \ -v $(pwd):/usr/share/nginx/html:ro \ -p 8080:80 \ nginx # View in browser curl http://localhost:8080 # Edit file on host echo '<h1>Updated content!</h1>' > index.html # Changes are instant! curl http://localhost:8080 # Cleanup docker rm -f dev-web cd .. && rm -rf dev-app

✅ Day 3 Checklist

  • Can create and use Docker volumes
  • Understand volume vs bind mount use cases
  • Can create custom networks
  • Containers communicate using names
  • Can debug with logs and exec
  • Can monitor container resources