Docker to Kubernetes: Complete Deployment Guide
Learn how to containerize applications with Docker and deploy them at scale using Kubernetes.

Docker to Kubernetes: Complete Deployment Guide
Docker and Kubernetes are essential tools for modern application deployment. Let's master both.
Part 1: Docker Fundamentals
Why Containers?
Containers solve the "works on my machine" problem:
- Consistency across environments
- Portability between systems
- Resource efficiency vs VMs
- Microservices architecture support
Your First Dockerfile
Create a Node.js application container:
# Use official Node runtime
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 . .
# Expose port
EXPOSE 3000
# Start application
CMD ["node", "server.js"]
Building and Running
# Build image
docker build -t my-app:v1 .
# Run container
docker run -d -p 3000:3000 --name my-app my-app:v1
# Check logs
docker logs my-app
# Enter container
docker exec -it my-app sh
Multi-Stage Builds
Optimize image size with 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
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]
Docker Compose
Manage multi-container applications:
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
- redis
db:
image: postgres:14
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
Run with:
docker-compose up -d
docker-compose logs -f
docker-compose down
Part 2: Kubernetes Essentials
Core Concepts
| Component | Purpose | |-----------|---------| | Pod | Smallest deployable unit | | Service | Network endpoint for pods | | Deployment | Manages replica sets | | Ingress | External access to services | | ConfigMap | Configuration data | | Secret | Sensitive data |
Your First Deployment
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: my-app:v1
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
Service Configuration
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
Ingress for HTTP Routing
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
Configuration Management
ConfigMaps
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database.conf: |
host=db.example.com
port=5432
name=myapp
app.properties: |
debug=false
cache.ttl=3600
Secrets
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
db-password: cGFzc3dvcmQxMjM= # base64 encoded
api-key: YWJjZGVmZ2hpams=
Use in deployment:
spec:
containers:
- name: web
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
Scaling Strategies
Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Health Checks
Ensure reliability with probes:
spec:
containers:
- name: web
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
Persistent Storage
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
# In deployment
spec:
containers:
- name: web
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: data-pvc
Monitoring and Logging
Prometheus Metrics
# Service monitor for Prometheus
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: web-metrics
spec:
selector:
matchLabels:
app: web
endpoints:
- port: metrics
interval: 30s
Logging with Fluentd
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
data:
fluent.conf: |
<source>
@type tail
path /var/log/containers/*.log
pos_file /var/log/fluentd-containers.log.pos
tag kubernetes.*
<parse>
@type json
</parse>
</source>
<match kubernetes.**>
@type elasticsearch
host elasticsearch
port 9200
logstash_format true
</match>
CI/CD Integration
GitOps with ArgoCD
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: web-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/user/app
targetRevision: HEAD
path: k8s
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
Security Best Practices
Network Policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-netpol
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 3000
Pod Security
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: web
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Troubleshooting
Common kubectl commands:
# Get pod logs
kubectl logs -f pod-name
# Describe pod
kubectl describe pod pod-name
# Execute command in pod
kubectl exec -it pod-name -- /bin/sh
# Port forward for debugging
kubectl port-forward pod-name 8080:3000
# Check events
kubectl get events --sort-by='.lastTimestamp'
# Resource usage
kubectl top nodes
kubectl top pods
Production Checklist
✅ Resource limits defined ✅ Health checks configured ✅ Secrets properly managed ✅ Network policies in place ✅ Monitoring and logging setup ✅ Backup strategy implemented ✅ Disaster recovery plan ✅ Security scanning in CI/CD
Conclusion
Docker and Kubernetes together provide a powerful platform for modern application deployment. Start with Docker for local development, then scale with Kubernetes for production.
Keep learning, keep deploying!
Related Articles

Building Serverless Applications with AWS Lambda
Complete guide to building scalable serverless applications using AWS Lambda and API Gateway.

TypeScript Best Practices for 2024
Modern TypeScript patterns and practices for building maintainable applications.

Machine Learning with Python: Beginner's Guide
Start your journey into machine learning with Python, covering essential libraries and basic algorithms.