Skip to main content

Docker and Containerization - A Complete Beginner's Guide

By · · 3 min read

Docker Containerization

Docker and Containerization: Complete Guide

Introduction

Docker is the tool you need when your app works on your laptop but breaks on the server. Instead of dealing with "works on my machine" problems, Docker containerizes applications so they run 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.0

Container 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 container

Advanced 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 --from=builder /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 too

Registry 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.0

Private 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.0

Production 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 runtime

2. Health Checks

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
  CMD node healthcheck.js

# Or in docker-compose
services:
  app:
    healthcheck:
      test: ["CMD", "curl", "-f", "https://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

3. Resource Limits

docker run -m 512M --cpus="0.5" my-app:1.0

Docker 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 lines

Enter Running Container

docker exec -it myapp /bin/sh      # Interactive shell
docker exec myapp npm version       # Run single command

Inspect Container

docker inspect myapp               # Full configuration
docker stats                       # CPU, memory usage

Docker 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! 🐳