
Weg von Fly.io

Bei Sliplane betreiben wir Managed Docker Hosting. Eine unserer wichtigsten Infrastruktur-Anforderungen ist es, isolierte, schnelle und reproduzierbare Docker-Builds für Kunden-Deployments laufen zu lassen. Anfangs haben wir Fly.io für diese Builds benutzt. Es hat funktioniert – bis es nicht mehr funktionierte.
Hier erzähle ich, was kaputt ging, wie wir es ersetzt haben und warum unser neues Setup besser ist.
Warum Fly.io erstmal wie das richtige Tool wirkte
Als wir anfingen, brauchten wir:
- Vollständig isolierte VMs pro Build
- Schnelle Startzeiten
- Persistente Volumes für Docker Layer Caching
- Auto-Suspend und Resume, um Kosten zu sparen
Fly.io hat genau das versprochen:
- Firecracker als Basis
- Einfache VM-Isolation pro App
- Wake-on-Request Funktionalität
- Persistente Volumes mit Auto-Skalierung bis zu 500 GB
Also haben wir für jeden Kunden eine eigene Fly-App gestartet. Builds wurden per HTTP ausgelöst, Fly hat die VM hochgefahren. Caching hat funktioniert, Startzeiten waren okay – insgesamt fühlte sich das sauber an.
Was kaputt ging (immer wieder)
Als echten Traffic kam, passierte Folgendes:
- VMs booteten nicht mehr, weil angeblich keine Kapazität da war
- Suspended Apps wachten nicht zuverlässig auf
- Manche VMs sind einfach abgestürzt, ohne Logs oder Recovery
- Wir haben geheime Limits getroffen, zum Beispiel die maximale Anzahl an Apps
Am Ende sind etwa 10 Prozent aller Builds ohne Fehler im Kunden-Code fehlgeschlagen. Wir haben Retrys, Workarounds und Logging eingebaut, aber Fly’s Probleme konnten wir nicht beheben.
Warum es einfach nicht passte
Fly ist eigentlich für kleine, stateless Web-Apps optimiert. Unsere Builds sind das nicht:
- 16 bis 32 GB RAM pro VM
- Persistente Volumes, die über Sessions hinweg genutzt werden
- Starkes Abhängigkeitsverhalten von Suspend und Resume
Fly’s internes Ressourcen-Management ist nicht für solche Workloads gemacht. Auch wenn sie jetzt AI-Agent-Workloads bewerben, die ähnlich klingen – unsere Erfahrungen sagen uns, Vorsicht ist geboten.
Warum nicht einfach einen Service kaufen?
Es gibt Plattformen, die sich auf schnelle, isolierte Docker-Builds spezialisiert haben, wie Depot. Für viele Teams ist das super.
Für uns passte es aber nicht.
Depot verlangt 4 Cent pro Build-Minute und 20 Cent pro GB im Monat für Storage. Das ist vier- bis fünfmal mehr, als wir selbst zahlen, wenn wir es selbst betreiben. Unser Geschäftsmodell funktioniert nicht mit nutzungsabhängiger Abrechnung.
- Wir berechnen unseren Kunden pro Server, nicht pro Build
- Wenn wir Depot-Preise zahlen würden, machen wir bei buildstarken Nutzern Verlust
- Extra Kosten pro Build-Minute würden den Prozess kompliziert und abschreckend machen
Wir wollen, dass Builds frei wirken und die Abrechnung einfach bleibt. Dafür müssen wir die Kosten kontrollieren.
Also haben wir es selbst gebaut.
Was wir jetzt laufen lassen
Wir haben alles auf Firecracker aufgebaut, auf bare metal Hardware:
- Eine dedizierte MicroVM pro Kunde
- NVMe-Backed Volumes für schnellen I/O
- RAM- und CPU-Overcommit direkt auf Hardware-Ebene
- Einen eigenen minimalen Orchestrator in Go, etwa 4000 Zeilen Code
Wir fahren nur wenige Builds gleichzeitig, meistens nur ein paar pro Server. Builds sind naturgemäß bursty: Sie brauchen für kurze Zeit viel CPU und warten dann auf I/O. Perfekt für Ressourcenteilung. Selbst bei Spitzenlast sind unsere Server nur zu etwa 20 Prozent ausgelastet. Einfach, vorhersehbar und besser als jeder Autoscaler, den wir ausprobiert haben.
Unser Orchestrator macht nur das, was wir brauchen:
- Firecracker MicroVMs starten
- Schnelle persistente Volumes mounten
- Builds planen und verwalten
- Automatisch aufräumen nach Nutzung
Weil es genau für diesen Zweck gebaut ist, lassen wir alles weg, was wir nicht brauchen. Kein Service-Discovery. Kein Pod-Networking. Keine ständig laufenden VMs. Einfach VM starten, Build ausführen und VM löschen.
Vorteile und was wir gewinnen
- Keine Kapazitätsfehler, weil wir die Hardware „besitzen“ (wir mieten bare metal Server, teilen sie aber nicht)
- Keine versteckten Limits, weil wir den Scheduler selbst schreiben
- Schnellere Builds mit besserem I/O und weniger Cold Starts
- Volle Observability
- Vorhersehbares Laufzeitverhalten
- Keine Überraschungen von Drittanbietern
- Günstiger pro Build – etwa 20 bis 30 Prozent der Fly-Kosten
Wir haben auf globale Vernetzung und PaaS-Komfort verzichtet, dafür mehr Kontrolle und Zuverlässigkeit gewonnen. Unsere Kunden legen mehr Wert darauf, dass Builds funktionieren, als darauf, an welchem Edge-Standort sie laufen.
Kompromisse
Was wir dabei verloren haben:
- Globales Routing
- Eingebaute Deployment-Tools
- Zero-Config Infrastruktur
Solltest Du das auch machen?
Fly.io ist eine gute Wahl für:
- MVPs und Side-Projekte
- Kleine, kurzzeitige Apps
- Stateless Workloads
- Apps, die globales Routing brauchen
Es passt weniger gut für:
- CI- oder Build-Systeme
- Alles mit großem RAM- oder Volumen-Bedarf
- Infrastruktur mit State und hohen Performance-Anforderungen
Probier Fly erst mal aus. Aber teste mit echter Nutzung. Nimm nicht einfach an, dass es skaliert, nur weil es am Anfang einfach wirkt. Ja, das ist definitiv unser Fehler, dass wir nicht früher gründlicher getestet haben
Abschließende Gedanken
Wir hatten nicht vor, Fly zu ersetzen. Es hat einfach nicht mehr für uns funktioniert.
Also haben wir unsere eigene Infrastruktur auf bare metal mit Firecracker gebaut.
Es war mehr Arbeit, aber das Ergebnis ist simpel. Unsere Builds fallen jetzt nur noch aus, wenn der Kunden-Code fehlerhaft ist.
Jonas Co-Founder, Sliplane.io
Kleiner Hinweis: Wir betreiben auch einen konkurrierenden Service. Trotzdem mag ich viele Teile von Fly und nutze es für andere interne Zwecke. Dieser Beitrag dreht sich nur um einen Fall, der nicht geklappt hat – völlig normal :)