#Docker#Kubernetes#DevOps#Helm#Cloud Native

Docker Kanvas: Bridging Compose and Kubernetes in Production

webhani·

The divide between local and production has always been the same. You define a service stack in Docker Compose, it works on your laptop, then you face the reality of Kubernetes: the Compose file is useless there. You need Deployments, Services, ConfigMaps, Secrets, PersistentVolumeClaims—all the machinery that Kubernetes expects. This gap has existed since Kubernetes became production standard, and teams have filled it with Helm, Kustomize, or handwritten YAML.

Docker Kanvas takes a different approach: keep the Compose file as the single source of truth and automatically generate the Kubernetes manifests that production needs.

The Problem Kanvas Solves

Consider a realistic local setup:

# docker-compose.yml
version: "3.9"
services:
  api:
    image: mycompany/api:latest
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgres://postgres:dev@db:5432/app
      REDIS_URL: redis://cache:6379
      LOG_LEVEL: debug
    depends_on:
      - db
      - cache
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 10s
      timeout: 5s
      retries: 3
 
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: app
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 3
 
  cache:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3
 
volumes:
  postgres_data:
  redis_data:

To deploy this to Kubernetes manually means writing at least three Deployments, three Services, two PersistentVolumeClaims, and one or two ConfigMaps. The health checks need to be translated into livenessProbe and readinessProbe configurations. Environment variables must be split into ConfigMap and Secret resources. Dependencies become initContainers or startup probes. By the time you're done, you have 300+ lines of YAML that must stay in sync with the Compose version for the next developer who joins the team.

Kanvas automates this conversion, producing production-ready manifests from your existing Compose definition.

What Kanvas Generates

The mapping is mechanical but thoughtful:

Compose ElementKubernetes Translation
servicesDeployment + Service
portsService.spec.ports (infers ClusterIP vs NodePort)
environmentConfigMap for non-secrets, Secret for redacted values
volumesPersistentVolumeClaim + volumeMounts in Pod
depends_oninitContainers with wait logic + readinessProbe
healthchecklivenessProbe and readinessProbe
build context(Not yet supported; assumes pre-built images)

For the Compose file above, Kanvas would generate something like:

# Generated by Kanvas — api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      initContainers:
      - name: wait-for-db
        image: busybox:1.35
        command: ['sh', '-c', 'until nc -z db 5432; do echo waiting for db; sleep 2; done']
      - name: wait-for-cache
        image: busybox:1.35
        command: ['sh', '-c', 'until nc -z cache 6379; do echo waiting for cache; sleep 2; done']
      containers:
      - name: api
        image: mycompany/api:latest
        ports:
        - containerPort: 8000
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: api-secrets
              key: database-url
        - name: REDIS_URL
          valueFrom:
            configMapKeyRef:
              name: api-config
              key: redis-url
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: api-config
              key: log-level
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 15
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 2
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: api
spec:
  selector:
    app: api
  ports:
  - protocol: TCP
    port: 8000
    targetPort: 8000
  type: ClusterIP

The generated manifests include reasonable resource requests and limits inferred from typical workload patterns. Dependencies are resolved into proper startup and readiness probes rather than naive depends_on sequencing.

How Kanvas Compares to Helm and Kustomize

ToolStrengthsWeaknessesBest For
HelmRich templating, package management, reusability, large ecosystemSteep learning curve, Go templating complexity, harder to debugDistributing applications, multi-environment deployments at scale
KustomizeSimple overlay patching, works with plain YAML, native kubectl supportLimited transformation logic, struggles with complex cross-cutting concernsSmall teams, straightforward environment overrides
KanvasCompose as source of truth, minimal Kubernetes knowledge required, automatic best practicesGenerates starting point only, not suitable for existing Helm shops, limited feature coverageTeams transitioning from Compose to Kubernetes, rapid MVP deployment

Helm is a package manager with a templating layer. It excels at distributing reusable application packages, but the learning curve is steep. Go template syntax adds friction, and debugging template errors consumes more time than it should.

Kustomize patches plain YAML files using overlays. It's simple to learn and works well for straightforward scenarios—different namespaces, image tags, replica counts. But complex transformations (conditional logic, computed values, cross-file references) push you back to writing Helm or accepting repetition.

Kanvas enters the market with a premise: if you already have working Compose files, don't rewrite them. Convert them. This appeals directly to teams that have invested in Compose but need Kubernetes without the Helm/Kustomize learning curve.

The trade-off is clear: Kanvas-generated manifests are functional starting points. Production-grade features—HorizontalPodAutoscaler, PodDisruptionBudget, NetworkPolicy, RBAC, Ingress with TLS termination—must be added manually. You're not avoiding Kubernetes complexity; you're deferring the learning until later.

Practical Workflow

Converting a Compose file:

# Install Kanvas CLI
docker install kanvas
 
# Convert the Compose file
kanvas convert docker-compose.yml --output ./k8s/
 
# Review and adjust generated manifests
ls ./k8s/
# api-deployment.yaml
# api-service.yaml
# db-deployment.yaml
# db-pvc.yaml
# cache-deployment.yaml
# cache-pvc.yaml
# configmaps.yaml
# secrets.yaml
 
# Apply to your cluster
kubectl apply -k ./k8s/

Before committing the secrets file, replace the base64-encoded values with references to a proper secrets management system (AWS Secrets Manager, HashiCorp Vault, External Secrets Operator).

When Kanvas Makes Sense

Use Kanvas if:

  • Your team uses Docker Compose locally but has no Kubernetes tooling yet
  • You need to get a production deployment running this week, not this quarter
  • Your application is small to medium-sized, with standard components (stateless API + database + cache)
  • Your team wants to learn Kubernetes incrementally, not sink time into Helm syntax

Stick with Helm or Kustomize if:

  • You already maintain mature Helm charts—the migration cost outweighs the benefit
  • Your workload relies on Custom Resource Definitions (Istio gateways, Operators, etc.)
  • You deploy to multiple Kubernetes clusters with significantly different configurations
  • Your organization has Kubernetes expertise and strong opinions about how infrastructure should be versioned

Webhani's Take

Kanvas fits a real need: it lowers the activation energy for Compose-to-Kubernetes transitions. For small teams without a dedicated DevOps person, or for consulting clients who want to run a pilot on Kubernetes without hiring new expertise, Kanvas is a practical shortcut.

However, it's not a replacement for Helm or Kustomize. It's a bridge. Once you've deployed with Kanvas and understand your production topology, you may eventually migrate to Helm if you need better package management across multiple clusters, or stick with Kanvas if it continues to meet your needs.

The broader 2026 trend—AWS EKS Auto, Karpenter, kro, now Kanvas—is about making Kubernetes simpler and less visible. The infrastructure should be boring. Kanvas contributes to that goal by letting developers who know Compose think about containers, not YAML manifests.

Takeaways

  • Kanvas automates the Compose-to-Kubernetes conversion, filling a real gap for teams moving from local to production
  • Generated manifests are idiomatic Kubernetes but require manual additions for production features (HPA, PDB, RBAC, networking policies)
  • It offers a different entry point than Helm or Kustomize, suitable for teams without existing Kubernetes infrastructure
  • Best used as a starting point for new Kubernetes deployments, not a migration tool for mature Helm-based workflows
  • The value increases with team size: the less Kubernetes expertise you have, the more Kanvas saves you