The VM Config Drift Problem
Docker solved the "works on my machine" problem. With VMs, you have to build it twice: once for development and once for production. You might also need to build it for CI, test, etc.
You spend days getting the perfect development environment - services configured, databases tuned, everything working together. Then deployment time comes and your development setup has conveniences baked in: default users, insecure keys, debug tools, dev-friendly assumptions.
Production can't use any of it. You start over with a clean base image and completely different provisioning scripts, rebuilding everything you already built.
Development VMs become throwaway sandboxes that can't be used anywhere else. You perfect something in dev, then start over for production with different tools, different configs, different everything.
This creates a fundamental disconnect. Your development environment is optimized for developer convenience - default users, debug tools, development-friendly networking. Production environments need security hardening, monitoring, compliance configurations.
Current tools handle this by making development and production completely separate worlds. Vagrant excels at developer environments with convenient boxes and simple orchestration. Production uses different tools entirely - Terraform, cloud-init, enterprise orchestration platforms.
The result? You spend time perfecting configurations that require complex workarounds to reuse. Knowledge doesn't transfer easily between environments. Development becomes a sandbox that requires translation for production.
Docker Model for VM Configs
There's a new tool called eryph that takes a different approach.
Docker lets you build an image locally, push it to a registry, then pull that exact same image in production. Same layers, same configs, everything identical.
Eryph does something similar, but for VM configurations instead of container images. You create these things called "genes" that are basically reusable VM config chunks. A gene might configure nginx, another might set up your app stack. You compose them together like Docker layers.
But unlike Vagrant boxes that are environment-specific, eryph genes work everywhere. The nginx config I write for development is the exact same nginx config that runs in production.
Shared Configs in Action
Let me show you how this actually works.
Say I'm building a web app that needs nginx. In development, I want the convenience stuff - a default user I can SSH as, maybe some debug tools. In production, I need the same nginx config but with security hardening and monitoring.
In my development environment:
# dev-server.yaml
name: nginx-dev
parent: dbosoft/ubuntu-22.04/latest # Neutral base
fodder:
# Dev convenience
- source: gene:dbosoft/starter-food:linux-starter
- source: gene:myorg/nginx-config # SHARED CONFIG
- source: gene:myorg/app-stack # SHARED CONFIG
In production, I use the exact same base and the exact same app configs:
# prod-server.yaml
name: nginx-prod
parent: dbosoft/ubuntu-22.04/latest # Same neutral base
fodder:
- source: gene:myorg/nginx-config # Same nginx config
- source: gene:myorg/app-stack # Same app config
- source: gene:myorg/prod-hardening # Production additions
- source: gene:myorg/monitoring # Production additions
The nginx and app stack genes are identical between dev and production. Only the environment-specific stuff changes.
When I fix a bug in the nginx config or optimize something, both environments get the improvement automatically. No rebuilding production from scratch, no manual syncing, no wondering if dev and prod have drifted apart.
Why This Works Better
It's basically like Docker layers, but for VMs. Instead of rebuilding everything for each environment, you compose from shared pieces.
The traditional way wastes so much work:
- Development: Vagrant box with custom scripts, throw it all away later
- Production: Start over with different base image, different scripts
With eryph, you build on shared foundations:
- Development: Neutral base + dev conveniences + your app configs
- Production: Same neutral base + same app configs + production hardening
Try It Yourself
Want to see how this works? Let me walk through setting up a shareable config.
First, install eryph. It runs on Windows with Hyper-V:
# Run in elevated PowerShell
irm https://raw.githubusercontent.com/eryph-org/eryph/main/src/apps/src/Eryph-zero/install.ps1 | iex
If you are on MacOs/Linux you can still use eryph via powershell commands - but you need a shared machine with eryph-zero somewhere.
Now I'll create a web server config that could work in both dev and production:
# web-config.yaml
name: shared-webserver
parent: dbosoft/ubuntu-22.04/latest
fodder:
- source: gene:dbosoft/starter-food:linux-starter
- name: nginx-setup
type: cloud-config
content:
package_update: true
packages:
- nginx
write_files:
- path: /var/www/html/index.html
content: |
<h1>Shared Config Works!</h1>
<p>This same config runs in dev and production</p>
runcmd:
- systemctl enable nginx
- systemctl start nginx
Deploy and test it:
# Deploy the VM
Get-Content web-config.yaml | New-Catlet | Start-Catlet
# Get IP and test
$ip = (Get-Catlet | `
Where-Object Name -eq "shared-webserver" | `
Get-CatletIp).IpAddress
start "http://$ip"
That web server config would work identically in production, just with different surrounding genes for hardening and monitoring.
No more maintaining separate configs that slowly drift apart. No more rebuilding the same nginx setup three different ways for dev, staging, and production.
The configs become portable and shareable, like Docker images but for full VMs. You can push your proven nginx fodder as a custom gene to the eryph genepool, someone else can pull it and layer their app on top, everyone benefits from improvements.
It works with whatever tools you're already using too. If you're a Vagrant user, there's a vagrant-eryph provider. PowerShell users get native cmdlets. There's even a GUI app if you prefer that.
The VMs built by eryph can be used directly with an on-premises Hyper-V installation or uploaded to Azure. For other platforms, the configuration is available as a generated cloud-init ISO, which is compatible with all platforms and images that support cloud-init.
Want to try it? The Quickstart has everything you need to get started, and you can browse existing configs at genepool.eryph.io. The whole thing is open source and free for development work.
Top comments (0)