Docker Fundamentals
Learn Docker basics: images, containers, Dockerfile creation, networking, volumes, and essential commands for containerization.
Learn Docker basics: images, containers, Dockerfile creation, networking, volumes, and essential commands for containerization. This hands-on tutorial focuses on practical implementation of docker fundamentals concepts.
Docker Fundamentals
Docker revolutionized application deployment by packaging code with its dependencies into portable containers.
What is Docker?
Docker is a platform for developing, shipping, and running applications in containers—lightweight, portable, and self-sufficient environments.
Traditional VMs: Docker Containers:
┌─────────────┐ ┌─────────────┐
│ App A │ │ App A │
│ Bins/Libs │ │ Bins/Libs │
│ Guest OS │ ├─────────────┤
├─────────────┤ │ App B │
│ App B │ │ Bins/Libs │
│ Bins/Libs │ ├─────────────┤
│ Guest OS │ │ App C │
├─────────────┤ │ Bins/Libs │
│ Hypervisor│ ├─────────────┤
├─────────────┤ │ Docker │
│ Host OS │ │ Engine │
├─────────────┤ ├─────────────┤
│ Hardware │ │ Host OS │
└─────────────┘ ├─────────────┤
│ Hardware │
└─────────────┘
Docker Architecture
┌───────────────────────────────────────────────────────────────┐
│ Docker Architecture │
├───────────────────────────────────────────────────────────────┤
│ │
│ Docker Client ──API──> Docker Daemon (Host) │
│ (CLI) ┌─────────────────────┐ │
│ (REST) │ Image Management │ │
│ │ Container Runtime │ │
│ │ Networks/Volumes │ │
│ └──────────┬──────────┘ │
│ │ │
│ ┌──────────┴──────────┐ │
│ │ Containerd │ │
│ │ (Container │ │
│ │ Runtime) │ │
│ └──────────┬──────────┘ │
│ ┌──────────┴──────────┐ │
│ │ runc │ │
│ │ (Low-level) │ │
│ └─────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────┘
Core Concepts
Images
Read-only templates used to create containers.
# List images
docker images
# Pull image from registry
docker pull nginx:latest
docker pull ubuntu:22.04
# Build image from Dockerfile
docker build -t myapp:1.0 .
# Tag image
docker tag myapp:1.0 registry.example.com/myapp:1.0
# Remove image
docker rmi nginx:latest
docker image prune # Remove dangling images
Containers
Runnable instances of images.
# Run container
docker run nginx
# Run interactively
docker run -it ubuntu:22.04 /bin/bash
# Run in background (detached)
docker run -d -p 80:80 --name web nginx
# List containers
docker ps # Running
docker ps -a # All
# Start/Stop/Restart
docker start web
docker stop web
docker restart web
# Remove container
docker rm web
docker rm -f web # Force remove running
# Execute command in running container
docker exec -it web /bin/bash
docker exec web nginx -t # Test config
# View logs
docker logs web
docker logs -f web # Follow
Dockerfile
A script containing instructions to build a Docker image.
Basic Structure
# Base image
FROM node:18-alpine
# Set working directory
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy application code
COPY . .
# Create non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# Change ownership
RUN chown -R nextjs:nodejs /app
USER nextjs
# Expose port
EXPOSE 3000
# Health check
HEALTHCHECK \
CMD curl -f http://localhost:3000/api/health || exit 1
# Start command
CMD ["npm", "start"]
Dockerfile Instructions
| Instruction | Purpose | Example |
|---|---|---|
FROM | Base image | FROM ubuntu:22.04 |
WORKDIR | Set working directory | WORKDIR /app |
COPY | Copy files from host | COPY . /app |
ADD | Copy + extract/URL support | ADD https://... /tmp/ |
RUN | Execute command | RUN apt-get update |
CMD | Default command | CMD ["node", "app.js"] |
ENTRYPOINT | Fixed command | ENTRYPOINT ["java", "-jar"] |
ENV | Set environment variable | ENV NODE_ENV=production |
ARG | Build-time variable | ARG VERSION=1.0 |
EXPOSE | Document port | EXPOSE 8080 |
VOLUME | Create mount point | VOLUME /data |
USER | Set user | USER 1000 |
LABEL | Add metadata | LABEL version="1.0" |
Multi-stage Builds
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine AS production
WORKDIR /app
ENV NODE_ENV=production
# Copy only necessary files from builder
COPY /app/dist ./dist
COPY /app/node_modules ./node_modules
COPY /app/package.json ./
USER node
EXPOSE 3000
CMD ["node", "dist/main.js"]
Essential Commands
Container Management
# Lifecycle
docker create nginx # Create but don't start
docker start container_id # Start created/stopped
docker stop container_id # Stop gracefully
docker kill container_id # Stop forcefully
docker restart container_id # Restart
docker pause container_id # Pause processes
docker unpause container_id # Resume
docker rm container_id # Remove
# Information
docker ps # List running
docker ps -a # List all
docker ps -q # List IDs only
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
docker inspect container_id # Detailed info (JSON)
docker stats # Resource usage
docker top container_id # Running processes
docker logs container_id # View logs
docker logs -f container_id # Follow logs
docker logs --tail 100 container_id # Last 100 lines
Image Management
# Build
docker build -t myapp:1.0 .
docker build -f Dockerfile.prod -t myapp:prod .
docker build --no-cache -t myapp:1.0 .
docker build --target production -t myapp:prod .
# Registry operations
docker login registry.example.com
docker push registry.example.com/myapp:1.0
docker pull nginx:latest
# Information
docker images
docker history myapp:1.0
docker inspect myapp:1.0
# Cleanup
docker rmi image_id
docker image prune # Remove dangling
docker image prune -a # Remove all unused
docker system prune # Remove unused data
Networking
Network Types
| Type | Description | Use Case |
|---|---|---|
bridge | Default private network | Container communication |
host | Use host's network | Performance, no isolation |
none | No network | Isolated containers |
overlay | Multi-host network | Docker Swarm |
macvlan | Assign MAC address | Legacy apps |
Network Commands
# List networks
docker network ls
# Create network
docker network create my-network
# Run with network
docker run -d --network my-network --name web nginx
docker run -d --network my-network --name db postgres
# Container DNS
docker exec web ping db # Works within same network
# Inspect network
docker network inspect my-network
# Connect/disconnect
docker network connect my-network container2
docker network disconnect my-network container2
# Remove
docker network rm my-network
Port Mapping
# Map host port to container port
docker run -p 8080:80 nginx # Host:Container
docker run -p 127.0.0.1:8080:80 nginx # Bind to specific IP
docker run -p 8080:80/udp nginx # UDP port
docker run -P nginx # Publish all EXPOSED ports
Storage
Volume Types
# Named volumes (managed by Docker)
docker volume create my-data
docker run -v my-data:/data nginx
# Bind mounts (host directory)
docker run -v /host/path:/container/path nginx
docker run -v $(pwd):/app nginx
# tmpfs mounts (in memory)
docker run --tmpfs /cache:rw,noexec,nosuid,size=100m nginx
Volume Commands
# Create
docker volume create my-volume
# List
docker volume ls
# Inspect
docker volume inspect my-volume
# Remove
docker volume rm my-volume
docker volume prune # Remove unused
# Backup
docker run --rm -v my-volume:/data -v $(pwd):/backup alpine \
tar czf /backup/backup.tar.gz -C /data .
# Restore
docker run --rm -v my-volume:/data -v $(pwd):/backup alpine \
tar xzf /backup/backup.tar.gz -C /data
Docker Compose
Basic docker-compose.yml
version: '3.8'
services:
web:
build: ./web
ports:
- "80:80"
volumes:
- ./web:/usr/share/nginx/html:ro
depends_on:
- api
networks:
- frontend
- backend
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
restart: unless-stopped
api:
build:
context: ./api
dockerfile: Dockerfile
target: production
environment:
- NODE_ENV=production
- DB_HOST=db
- DB_PORT=5432
env_file:
- .env.api
ports:
- "3000:3000"
depends_on:
db:
condition: service_healthy
networks:
- backend
deploy:
replicas: 2
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
restart: unless-stopped
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: appuser
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
volumes:
- db-data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
secrets:
- db_password
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "pg_isready -U appuser -d myapp"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
networks:
- backend
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # No external access
volumes:
db-data:
driver: local
redis-data:
driver: local
secrets:
db_password:
file: ./secrets/db_password.txt
Compose Commands
# Start services
docker-compose up
docker-compose up -d # Detached
docker-compose up --build # Rebuild images
docker-compose up --force-recreate # Recreate containers
# Stop services
docker-compose down
docker-compose down -v # Remove volumes too
docker-compose down --rmi all # Remove images too
# View status
docker-compose ps
docker-compose logs
docker-compose logs -f web # Follow web service
# Execute commands
docker-compose exec web /bin/bash
docker-compose run --rm api npm test
# Scale services
docker-compose up -d --scale web=3
# Validate config
docker-compose config
Best Practices
Image Optimization
# Use specific base image tags
FROM node:18.17.0-alpine3.18
# Multi-stage builds for smaller images
# .dockerignore to exclude files
# Minimize layers (combine RUN commands)
# Use --no-cache for reproducible builds
# Scan images for vulnerabilities
Security
# Run as non-root
RUN adduser -D appuser
USER appuser
# Use read-only root filesystem
docker run --read-only nginx
# Drop capabilities
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
# Use secrets for sensitive data
# Don't embed secrets in images
# Scan images: docker scan or trivy
.dockerignore
# Git
.git
.gitignore
# Dependencies
node_modules
vendor
# Build outputs
*.log
*.tmp
dist
build
# IDE
.idea
.vscode
# OS
.DS_Store
Thumbs.db
# Tests
__tests__
*.test.js
coverage
# Documentation
*.md
docs
Quiz
Quiz
Question 1 of 5What is the difference between a Docker image and a container?
Next Steps
Now let's explore advanced Docker concepts and then dive into Kubernetes for container orchestration.