Migration Guide: docker-compose to Skaffold + Helm
This guide helps you migrate from the existing docker-compose development workflow to the new Skaffold + Helm setup.
Overview
Before: docker-compose up started all services locally After: skaffold dev deploys services to a local Kubernetes cluster
Migration Steps
Phase 1: Parallel Operation (Recommended)
Run both systems side-by-side during the transition:
# Keep using docker-compose while learning Skaffold
docker-compose up -d
# In another terminal, try Skaffold
minikube start --memory=4096 --cpus=2
skaffold dev --profile=minimalPhase 2: Team Migration
- Setup Meeting: Review new workflow with the team
- Documentation: Share this guide and development-skaffold.md
- Pair Sessions: Have experienced users help others
- Gradual Adoption: Start with minimal profile, add services
Phase 3: Full Migration
- Update Documentation: Change README.md to reference Skaffold
- Update CI/CD: Modify build scripts to use Helm charts
- Deprecate docker-compose: Add deprecation notice
- Remove docker-compose: After team is comfortable
Service Mapping
docker-compose Services → Kubernetes Resources
| docker-compose | Kubernetes Resource | Helm Template |
|---|---|---|
control-plane | Deployment + Service | templates/control-plane/ |
agent | Deployment | templates/agent/ |
db | PostgreSQL subchart | Bitnami PostgreSQL |
permify | Deployment + Service | templates/permify/ |
ovn-northd | Deployment | templates/ovn/northd-deployment.yaml |
ovn-nb-db | StatefulSet + Service | templates/ovn/nb-db-statefulset.yaml |
ovn-sb-db | StatefulSet + Service | templates/ovn/sb-db-statefulset.yaml |
openvswitch | DaemonSet | templates/ovs/daemonset.yaml |
Configuration Migration
Environment Variables
Before (docker-compose.yml):
services:
control-plane:
environment:
DATABASE_URL: postgresql://strato:password@db:5432/strato
PERMIFY_URL: http://permify:3476After (helm/strato/values-dev.yaml):
controlPlane:
env:
WEBAUTHN_RELYING_PARTY_ORIGIN: "http://localhost:30080"
LOG_LEVEL: "debug"
# DATABASE_URL and PERMIFY_URL auto-generated from templatesVolume Mounts
Before (docker-compose.yml):
services:
control-plane:
volumes:
- ./control-plane:/app
- db_data:/var/lib/postgresql/dataAfter:
- Source code: Skaffold file sync
- Database: Kubernetes PersistentVolumes
- Configuration: ConfigMaps and Secrets
Networking
Before: Docker bridge network with service names After: Kubernetes service discovery with DNS
| Before | After |
|---|---|
http://permify:3476 | http://strato-permify:3476 |
postgresql://db:5432 | postgresql://strato-postgresql:5432 |
ws://control-plane:8080 | ws://strato-control-plane:8080 |
Command Migration
Starting Services
# Before
docker-compose up
# After
skaffold devViewing Logs
# Before
docker-compose logs -f control-plane
# After
kubectl logs -f deployment/strato-control-plane
# Or: skaffold dev (shows all logs)Executing Commands
# Before
docker-compose exec control-plane swift run migrate
# After
kubectl exec -it deployment/strato-control-plane -- swift run migrateStopping Services
# Before
docker-compose down
# After
skaffold delete
# Or: Ctrl+C if running skaffold devRebuilding Images
# Before
docker-compose build
docker-compose up
# After
# Automatic rebuild on file changes, or:
skaffold buildDevelopment Workflow Changes
Code Changes
Before:
- Edit source files
docker-compose restart control-plane- Check logs with
docker-compose logs
After:
- Edit source files
- Skaffold automatically detects changes and rebuilds
- Logs stream automatically in terminal
Database Access
Before:
docker-compose exec db psql -U strato -d stratoAfter:
kubectl exec -it strato-postgresql-0 -- psql -U strato -d stratoDebugging
Before:
docker-compose exec control-plane /bin/bashAfter:
kubectl exec -it deployment/strato-control-plane -- /bin/bashConfiguration Differences
Resource Usage
docker-compose: Uses host resources directly Kubernetes: Resource limits/requests defined in values.yaml
# helm/strato/values-dev.yaml
controlPlane:
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 512Mi
cpu: 500mEnvironment Isolation
docker-compose: Shared host network and filesystem Kubernetes: Isolated namespaces and network policies
Service Discovery
docker-compose: Container names resolve automatically Kubernetes: Service names with namespace suffix
Troubleshooting Migration Issues
"Service not accessible"
Problem: Can't reach services after migration
Solution:
# Check service status
kubectl get services
kubectl get pods
# Use port-forwarding for testing
kubectl port-forward service/strato-control-plane 8080:8080"Database connection failed"
Problem: Control plane can't connect to PostgreSQL
Solution:
# Check PostgreSQL pod
kubectl get pods | grep postgresql
kubectl logs strato-postgresql-0
# Verify connection string
kubectl describe configmap strato-control-plane-config"Performance is slower"
Potential Causes:
- Insufficient minikube resources
- Image rebuilding instead of file sync
- Resource limits too low
Solutions:
# Increase minikube resources
minikube config set memory 6144
minikube config set cpus 4
minikube delete && minikube start
# Check Skaffold file sync is working
# Should see "File sync succeeded" in logs"Networking issues between services"
Problem: Services can't communicate
Solution:
# Check service discovery
kubectl exec -it deployment/strato-agent -- nslookup strato-control-plane
# Check NetworkPolicies (shouldn't be any in development)
kubectl get networkpolicies
# Verify service endpoints
kubectl get endpointsRollback Plan
If you need to rollback to docker-compose:
# Stop Skaffold environment
skaffold delete
# Stop minikube (optional)
minikube stop
# Return to docker-compose
docker-compose up -dBenefits After Migration
- Production Parity: Same Helm charts for dev and production
- Better Resource Management: Kubernetes resource limits
- Service Isolation: Each service in its own container/namespace
- Easier Scaling: Can scale individual services
- Better Monitoring: Kubernetes-native metrics and logs
- Team Consistency: Everyone uses the same Kubernetes setup
Team Training Checklist
- [ ] Install required tools (kubectl, helm, skaffold, minikube)
- [ ] Complete quick start guide
- [ ] Practice basic kubectl commands
- [ ] Test hot-reload workflow
- [ ] Learn log viewing and debugging
- [ ] Practice troubleshooting common issues
- [ ] Update local development documentation
FAQ
Q: Why migrate from docker-compose? A: Production parity, better resource management, team consistency, easier scaling.
Q: Is this more complex than docker-compose? A: Initially yes, but provides more control and better matches production environment.
Q: Can I still use docker-compose for some development? A: Yes, during transition period. Eventually we'll remove docker-compose.yml.
Q: What if I don't want to run all services? A: Use SKAFFOLD_PROFILE=minimal or disable services in values-dev.yaml.
Q: How do I reset everything? A: skaffold delete && minikube delete && minikube start