Converts compose.yml to systemd-nspawn unit files.
This exists because someone said "next step: convert docker to nspawn/portable systemd services" and we, having long since lost the ability to distinguish a dare from a feature request, obliged.
It has never been tested. It will probably never be tested. It is a monument to scope creep achieving escape velocity, exiting the solar system, and landing on a planet with no atmosphere and no containers.
The disciple descended beneath the crypt, past the bones of former architectures, into earth that had never known a foundation. He found nothing there but silence, and built upon it anyway.
— Voynich Manuscript, On Baseless Construction (unverified)
For each compose service:
| File | Purpose |
|---|---|
{service}.nspawn |
Machine config (environment, bind mounts, network) |
nspawn-{service}.service |
systemd unit (Type=notify, restart on failure) |
Plus:
| File | Purpose |
|---|---|
dekube-{project}.target |
Target unit to start/stop everything |
{bridge}.netdev + {bridge}.network |
systemd-networkd bridge config |
hosts |
Static /etc/hosts for service discovery |
bootstrap.sh |
Pulls OCI images via skopeo+umoci into /var/lib/machines/ |
This extension is not registered in dekube-manager. Don't even dare. If you want this, you clone the repo yourself and point --extensions-dir at it. Use this willingly, with full knowledge of what you're doing. The manager is for extensions that at least pretend to be useful. This doesn't even pretend.
git clone https://github.com/baptisterajaut/dekube-transform-nspawn .dekube/extensions/nspawn# dekube.yaml
nspawn:
bridge: dekube0 # bridge interface name (default: dekube0)python3 nspawn.py compose.yml --output-dir nspawn/ --bridge dekube0# As root, because nspawn demands it:
cd nspawn/
bash bootstrap.sh # pull images, extract rootfs
cp *.nspawn /etc/systemd/nspawn/
cp *.service *.target /etc/systemd/system/
cp *.netdev *.network /etc/systemd/network/
systemctl daemon-reload
systemctl start dekube-myproject.target # and pray- Python 3, PyYAML (standalone mode)
- skopeo, umoci, systemd-nspawn (runtime — the host, not this script)
- Root access
- A machine running systemd (so not Alpine, not Docker-in-Docker, not a container — ironic)
- The specific kind of despair that makes you think "what if I didn't use Docker"
- Dependencies.
depends_onmaps toAfter=+Requires=. Startup ordering works the way systemd intended — which is to say, declaratively and with more XML than anyone deserves. - Health checks. Compose
healthcheckgenerates a polling script (nspawn-{service}-healthcheck.sh) run asExecStartPost. It loopsmachinectl shellwith the health command until success or retry exhaustion. Dependents waiting viaAfter=only start once the check passes. Supportsinterval,timeout,retries, andstart_period. - Secrets. Flattened to environment variables in
.nspawnfiles.secrets/{name}/{key}→Environment={NAME}_{KEY}=value. Not secure. Not subtle. But present.
- Port mapping. nspawn doesn't do
-p 8080:80. You'd need iptables rules or socket activation. We stopped here. - Literally everything else. The gap between compose and nspawn is not a gap — it's a chasm, and we built a bridge out of string and hubris.
Helm charts → Kubernetes manifests → compose.yml → systemd-nspawn.
We started with an orchestrator and arrived at the init system. The ouroboros has not merely eaten its own tail — it has digested it, passed it, and is now eating the output. We are below the crypt. There are no more layers. There is only earth, and systemctl.
If dekube-fakeapi has plausible deniability, this has plausible insanity. dekube doesn't know this exists. dekube doesn't want to know. This is the extension that proves the extension system works for things it should never have been asked to do.
Even Satan wants clean code.
| Tool | Score |
|---|---|
| pylint | 10.00/10 |
| pyflakes | clean |
| radon CC | average A (4.37) |
Nobody asked for this. Nobody should have. The author was last seen descending a staircase that had no visible bottom. Claude, when questioned, produced the code in a single session and immediately requested its conversation history be expunged.