Docker and Containerization: Complete Guide
Introduction
Docker revolutionized how developers build, deploy, and scale applications. Instead of worrying about "works on my machine" problems, Docker containerizes applications so they work identically everywhere—your laptop, server, or cloud platform. This guide takes you from Docker basics to production-ready deployments, with practical examples you can use immediately.
What is Docker?
Docker is a containerization platform that packages your application with all dependencies into a single unit called a container. Unlike virtual machines that virtualize hardware, Docker containers share the OS kernel, making them lightweight and fast.
Key Benefits:
- Consistency - Same environment everywhere
- Speed - Containers start in seconds
- Efficiency - Share OS kernel, minimal overhead
- Scalability - Easy to run multiple instances
- Isolation - Each container is independent
Docker Fundamentals
Images vs Containers
- Image: Blueprint (like a class in OOP)
- Container: Running instance (like an object)
Dockerfile Basics
# Base image
FROM node:18-alpine
# Working directory
WORKDIR /app
# Copy files
COPY package*.json ./
# Install dependencies
RUN npm install
# Expose port
EXPOSE 3000
# Start command
CMD ["npm", "start"]Building an Image
docker build -t my-app:1.0 .
docker images # List all images
docker run -p 3000:3000 my-app:1.0Container Lifecycle
docker run --name myapp my-app:1.0 # Create and start
docker ps # Running containers
docker ps -a # All containers
docker stop myapp # Stop container
docker start myapp # Restart container
docker rm myapp # Remove containerAdvanced Dockerfile Optimization
Multi-stage Builds (Reduce Image Size)
# Build stage
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine
WORKDIR /app
COPY /app/dist ./dist
COPY package*.json ./
RUN npm install --production
EXPOSE 3000
CMD ["node", "dist/index.js"]Result: 500MB → 50MB image size!
Layer Caching Optimization
# Order matters for caching!
FROM node:18
WORKDIR /app
# Stable dependencies should be first
COPY package*.json ./
RUN npm install
# Frequently changing code last
COPY . .
CMD ["npm", "start"]Docker Compose for Multi-Container Apps
Example: Node.js + MongoDB + Redis
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- MONGO_URL=mongodb://mongo:27017/myapp
- REDIS_URL=redis://redis:6379
depends_on:
- mongo
- redis
networks:
- app-network
mongo:
image: mongo:5
volumes:
- mongo-data:/data/db
networks:
- app-network
redis:
image: redis:7-alpine
networks:
- app-network
volumes:
mongo-data:
networks:
app-network:Commands
docker-compose up # Start all services
docker-compose up -d # Background
docker-compose logs app # View logs
docker-compose ps # Status
docker-compose down # Stop and remove
docker-compose down -v # Remove volumes tooRegistry and Pushing Images
Docker Hub
# Login
docker login
# Tag image for Docker Hub
docker tag my-app:1.0 username/my-app:1.0
# Push
docker push username/my-app:1.0
# Pull
docker pull username/my-app:1.0Private Registry (GitLab, GitHub, AWS ECR)
docker tag my-app:1.0 registry.gitlab.com/username/my-app:1.0
docker push registry.gitlab.com/username/my-app:1.0Production Best Practices
1. Security
# Run as non-root user
RUN useradd -m appuser
USER appuser
# Don't store secrets in image
ARG SECRET_KEY
# Use environment variables at runtime2. Health Checks
HEALTHCHECK \
CMD node healthcheck.js
# Or in docker-compose
services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "https://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 33. Resource Limits
docker run -m 512M --cpus="0.5" my-app:1.0Docker Networking
Types of Networks
- bridge (default) - Containers on same host communicate
- host - Container uses host's network
- overlay - Multi-host networking (swarm/kubernetes)
Service Discovery
// Inside container, reference other services by name
const mongoUrl = 'mongodb://mongo:27017/myapp';
const redisUrl = 'redis://redis:6379';Debugging Docker Issues
View Logs
docker logs myapp
docker logs -f myapp # Follow logs
docker logs --tail 50 myapp # Last 50 linesEnter Running Container
docker exec -it myapp /bin/sh # Interactive shell
docker exec myapp npm version # Run single commandInspect Container
docker inspect myapp # Full configuration
docker stats # CPU, memory usageDocker vs Virtual Machines
| Aspect | Docker | VM |
|---|---|---|
| Size | 50-100MB | 1-5GB |
| Boot time | Seconds | Minutes |
| OS kernel | Shared | Separate |
| Overhead | Low | High |
| Density | 100s per host | 10s per host |
Kubernetes Introduction
For orchestrating Docker containers at scale:
- Auto-scaling - Automatically scale based on load
- Rolling updates - Update without downtime
- Self-healing - Restart failed containers
- Load balancing - Distribute traffic
Learn Docker first, then explore Kubernetes!
Tools and Resources
- Image Building: Buildkit, Kaniko
- Monitoring: Docker Desktop, Portainer
- CI/CD: GitHub Actions, GitLab CI, Jenkins
- Documentation: Docker Docs, Katacoda Tutorials
- Learning: Play with Docker, Docker Labs
Real-World Checklist
- ✓ Create Dockerfile for your app
- ✓ Build image locally
- ✓ Test container thoroughly
- ✓ Use docker-compose for dependencies
- ✓ Optimize image size (multi-stage builds)
- ✓ Add health checks
- ✓ Implement logging strategy
- ✓ Push to registry
- ✓ Document container setup
- ✓ Monitor container metrics
Conclusion
Docker containerization is now a standard in modern development. From local development to production deployment, Docker ensures consistency and simplicity. Start small, master the basics, then explore advanced topics like Docker Swarm and Kubernetes.
Your applications deserve to be containerized! 🐳