Skip to main content

Migration Guide: Docker Compose to Kubernetes

Docker Compose excels for development and simple deployments, but production environments demand the scalability, high availability, and operational automation that Kubernetes provides. However, migrating from Docker Compose to Kubernetes is not just about rewriting YAML. Success requires understanding the fundamental architectural differences in networking, storage, and secret management.

Kubo provides production-grade Kubernetes infrastructure and supports smooth migrations from Docker Compose. This article walks through every phase of the migration process.

Fundamental Differences Between Docker Compose and Kubernetes

Before starting a migration, understanding the architectural differences between the two systems is essential.

AspectDocker ComposeKubernetes
ScopeSingle hostMulti-node cluster
ScalingManual (scale option)Automatic (HPA / VPA)
Health Checkshealthcheck directiveliveness / readiness / startup Probes
NetworkingBridge networksService / Ingress / NetworkPolicy
StorageBind mounts / volumesPersistentVolume / PersistentVolumeClaim
Secrets.env files / secretsSecret / External Secrets Operator
Service DiscoveryContainer/service namesDNS-based Services
Rolling UpdatesNoneDeployment strategy

The Kubernetes official documentation introduces the conversion process using Kompose, but this is only a starting point.

Captain.AI can assist your migration process with AI — from analyzing Docker Compose files to optimizing Kubernetes manifests.

Phase 1: Assessment and Architecture Audit

The first step is thoroughly analyzing your current Docker Compose configuration.

Checklist

  • Service dependencies: Map startup order defined by depends_on
  • Volume mappings: Distinguish development bind mounts (./src:/app) from persistent data
  • Network configuration: Identify custom networks and inter-service communication
  • Environment variables: Catalog .env files, environment directives, and secrets
  • Build contexts: Identify build directives (K8S requires pre-built images)
  • Resource constraints: Note mem_limit, cpus, and similar settings
yaml
# Typical Docker Compose configuration
services:
  web:
    build: ./web
    ports:
      - "8080:8080"
    environment:
      - database_url=postgres:--db:5432-myapp
    depends_on:
      - db
    volumes:
      - .-web:-app  # development bind mount
  
  db:
    image: postgres:16
    volumes:
      - db-data:-var-lib-postgresql-data
    environment:
      - POSTGRES_PASSWORD=secret

volumes:
  db-data:

Critical: Development bind mounts (./web:/app) cannot be migrated to Kubernetes. Application code must be included in the image. The SFEIR migration guide emphasizes this point.

Phase 2: Automated Conversion with Kompose

Kompose automatically converts Docker Compose files into Kubernetes manifests.

Installation

bash
# macOS
brew install kompose

# Linux
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-linux-amd64 -o kompose
chmod +x kompose && sudo mv ./kompose /usr/local/bin/kompose

Basic Conversion

bash
# Convert docker-compose.yml to Kubernetes manifests
kompose convert

# Example output:
# INFO Kubernetes file "web-service.yaml" created
# INFO Kubernetes file "db-service.yaml" created
# INFO Kubernetes file "web-deployment.yaml" created
# INFO Kubernetes file "db-deployment.yaml" created
# INFO Kubernetes file "db-data-persistentvolumeclaim.yaml" created

Kompose generates two Kubernetes resources from each Docker Compose service: a Deployment and a Service. Volumes are converted to PersistentVolumeClaims.

Customization with Kompose Labels

yaml
services:
  web:
    image: myapp:latest
    ports:
      - "8080:8080"
    labels:
      kompose.service.type: LoadBalancer
      kompose.service.expose: "myapp.example.com"
      kompose.image-pull-policy: Always

However, as the Support Tools migration guide points out, Kompose "creates a functional base but is rarely optimal for production," necessitating refinement in the next phase.

Phase 3: Production-Ready with Helm / Kustomize

Elevate Kompose-generated manifests to production quality using Helm or Kustomize.

Migrating to Helm Charts

bash
# Scaffold a Helm chart
helm create myapp

# Directory structure
myapp/
  Chart.yaml
  values.yaml
  templates/
    deployment.yaml
    service.yaml
    ingress.yaml
    hpa.yaml

Externalize environment-specific settings in values.yaml:

yaml
# values.yaml
replicaCount: 3
image:
  repository: harbor.example.com/myproject/web
  tag: "1.0.0"
  pullPolicy: IfNotPresent
resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 128Mi
ingress:
  enabled: true
  hosts:
    - host: myapp.example.com
      paths:
        - path: /
          pathType: Prefix

Essential Additions

Add production-critical configurations that Kompose doesn't auto-generate:

yaml
# Health checks (Probes)
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 10
readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5

# Resource limits
resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 512Mi

# Pod Disruption Budget
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: web

On Kubo's Kubernetes environment, Helm chart deployments are the standard workflow.

Phase 4: Storage and Network Migration

Storage Migration

Map Docker Compose volumes to Kubernetes PersistentVolumeClaims (PVCs):

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: db-data
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 10Gi

Consider using StatefulSets for database persistence. StatefulSets provide stable network identities and persistent storage, making them ideal for database workloads.

Secret Management

Migrate .env file secrets to Kubernetes Secrets:

bash
# Create a Secret
kubectl create secret generic db-credentials \
  --from-literal=POSTGRES_PASSWORD=secure-password

# Or integrate with external secret stores via External Secrets Operator

For integration with HashiCorp Vault or AWS Secrets Manager, the External Secrets Operator is recommended.

Networking

Docker Compose's service-name-based communication migrates to Kubernetes DNS-based service discovery:

yaml
# Docker Compose: DATABASE_URL=postgres://db:5432/myapp
# Kubernetes:     DATABASE_URL=postgres://db-service.default.svc.cluster.local:5432/myapp

Phase 5: Testing and Gradual Rollout

The final migration phase involves staged rollouts and validation.

Migration Testing Strategy

  1. Staging environment validation: Full functional testing before production migration
  2. Load testing: Validate under production-equivalent load using k6 or Locust
  3. Canary deployment: Route a portion of traffic to the new environment for gradual migration
  4. Rollback plan: Prepare procedures to immediately revert to the old environment if issues arise
yaml
# Canary deployment example
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-canary
spec:
  replicas: 1  # Only a portion of traffic
  selector:
    matchLabels:
      app: web
      track: canary

For medium-sized applications, plan 2-4 weeks for the complete migration. The dasroot migration guide recommends a similar timeline.

Summary: A Planned Path to Production Kubernetes

Migrate from Docker Compose to Kubernetes through these five planned phases:

  1. Assessment: Inventory Docker Compose configuration and map dependencies
  2. Automated Conversion: Generate initial manifests with Kompose
  3. Production-Ready: Add Probes, resource limits, and Ingress with Helm/Kustomize
  4. Storage & Network Migration: Configure PVCs, Secrets, and Services
  5. Gradual Rollout: Staging validation, canary deployments, and load testing

Kubo provides the ideal Kubernetes infrastructure as a migration target from Docker Compose. With Captain.AI's AI assistance, the entire migration process is supported — from Kubernetes manifest generation to operations automation.

If you're considering a migration to Kubernetes, please contact us.

← Back to all posts