Sechseinhalb Monate nach der ersten Ankündigung, 22 Betas und 2 RCs später: incus-compose ist 1.0.0.
Drei Rewrites endete mit einem Satz, den ich wieder aufgreifen will. „go-orb: drei Jahre Arbeit. Keine Nutzer. incus-compose: zwei Monate. Mehrere." Das ist so geblieben. Leute haben es benutzt, kaputt gemacht, Issues aufgemacht — und der Core aus Der Core soll nichts wissen hat einfach aufgesogen, was sie ihm entgegengeworfen haben. Neue Ressourcen, neue Randfälle, ohne dass der Core selbst sich ändern musste.
1.0 heißt: die Befehle, die man von Docker Compose kennt, gibt es jetzt auch hier. up, down, start, stop, restart, logs, exec. Es zieht Images von docker.io und ghcr.io, baut lokal über Podman oder Docker, macht Health-Checks und Restart-Policies über einen kleinen Sidecar namens ic-healthd, und schiebt UID/GID bei Volumes, damit Bind-Mounts sich vernünftig verhalten. Nichts davon ist exotisch. Compose hat diese Probleme schon gelöst — ich musste sie nur nach Incus bringen, ohne zu verlieren, was Incus zu Incus macht: System-Container, VMs, echte Isolation.
Irgendwo um beta19 brauchte @blurry einen CIFS-Netzwerkshare in einem Container. Incus’ normales Disk-Device konnte das nicht idmappen — der Kernel hat sich geweigert. Ich hab dafür keine CIFS-Unterstützung gebaut. x-incus ließ ihn rohe LXC-Config direkt in die Instanz legen, lxc.mount.entry = ... rbind,idmap=container, an incus-compose vorbei, nur für dieses eine Device. Als idmap trotzdem quer schoss, war der eigentliche Fix kleiner: ein Opt-out vom Shifting, damit der Mount gar kein idmap braucht. Das ist die ganze Philosophie von x-incus — den Wrapper bauen, aber die Tür nach unten nie zuschweißen.
Was ich nicht eingeplant hatte: Windows und macOS. incus-compose und der incus-Client sind reine Go-Binaries. Kein Docker Desktop, kein WSL, keine lokale Linux-VM — man zeigt von einem Windows-Laptop aus über HTTPS auf einen entfernten Incus-Host, und es läuft.
Was noch fehlt, zeigt sich erst, wenn echte Nutzung die Kanten glattgeschliffen hat. healthd pollt noch, statt auf Incus’ eigene Event-API zu hören. Es gibt noch keinen backup-Befehl. run, pause/unpause, port sind noch offen — klein genug für einen ersten Beitrag.
@bketelsens Proof-of-Concept war der Anfang. @stgraber hat das Projekt in die lxc-Organisation geholt. @pyrodogg hat das Bind-Mount-Seeding-Problem gefunden — Host-Dateien stillschweigend in ein Volume zu kopieren kappt die Verbindung zum Original-Verzeichnis, der falsche Default für eine Medienbibliothek — und daraus ein Opt-in gemacht. @blurry ist unmanaged Bridges und CIFS-Shares nachgejagt, bis USB- und GPU-Passthrough existierten, für ein Frigate-NVR-Setup auf Hardware, die ich selbst nicht besitze. @Sagi, @neitsab, @kgoetz, @edorgeville, @bburky — 22 Betas sind dazu da, kaputt gemacht zu werden, und ihr habt meins auf Wegen kaputt gemacht, die ich allein nie gefunden hätte.
Stunden vor dem Release ist Brian wieder im Thread aufgetaucht — der, dessen Proof-of-Concept das alles losgetreten hat, monatelang still. „It looks like you’ve solved all of the really big problems." Das ist der ganze Bogen in einem Satz, von dem, dessen eigene Version nie so weit gekommen ist.
Ich betreibe das selbst in Produktion: Immich, Wiki.js, LeafWiki, Gitea, Caddy, Kimai, ein DNS-Stack. Das ist die Testsuite, die zählt.
Boring, ausgeliefert.
Von René Jochum und Claude (Anthropic). Lizenz: CC-BY-4.0.
