Docker and Kubernetes: Complete Container Orchestration Guide for 2025
Containers have revolutionized application deployment, and Kubernetes has become the industry standard for container orchestration. This comprehensive guide covers everything you need to deploy production-grade containerized applications.
Understanding Containers
What are Containers?
Containers package applications with all dependencies into standardized units. Unlike virtual machines, containers share the host OS kernel, making them lightweight and portable.
- Consistent environments (dev, staging, production)
- Faster deployment (seconds vs. minutes)
- Better resource utilization
- Simplified scaling
- Microservices enablement
Docker Fundamentals
Docker is the most popular container platform, powering over 75% of containerized applications.
- **Images**: Read-only templates for containers
- **Containers**: Running instances of images
- **Dockerfile**: Instructions to build images
- **Docker Hub**: Public image registry
- **Volumes**: Persistent data storage
- **Networks**: Container communication
Creating Your First Dockerfile
1# <span class="text-yellow-<span class="text-orange-400">300span>">Usespan> official base image2<span class="text-yellow-<span class="text-orange-400">300span>">FROMspan> node:<span class="text-orange-400">18span>-alpine3 4# <span class="text-yellow-<span class="text-orange-400">300span>">Setspan> working directory5<span class="text-yellow-<span class="text-orange-400">300span>">WORKDIRspan> /app6 7# <span class="text-yellow-<span class="text-orange-400">300span>">Copyspan> package files8<span class="text-yellow-<span class="text-orange-400">300span>">COPYspan> package*.json ./9 10# <span class="text-yellow-<span class="text-orange-400">300span>">Installspan> dependencies11<span class="text-yellow-<span class="text-orange-400">300span>">RUNspan> npm ci --only=production12 13# <span class="text-yellow-<span class="text-orange-400">300span>">Copyspan> application code14<span class="text-yellow-<span class="text-orange-400">300span>">COPYspan> . .15 16# <span class="text-yellow-<span class="text-orange-400">300span>">Exposespan> port17<span class="text-yellow-<span class="text-orange-400">300span>">EXPOSEspan> <span class="text-orange-400">3000span>18 19# <span class="text-yellow-<span class="text-orange-400">300span>">Setspan> <span class="text-blue-400">userspan>(security best practice)20<span class="text-yellow-<span class="text-orange-400">300span>">USERspan> node21 22# <span class="text-yellow-<span class="text-orange-400">300span>">Startspan> application23<span class="text-yellow-<span class="text-orange-400">300span>">CMDspan> [<span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"node"span>, <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"server.js"span>]- Use specific image tags (not latest)
- Multi-stage builds for smaller images
- Run as non-root user
- Minimize layers
- Use .dockerignore file
- Scan for vulnerabilities
Docker Compose for Multi-Container Apps
1version: <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">'<span class="text-orange-400">3span>.<span class="text-orange-400">8span>'span>2services:3 web:4 build: .5 ports:6 - <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"<span class="text-orange-400">3000span>:<span class="text-orange-400">3000span>"span>7 environment:8 - NODE_ENV=production9 - DB_HOST=database10 depends_on:11 - database12 - redis13 14 database:15 image: postgres:<span class="text-orange-400">15span>-alpine16 volumes:17 - postgres_data:/<span class="text-purple-<span class="text-orange-400">400span> font-semibold">varspan>/lib/postgresql/data18 environment:19 - POSTGRES_PASSWORD=secret20 21 redis:22 image: redis:<span class="text-orange-400">7span>-alpine23 ports:24 - <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"<span class="text-orange-400">6379span>:<span class="text-orange-400">6379span>"span>25 26volumes:27 postgres_data:Kubernetes Architecture
Control Plane Components
- 1API Server: Entry point for all operations
- 2etcd: Distributed key-value store (cluster state)
- 3Scheduler: Assigns pods to nodes
- 4Controller Manager: Maintains desired state
- 5Cloud Controller Manager: Cloud provider integration
Worker Node Components
- 1kubelet: Runs on each node, manages pods
- 2kube-proxy: Network proxy and load balancer
- 3Container Runtime: Docker, containerd, or CRI-O
Kubernetes Objects
Pod: Smallest deployable unit
1apiVersion: v12kind: <span class="text-yellow-<span class="text-orange-400">300span>">Podspan>3metadata:4 name: nginx-pod5spec:6 containers:7 - name: nginx8 image: nginx:<span class="text-orange-400">1span>.<span class="text-orange-400">25span>9 ports:10 - containerPort: <span class="text-orange-400">80span>Deployment: Manages pod replicas
1apiVersion: apps/v12kind: <span class="text-yellow-<span class="text-orange-400">300span>">Deploymentspan>3metadata:4 name: web-app5spec:6 replicas: <span class="text-orange-400">3span>7 selector:8 matchLabels:9 app: web10 template:11 metadata:12 labels:13 app: web14 spec:15 containers:16 - name: app17 image: myapp:<span class="text-orange-400">1span>.<span class="text-orange-400">0span>18 resources:19 limits:20 memory: <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"512Mi"span>21 cpu: <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"500m"span>22 requests:23 memory: <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"256Mi"span>24 cpu: <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"250m"span>Service: Exposes pods
1apiVersion: v12kind: <span class="text-yellow-<span class="text-orange-400">300span>">Servicespan>3metadata:4 name: web-service5spec:6 selector:7 app: web8 ports:9 - port: <span class="text-orange-400">80span>10 targetPort: <span class="text-orange-400">8080span>11 <span class="text-purple-<span class="text-orange-400">400span> font-semibold">typespan>: <span class="text-yellow-<span class="text-orange-400">300span>">LoadBalancerspan>ConfigMap & Secrets: Configuration management
1apiVersion: v12kind: <span class="text-yellow-<span class="text-orange-400">300span>">ConfigMapspan>3metadata:4 name: app-config5data:6 APP_ENV: production7 LOG_LEVEL: info8---9apiVersion: v110kind: <span class="text-yellow-<span class="text-orange-400">300span>">Secretspan>11metadata:12 name: db-secret13<span class="text-purple-<span class="text-orange-400">400span> font-semibold">typespan>: <span class="text-yellow-<span class="text-orange-400">300span>">Opaquespan>14data:15 password: cGFzc3dvcmQxMjM= # base64 encodedDeployment Strategies
Rolling Update
- Zero downtime
- Can rollback if issues detected
- Gradual traffic shift
1spec:2 strategy:3 <span class="text-purple-<span class="text-orange-400">400span> font-semibold">typespan>: <span class="text-yellow-<span class="text-orange-400">300span>">RollingUpdatespan>4 rollingUpdate:5 maxSurge: <span class="text-orange-400">1span>6 maxUnavailable: <span class="text-orange-400">0span>Blue-Green Deployment
- Deploy to green (new version)
- Test thoroughly
- Switch traffic to green
- Keep blue as fallback
Canary Deployment
- Deploy new version alongside old
- Route 5% traffic to new
- Monitor metrics
- Increase percentage if stable
- Full rollout or rollback
Production Best Practices
Resource Management
Always set resource limits:
1resources:2 requests:3 memory: <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"256Mi"span>4 cpu: <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"250m"span>5 limits:6 memory: <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"512Mi"span>7 cpu: <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">"500m"span>Health Checks
Implement liveness and readiness probes:
1livenessProbe:2 httpGet:3 path: /health4 port: <span class="text-orange-400">8080span>5 initialDelaySeconds: <span class="text-orange-400">30span>6 periodSeconds: <span class="text-orange-400">10span>7 8readinessProbe:9 httpGet:10 path: /ready11 port: <span class="text-orange-400">8080span>12 initialDelaySeconds: <span class="text-orange-400">5span>13 periodSeconds: <span class="text-orange-400">5span>Autoscaling
Horizontal Pod Autoscaler:
1apiVersion: autoscaling/v22kind: <span class="text-yellow-<span class="text-orange-400">300span>">HorizontalPodAutoscalerspan>3metadata:4 name: web-app-hpa5spec:6 scaleTargetRef:7 apiVersion: apps/v18 kind: <span class="text-yellow-<span class="text-orange-400">300span>">Deploymentspan>9 name: web-app10 minReplicas: <span class="text-orange-400">2span>11 maxReplicas: <span class="text-orange-400">10span>12 metrics:13 - <span class="text-purple-<span class="text-orange-400">400span> font-semibold">typespan>: <span class="text-yellow-<span class="text-orange-400">300span>">Resourcespan>14 resource:15 name: cpu16 target:17 <span class="text-purple-<span class="text-orange-400">400span> font-semibold">typespan>: <span class="text-yellow-<span class="text-orange-400">300span>">Utilizationspan>18 averageUtilization: <span class="text-orange-400">70span>Security
- Use RBAC for access control
- Network policies for pod communication
- Pod security policies/standards
- Secret management (HashiCorp Vault)
- Image scanning
- Run as non-root
- Read-only file systems
Monitoring and Logging
Prometheus + Grafana: Metrics ELK or Loki: Logging Jaeger: Distributed tracing
1# <span class="text-yellow-<span class="text-orange-400">300span>">ServiceMonitorspan> <span class="text-purple-<span class="text-orange-400">400span> font-semibold">forspan> <span class="text-yellow-<span class="text-orange-400">300span>">Prometheusspan>2apiVersion: monitoring.coreos.com/v13kind: <span class="text-yellow-<span class="text-orange-400">300span>">ServiceMonitorspan>4metadata:5 name: web-app6spec:7 selector:8 matchLabels:9 app: web10 endpoints:11 - port: metrics12 interval: 30sHelm: Kubernetes Package Manager
Helm simplifies complex deployments:
1# <span class="text-yellow-<span class="text-orange-400">300span>">Installspan> application2helm install my-app ./chart3 4# <span class="text-yellow-<span class="text-orange-400">300span>">Upgradespan>5helm upgrade my-app ./chart6 7# <span class="text-yellow-<span class="text-orange-400">300span>">Rollbackspan>8helm rollback my-app <span class="text-orange-400">1span>Chart Structure:
1my-chart/2āāā <span class="text-yellow-<span class="text-orange-400">300span>">Chartspan>.yaml3āāā values.yaml4āāā templates/5ā āāā deployment.yaml6ā āāā service.yaml7ā āāā ingress.yaml8āāā charts/CI/CD with Kubernetes
GitOps with ArgoCD
Declarative, Git-based deployment: 1. Commit changes to Git 2. ArgoCD detects changes 3. Automatically syncs to cluster 4. Ensures desired state
Jenkins Pipeline
1pipeline {2 agent any3 stages {4 <span class="text-blue-400">stagespan>(<span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">'<span class="text-yellow-<span class="text-orange-400">300span>">Buildspan>'span>) {5 steps {6 sh <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">'docker build -t myapp:tag .'span>7 }8 }9 <span class="text-blue-400">stagespan>(<span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">'<span class="text-yellow-<span class="text-orange-400">300span>">Pushspan>'span>) {10 steps {11 sh <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">'docker push myapp:tag'span>12 }13 }14 <span class="text-blue-400">stagespan>(<span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">'<span class="text-yellow-<span class="text-orange-400">300span>">Deployspan>'span>) {15 steps {16 sh <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">'kubectl apply -f k8s/'span>17 sh <span <span class="text-purple-<span class="text-orange-400">400span> font-semibold">classspan>="text-green-<span class="text-orange-400">400span>">'kubectl rollout status deployment/myapp'span>18 }19 }20 }21}Managed Kubernetes Services
AWS EKS (Elastic Kubernetes Service)
- Managed control plane
- Integrated with AWS services
- Auto-scaling node groups
- IAM integration
Google GKE (Google Kubernetes Engine)
- Most feature-complete managed K8s
- Autopilot mode (fully managed)
- Best for Google Cloud ecosystem
Azure AKS (Azure Kubernetes Service)
- Free control plane
- Integrated with Azure services
- Azure Active Directory integration
- Virtual nodes (serverless)
Choosing a Platform
Use EKS if: Already on AWS, need deep AWS integration Use GKE if: Want best K8s experience, using Google Cloud Use AKS if: Microsoft ecosystem, Azure services Use Self-Managed if: Need complete control, regulatory requirements
Cost Optimization
- 1Right-size resources: Don't over-provision
- 2Use spot instances: Up to 90% savings
- 3Cluster autoscaling: Scale down when not needed
- 4Pod disruption budgets: Safe maintenance
- 5Namespace quotas: Prevent resource hogging
Common Pitfalls
- 1No resource limits: Causes node crashes
- 2Stateful apps in pods: Use StatefulSets
- 3Secrets in Git: Use secret management tools
- 4No health checks: Broken pods stay running
- 5Large images: Slow deployments
- 6Direct pod access: Always use services
Learning Path
- Build images
- Run containers
- Docker Compose
- Networking and volumes
- Pods, Deployments, Services
- kubectl commands
- Local cluster (Minikube/kind)
- StatefulSets, DaemonSets
- ConfigMaps, Secrets
- Ingress controllers
- Persistent volumes
- RBAC and security
- Monitoring and logging
- CI/CD pipelines
- Helm charts
Conclusion
Docker and Kubernetes have become essential skills for modern software engineers. Containers provide consistency and portability, while Kubernetes offers powerful orchestration at scale.
Start by containerizing a simple application with Docker, then deploy it to a local Kubernetes cluster. Once comfortable with the basics, explore managed services like EKS, GKE, or AKS for production deployments.
The ecosystem is vast, but the core concepts remain consistent. Focus on fundamentals first, then expand to advanced topics like service meshes (Istio), serverless (Knative), and edge computing.
The future of application deployment is containerized, and Kubernetes is leading the way. The time to learn is now.