Warum wir eigene Cloud Native Buildpacks auf Ubuntu 26.04 gebaut haben
Kurz gesagt
- Nodion baut Git-Apps mit eigenen Cloud Native Buildpacks auf dem Stack nodion-26, basierend auf Ubuntu 26.04 LTS; das sind nicht Paketo-, Heroku- oder Google-Buildpacks.
- Zwölf in Go geschriebene Buildpacks decken Node.js, statische Sites, Ruby, Python, PHP, Go, Rust, Elixir, Java und .NET ab, plus Procfiles und extra Debian-Pakete.
- Nodion hält eine Sprachlinie, solange sie nicht end-of-life ist, und bis zu drei Monate danach, und eine angeforderte Minor-Version bekommt ihren neuesten veröffentlichten Patch.
- Die Detection prüft 14 Gruppen der Reihe nach und beherrscht polyglotte Apps wie Laravel mit Vite oder Rails mit JS; Details stehen in den Buildpacks-Docs.
Nodion baut Git-Apps mit eigenen Cloud Native Buildpacks. Wir folgen der Cloud-Native-Buildpacks-Spezifikation für Detect, Build und Launch, aber Stack, Language-Buildpacks und Runtime-Versionen sind unsere. Der Stack heißt nodion-26 und basiert auf Ubuntu 26.04 LTS. Das sind nicht Paketo-, Heroku- oder Google-Buildpacks. Darum haben wir sie gebaut, und das bedeutet das für deine Builds.
Buildpacks in 30 Sekunden
Ein Buildpack macht aus Quellcode ein Container-Image ohne Dockerfile. Es erkennt die Sprache, installiert eine Runtime und die Dependencies, baut die App und setzt einen Startbefehl. Cloud Native Buildpacks sind der offene Standard dafür. Ein Builder bündelt die Buildpacks, den Lifecycle, der sie ausführt, und die Base Images für Build und Run. Neu im Thema? Starte mit Cloud Native Buildpacks erklärt.
Warum keinen bestehenden Builder wiederverwenden?
Paketo, Heroku und Google veröffentlichen alle Cloud Native Buildpacks, und das sind solide Projekte. Eines davon zu nehmen wäre der Shortcut gewesen.
Wir haben uns dagegen entschieden, weil der Builder für eine Plattform kein Detail ist. Er entscheidet, auf welchem Betriebssystem deine App läuft, welche Runtime-Versionen es gibt, wie eine Version gewählt wird und was passiert, wenn eine Version end-of-life erreicht. Das sind Produktentscheidungen, die unsere User bei jedem Deploy spüren. Wir wollten sie in der eigenen Hand, an einem Ort festgehalten und über Sprachen hinweg identisch.
Was wir gebaut haben
Ein Stack auf Ubuntu 26.04 LTS
Der Stack nodion-26 hat zwei Images. Das Build-Image trägt Compiler und Header. Das Run-Image trägt die Client-Libraries, die Apps häufig brauchen, etwa die Postgres- und MySQL-Clients, ImageMagick und CA-Zertifikate. Dein Prozess läuft als Non-Root-User.
Wir haben Ubuntu 26.04 gewählt, weil es das neueste LTS-Release ist. Canonical hat es im April 2026 veröffentlicht und listet Standard-Security-Maintenance bis Mai 2031, die Basis unter deiner App hat also einen langen Lauf, bevor der nächste große Umzug ansteht.
Zwölf Buildpacks, eine Codebase
Es gibt zwölf Buildpacks: Node.js, statische Sites, Ruby, Python, PHP, Go, Rust, Elixir, Java und .NET, plus eines für Procfiles und eines für extra Debian-Pakete. Alle sind in Go gegen libcnb geschrieben, die Go-Library des Cloud-Native-Buildpacks-Projekts, und leben in einem Modul. Sie teilen eine einzige Library für Versionsauflösung, Downloads und Logging, ein Versionspin, eine Fehlermeldung oder ein Download-Check funktioniert also in jeder Sprache gleich.
Detection, die polyglotte Apps kennt
Der Builder prüft 14 Gruppen von oben nach unten, und die erste Gruppe, deren erforderliche Dateien alle da sind, gewinnt. Die Reihenfolge zählt bei echten Projekten:
- Ein statisches JavaScript-Frontend wird mit Node.js gebaut und dann vom Static-Buildpack ausgeliefert.
composer.jsonpluspackage.jsonbekommt PHP und Node.js in einem Build (zum Beispiel Laravel mit Vite).Gemfilepluspackage.jsonbekommt Ruby und Node.js (Rails mit JS-Pipeline).- Dann einzelne Sprachen, ein standalone Node.js-Server, eine reine statische Site und zuletzt eine App nur mit Procfile.
Extra Debian-Pakete sind ein optionaler Teil jeder Gruppe, jede App kann sie also ergänzen.
Unsere eigene Runtime-Pipeline
Welche Runtimes existieren, steht in einer Versionsmatrix in unserem Repository. Ein stündlicher Job prüft End-of-Life-Daten und neue Releases, wendet die Support-Politik an und öffnet einen Pull Request, der die Matrix aktualisiert. Ist der gemergt, wird jede fehlende Runtime-Version gebaut und veröffentlicht, und Apps holen sie beim nächsten Build.
Ruby, Python, PHP und Erlang werden aus dem Source auf unserem Build-Image kompiliert. Die anderen Runtimes werden aus Upstream-Binaries neu verpackt. Wenn ein Build eine Runtime lädt, prüft er die Datei gegen ihre veröffentlichte Checksum, bevor er sie entpackt.
Was du bekommst
Eine Versionspolitik, die in einen Absatz passt
Wir halten eine Sprachlinie, solange sie nicht end-of-life ist, und bis zu drei Monate danach. Fordere eine Minor-Version an, und du bekommst den neuesten veröffentlichten Patch dieser Minor. Eine Version unter der ältesten veröffentlichten Linie scheitert als end-of-life, eine Version neuer als alles bisher Gebaute scheitert als noch nicht verfügbar. In beiden Fällen stoppt der Build mit einer klaren Meldung statt still eine andere Version zu nutzen.
Go und Rust sind die Ausnahme: die neueste veröffentlichte Toolchain baut die App, und ältere Werte in go.mod oder rust-version kompilieren weiter.
| Sprache | Default | Veröffentlichte Linien (September 2026) |
|---|---|---|
| Node.js | 24 | 22, 24, 25, 26 |
| Python | 3.13 | 3.10 bis 3.14 |
| PHP | 8.3 | 8.2 bis 8.5 |
| Ruby | 3.4 | 3.3, 3.4, 4.0 |
| Go | 1.26 | Neueste Toolchain (1.25 bis 1.27) |
| Rust | 1.96 | Neueste Toolchain (1.95 bis 1.98) |
| Java | 21 | 11, 17, 21, 25, 26 |
| .NET | 10 | 8, 9, 10 |
| Elixir | 1.20 | 1.15 bis 1.20 (Erlang/OTP 26 bis 29) |
Patches wandern, sobald wir sie veröffentlichen. Jede Sprachseite erklärt, wie du eine Version pinnst, zum Beispiel mit .node-version oder .python-version.
Escape Hatches, wo du sie brauchst
- Procfile: definiere eigene Process Types. Jeder Typ wird ein eigener Prozess auf der App, und Sprachdefaults gelten nur, wenn es kein Procfile gibt.
- Extra Systempakete: liste Debian-Pakete in
project.toml(oder einerAptfile). Sie werden ins Image extrahiert; Maintainer-Skripte laufen nicht. - Monorepos: zeige das Basisverzeichnis auf den App-Ordner.
[com.nodion.buildpacks.deb-packages]
install = ["ffmpeg", "pandoc"] Was wir nicht geändert haben
Die Spezifikation. Detect, Build und Launch funktionieren wie auf jeder Cloud-Native-Buildpacks-Plattform, und das Ergebnis ist ein normales OCI-Image. Nodion nutzt standardmäßig den eigenen Builder, und du kannst einen anderen wählen, wenn du das bevorzugst. Hat dein Repository bereits ein Dockerfile oder ist kein unterstützter Sprachbaum, nutze das. Unsicher, was passt? Siehe Dockerfile vs Buildpacks.
Zum Ausprobieren verbinde ein Repository unter Applications → New, wähle Buildpacks und stelle sicher, dass deine App auf PORT hört. Alles Weitere steht in den Buildpacks-Docs.
Häufige Fragen
Welche Buildpacks nutzt Nodion?
Nodions eigene Cloud Native Buildpacks auf dem Stack nodion-26 (Ubuntu 26.04 LTS). Sie folgen der Cloud-Native-Buildpacks-Spezifikation, aber Language-Buildpacks, Stack und Runtime-Versionen sind Nodions, nicht Paketo, Heroku oder Google.
Welche Sprachen unterstützen Nodion-Buildpacks?
Node.js, Python, Ruby, PHP, Go, Rust, Elixir, Java, .NET und statische Sites, plus Apps nur mit Procfile. Extra Debian-Pakete lassen sich mit project.toml oder einer Aptfile ergänzen.
Wie lange unterstützt Nodion eine Sprachversion?
Eine Sprachlinie bleibt verfügbar, solange sie nicht end-of-life ist, und bis zu drei Monate danach. Go und Rust bauen immer mit der neuesten veröffentlichten Toolchain, die auch älteren Code kompiliert.
Kann ich auf Nodion ein Dockerfile statt Buildpacks nutzen?
Ja. Nutze ein Dockerfile, wenn dein Repository schon eines hat oder kein unterstützter Sprachbaum ist, und Nodion baut und betreibt dieses Image.