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 Element | Kubernetes Translation |
|---|---|
services | Deployment + Service |
ports | Service.spec.ports (infers ClusterIP vs NodePort) |
environment | ConfigMap for non-secrets, Secret for redacted values |
volumes | PersistentVolumeClaim + volumeMounts in Pod |
depends_on | initContainers with wait logic + readinessProbe |
healthcheck | livenessProbe 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: ClusterIPThe 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
| Tool | Strengths | Weaknesses | Best For |
|---|---|---|---|
| Helm | Rich templating, package management, reusability, large ecosystem | Steep learning curve, Go templating complexity, harder to debug | Distributing applications, multi-environment deployments at scale |
| Kustomize | Simple overlay patching, works with plain YAML, native kubectl support | Limited transformation logic, struggles with complex cross-cutting concerns | Small teams, straightforward environment overrides |
| Kanvas | Compose as source of truth, minimal Kubernetes knowledge required, automatic best practices | Generates starting point only, not suitable for existing Helm shops, limited feature coverage | Teams 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