Introduction

Docker has revolutionized how we approach application deployment and infrastructure management. In this article, we’ll explore the fundamentals and industry best practices.

What is Docker?

Docker is a containerization platform that packages your application along with all its dependencies into a standardized unit called a container. This ensures consistency across development, testing, and production environments.

Key Benefits

  • Consistency: Same environment everywhere
  • Isolation: Containers are isolated from each other
  • Portability: Run anywhere Docker is installed
  • Efficiency: Lightweight compared to virtual machines
  • Scalability: Easy to scale horizontally

Docker Images & Containers

Images are blueprints or templates, while containers are running instances of those images.

FROM golang:1.21-alpine
WORKDIR /app
COPY . .
RUN go build -o myapp
EXPOSE 8080
CMD ["./myapp"]

This Dockerfile:

  1. Uses Go 1.21 as the base image
  2. Sets working directory
  3. Copies source code
  4. Builds the application
  5. Exposes port 8080
  6. Sets the default command

Docker Compose for Multi-Container Apps

For applications with multiple services, Docker Compose simplifies orchestration:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "8080:8080"
    environment:
      - DATABASE_URL=postgres://db:5432/mydb
    depends_on:
      - db
  
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secure_password
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Best Practices

1. Keep Images Small

  • Use Alpine Linux as base image
  • Multi-stage builds to reduce final size
  • Minimize layers
# Stage 1: Build
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# Stage 2: Runtime
FROM alpine:latest
COPY --from=builder /app/myapp /myapp
ENTRYPOINT ["/myapp"]

2. Security

  • Never run containers as root
  • Use read-only filesystems when possible
  • Scan images for vulnerabilities
  • Use secrets management for sensitive data

3. Networking

  • Use custom networks for container communication
  • Expose only necessary ports
  • Use environment-specific configurations

4. Logging & Monitoring

  • Centralize logs outside containers
  • Use structured logging
  • Implement health checks
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
  interval: 30s
  timeout: 10s
  retries: 3

CI/CD Integration

Modern DevOps workflows integrate Docker with CI/CD:

# GitHub Actions Example
name: Build and Push Docker Image
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Build image
        run: docker build -t myapp:${{ github.sha }} .
      - name: Push to registry
        run: docker push myapp:${{ github.sha }}

Kubernetes Orchestration

For production-scale deployments, Kubernetes manages container orchestration:

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
  - name: myapp
    image: myapp:latest
    ports:
    - containerPort: 8080

Troubleshooting Tips

# View running containers
docker ps

# View logs
docker logs <container_id>

# Execute command in running container
docker exec -it <container_id> /bin/bash

# Remove unused images and containers
docker system prune

# Inspect container details
docker inspect <container_id>

Conclusion

Docker is a cornerstone of modern DevOps practices. It enables:

  • Faster development cycles
  • Consistent deployments
  • Better resource utilization
  • Simplified scaling

Start experimenting with Docker today. Begin with simple applications, then gradually integrate it into your CI/CD pipeline.

Resources