Modern deployment strategies leverage containers and orchestration to achieve scalability, reliability, and efficiency. Let's explore comprehensive approaches to deploying applications using Docker and Kubernetes.
Containerization with Docker
Docker provides a consistent runtime environment across development, testing, and production.
Optimizing Docker Images
dockerfile
# Multi-stage build for smaller images
FROM node:20-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy source code
COPY . .
# Build application
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
# Copy from builder
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json ./
# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
USER nodejs
EXPOSE 3000
CMD ["node", "dist/index.js"]Docker Compose for Development
yaml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
target: development
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
- DATABASE_URL=postgres://postgres:password@db:5432/myapp
depends_on:
- db
- redis
db:
image: postgres:16-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_DB=myapp
ports:
- "5432:5432"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:Kubernetes Fundamentals
Kubernetes provides container orchestration for scaling and management.
Deployment Configuration
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels:
app: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: myapp-secrets
key: database-url
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5Service Configuration
yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
name: myapp-internal
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 3000
targetPort: 3000
type: ClusterIPAdvanced Deployment Strategies
Rolling Updates
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2 # Can create 2 extra pods
maxUnavailable: 0 # No pods should be down
template:
# ... pod templateBlue-Green Deployment
yaml
# Blue deployment (current version)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-blue
spec:
replicas: 5
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: myapp
image: myapp:v1.0.0
---
# Green deployment (new version)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-green
spec:
replicas: 5
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: myapp
image: myapp:v2.0.0
---
# Service that switches between blue and green
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
version: blue # Switch to 'green' to deploy new version
ports:
- port: 80
targetPort: 3000Canary Deployment
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-stable
spec:
replicas: 9
selector:
matchLabels:
app: myapp
track: stable
template:
metadata:
labels:
app: myapp
track: stable
spec:
containers:
- name: myapp
image: myapp:v1.0.0
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-canary
spec:
replicas: 1 # 10% of traffic
selector:
matchLabels:
app: myapp
track: canary
template:
metadata:
labels:
app: myapp
track: canary
spec:
containers:
- name: myapp
image: myapp:v2.0.0
---
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 3000ConfigMaps and Secrets
Managing Configuration
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
data:
NODE_ENV: "production"
PORT: "3000"
LOG_LEVEL: "info"
config.yaml: |
server:
port: 3000
database:
host: postgres
port: 5432
---
apiVersion: v1
kind: Secret
metadata:
name: myapp-secrets
type: Opaque
stringData:
database-url: "postgres://user:pass@postgres:5432/myapp"
api-key: "your-api-key"
jwt-secret: "your-jwt-secret"Helm Charts
Creating reusable Kubernetes packages.
yaml
# Chart.yaml
apiVersion: v2
name: myapp
description: My Application
version: 1.0.0
appVersion: "1.0.0"
# values.yaml
replicaCount: 3
image:
repository: myapp
pullPolicy: IfNotPresent
tag: "1.0.0"
service:
type: ClusterIP
port: 80
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: false
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 80Monitoring and Logging
Prometheus Monitoring
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
data:
prometheus.yml: |
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: trueConclusion
Docker and Kubernetes provide powerful tools for modern deployment strategies. Start with basic deployments, evolve to advanced strategies like blue-green and canary, and always monitor your applications for optimal performance.