Share
๐Ÿ’ฌ WhatsApp๐• Post
โ˜๏ธ Cloud & DevOpsIntermediateโฑ 14 min read

Docker to Kubernetes: The Complete Enterprise Production Deployment Playbook

A production-grade guide to containerizing full-stack web applications with multi-stage Dockerfiles and orchestrating zero-downtime deployments on Kubernetes.

Docker to Kubernetes: The Complete Enterprise Production Deployment Playbook
โ˜๏ธCloud & DevOps
LEARNTRIX VISUAL
100% Free Knowledgeโ€ขโฑ 14 min deep read
โœฆ Shareable Infographic Guide
๐Ÿ“… Published: 15 July 2026|VSumit Lakhtariya
๐Ÿ“– ELIF8 Explainedยฉ Learntrix

Header Ad Advertisement

In modern enterprise software engineering, the phrase "it works on my local machine" has been permanently eliminated by containerization.

However, running a single docker run command on an individual virtual machine is vastly different from managing a high-availability, fault-tolerant cluster serving millions of concurrent requests across multiple availability zones.

This playbook provides a hands-on, battle-tested migration path from building lightweight, hardened Docker images to deploying production-ready Kubernetes manifests with zero-downtime rolling updates.


1. Step 1: Writing a Production-Grade Multi-Stage Dockerfile

A common novice mistake is copying the entire project directory (including node_modules, compilers, test runners, and source TypeScript files) into a single-stage runtime image, resulting in massive 1+ GB images riddled with security vulnerabilities.

The 3-Stage Distroless / Alpine Pattern (Node.js / Next.js / NestJS):

# -------------------------------------------------------------
# Stage 1: Base & Dependency Installation
# -------------------------------------------------------------
FROM node:22-alpine AS deps
WORKDIR /app
RUN apk add --no-cache libc6-compat
COPY package.json package-lock.json ./
RUN npm ci --frozen-lockfile

# -------------------------------------------------------------
# Stage 2: Production Build
# -------------------------------------------------------------
FROM node:22-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NODE_ENV=production
RUN npm run build

# -------------------------------------------------------------
# Stage 3: Minimal Hardened Runtime
# -------------------------------------------------------------
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=3000

# Security: Create a non-privileged system user (Never run as root!)
RUN addgroup --system --gid 1001 nodejs && \
    adduser --system --uid 1001 appuser

COPY --from=builder --chown=appuser:nodejs /app/public ./public
COPY --from=builder --chown=appuser:nodejs /app/.next/standalone ./
COPY --from=builder --chown=appuser:nodejs /app/.next/static ./.next/static

USER appuser
EXPOSE 3000
CMD ["node", "server.js"]
Image Size Reduction:
โŒ Single-stage build: 1,320 MB (1.32 GB)
โœ… Multi-stage standalone build: 82 MB (94% image weight eliminated!)

2. Step 2: Local Multi-Service Development with Docker Compose

Before deploying to Kubernetes, validate that your application seamlessly communicates with its supporting infrastructure (PostgreSQL database, Redis cache, RabbitMQ) using a declarative docker-compose.yml:

version: '3.8'

services:
  web-app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://postgres:secret123@db:5432/production_db
      - REDIS_URL=redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: secret123
      POSTGRES_DB: production_db
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  cache:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  postgres_data:

3. Step 3: Kubernetes Architecture Core Primitives

When transitioning from Docker Compose to Kubernetes, services map to declarative API objects:

[ Ingress Controller (Nginx / Traefik / AWS ALB) ]
                      โ”‚ (SSL Termination & Host Routing)
                      โ–ผ
        [ Kubernetes Service (ClusterIP) ]
                      โ”‚ (Internal Load Balancing across Pods)
                      โ–ผ
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ–ผ                โ–ผ                โ–ผ
[ Pod 1 (v1.4) ] [ Pod 2 (v1.4) ] [ Pod 3 (v1.4) ] โ”€โ”€ (Managed by Deployment ReplicaSet)

4. Step 4: The Production Kubernetes Deployment Manifest

Here is an enterprise-grade Kubernetes manifest implementing zero-downtime rolling updates, resource constraints, and health probes:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: learntrix-api-deployment
  namespace: production
  labels:
    app: learntrix-api
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Creates 1 new pod before killing an old pod
      maxUnavailable: 0  # Guarantees 100% capacity during deployments
  selector:
    matchLabels:
      app: learntrix-api
  template:
    metadata:
      labels:
        app: learntrix-api
    spec:
      containers:
        - name: learntrix-api
          image: registry.vyuhantrix.com/learntrix-api:v2.4.1
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 3000
          
          # 1. Mandatory Resource Limits
          resources:
            requests:
              cpu: "250m"       # 0.25 CPU Core guaranteed
              memory: "256Mi"   # 256 MB RAM guaranteed
            limits:
              cpu: "1000m"      # Throttled at 1 full CPU Core
              memory: "512Mi"   # OOMKilled if memory leaks above 512 MB

          # 2. Readiness Probe: Checks if app finished DB migrations
          readinessProbe:
            httpGet:
              path: /api/health/ready
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 5

          # 3. Liveness Probe: Checks if server loop is deadlocked
          livenessProbe:
            httpGet:
              path: /api/health/live
              port: 3000
            initialDelaySeconds: 15
            periodSeconds: 10

5. Step 5: Kubernetes Service & Ingress Routing

To expose these pods securely to internal services and the global internet:

apiVersion: v1
kind: Service
metadata:
  name: learntrix-api-service
  namespace: production
spec:
  type: ClusterIP
  selector:
    app: learntrix-api
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: learntrix-ingress
  namespace: production
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    kubernetes.io/ingress.class: nginx
spec:
  tls:
    - hosts:
        - api.learntrix.com
      secretName: learntrix-api-tls
  rules:
    - host: api.learntrix.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: learntrix-api-service
                port:
                  number: 80

6. Step 6: Horizontal Pod Autoscaler (HPA)

To automatically scale pods during sudden viral traffic surges without human intervention:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: learntrix-api-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: learntrix-api-deployment
  minReplicas: 3
  maxReplicas: 25
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
When CPU utilization exceeds 70% across running pods, Kubernetes automatically provisions 
additional pods in seconds and adds them to the ingress load balancer.

๐Ÿ’ก

Production Golden Rule

Always configure maxUnavailable: 0 in your rolling update strategy and implement strict readinessProbe endpoints so that a pod is only registered in the load balancer once all database connection pools and caches are completely warmed up.

Mid Content Ad Advertisement

Editorial Disclaimer

The information in this article is provided for educational and informational purposes only. While we strive for accuracy, content may become outdated as technologies, regulations, and best practices evolve. Learntrix and Vyuhantrix make no warranties regarding the completeness, accuracy, or applicability of the information to your specific situation. Always verify critical information from primary and authoritative sources before implementation.

Last content review: September 2026 ยท Learntrix by Vyuhantrix

ยฉ

Copyright 2026 Vyuhantrix Technologies. All content on Learntrix is the intellectual property of Vyuhantrix. Reproduction, distribution, or republishing of this article โ€” in whole or in part โ€” without written permission from Vyuhantrix is strictly prohibited.

Tags:#docker#kubernetes#devops#cloud#containers#k8s#microservices

Footer Article Ad Advertisement