GrundkonzepteBuild-Pipeline

Build-Pipeline

Builds laufen auf den Build-Nodes von Lizard — du brauchst Docker lokal nicht. Beim Bereitstellen entscheidet die Plattform anhand einer festen Reihenfolge, wie dein Quellcode in ein Container-Image umgewandelt wird, und führt dieses Image dann in einem isolierten Pod aus. Nicht jeder container as a service baut das Image für dich; der Blog vergleicht die drei Varianten, in denen diese Kategorie vorkommt.

Reihenfolge der Build-Entscheidung

Die Plattform wählt genau eine Build-Strategie, in dieser Reihenfolge:

  1. Dockerfile aus dem Repo unter dockerfilePath: Wenn dockerfilePath im Service gesetzt ist, wird dieses Dockerfile unverändert verwendet, auch wenn zusätzlich Build- oder Startbefehle gesetzt sind. Ein gesetztes startCommand ersetzt zur Laufzeit weiterhin ENTRYPOINT und CMD des Dockerfile. Siehe Mit einer Dockerfile deployen.
  2. Synthetisierte Dockerfile — andernfalls, wenn buildCommand und/oder startCommand im Service gesetzt sind (oder per lizard up --build-command / --start-command übergeben werden), erzeugt Lizard daraus eine Dockerfile. lizardpack wird nicht aufgerufen.
  3. Dockerfile im Quellcode — andernfalls wird eine Dockerfile im Stammverzeichnis des Build-Verzeichnisses verwendet (siehe die GitHub-Ausnahme unten).
  4. Automatische Erkennung durch lizardpack — andernfalls führt die Plattform lizardpack aus, den eigenen Buildpack-/Dockerfile-Generator.

Automatische Erkennung durch lizardpack

lizardpack prüft dein Repo und baut ein optimiertes Multi-Stage-Image. Unterstützte Stacks, in dieser Reihenfolge abgeglichen:

Hugo → Go → Node → Python → Rust → Ruby → PHP → Java → static

Siehe Framework-Anleitungen für Produktionsskripte, Adapter, Ausgabepfade und Ports: Hugo, Go, Node (Node.js, Next.js, Nuxt, SvelteKit, Astro, React, Vue, Docusaurus, VitePress), Python (Django, FastAPI, Streamlit) und Ruby (Rails). lizardpack erkennt den Stack anhand der Projektdateien und Abhängigkeiten. Passen mehrere Provider, gilt diese Reihenfolge. Wie du eine Node.js- oder Python-Version festlegst, steht unter Laufzeitversionen.

Auf diesem Pfad gilt:

  • Hochgeladener Quellcode (lizard up) verwendet eine Dockerfile im Stammverzeichnis immer so, wie sie geschrieben ist.
  • GitHub-Quellcode verwendet eine Dockerfile im Stammverzeichnis so, wie sie geschrieben ist, es sei denn, sie wirkt unvollständig: Sie enthält ein COPY von build, dist, out, .next oder public ohne abschließenden Schrägstrich (COPY dist /usr/share/nginx/html) und keine RUN-Zeile, die mit npm, yarn, pnpm, bun, pip, pip3, bundle, cargo, go build, mvn oder gradle beginnt. lizardpack erzeugt dann einen Ersatz.
  • Ohne Dockerfile erzeugt lizardpack eine für dich.
  • Der Startbefehl wird automatisch erkannt: eine Procfile-web:-Zeile (Python/Ruby) oder package.json scripts.start (Node) wird automatisch übernommen. Welche genaue Zeile Django, Flask und FastAPI jeweils brauchen, steht unter Python-App-Hosting.
  • Der Port wird aus EXPOSE, Framework-Standards oder einer expliziten PORT-Umgebungsvariable abgeleitet.

Wichtig: Bei GitHub-Quellcode gilt eine Dockerfile, die vorgebaute Ausgabe kopiert (COPY dist /dest) und keinen RUN-Schritt mit einem Paketmanager hat, als unvollständig und wird von lizardpack neu erzeugt. Füge einen echten Build-Schritt hinzu oder setze dockerfilePath, um die unveränderte Verwendung zu erzwingen. Siehe Dockerfile-Änderungen werden nicht übernommen.

Was einen Neuaufbau auslöst

AktionNeuaufbau?
git push in den verfolgten Branch✅ per GitHub-Webhook
lizard redeploy / lizard up✅ explizit
Ändern von Variablen für VITE_* oder NEXT_PUBLIC_*✅ baut einen laufenden Service neu; wann die Werte den Build erreichen, steht unter Build-Zeit-Variablen
service set von Build-Feldern (repoUrl, branch, sourceType, buildCommand, dockerfilePath, rootDirectory)✅ löst bei einem laufenden Service automatisch einen Neuaufbau aus; andernfalls führe lizard redeploy aus
service set von reinen Laufzeitfeldern (startCommand, preDeployCommand, containerPort, watchPatterns)❌ führe lizard redeploy aus, damit es angewendet wird
Jede andere Änderung an Umgebungsvariablen / Secrets❌ wird bei einem schnellen Neustart angewendet (kein Neuaufbau)

Nicht doppelt bauen. Nach einem service set, das bei einem laufenden Service ein Build-Feld ändert, startet der Neuaufbau automatisch. Hänge nicht noch ein lizard redeploy direkt danach an, sonst stellst du einen zweiten, überflüssigen Build in die Warteschlange (warum). Ein abgestürzter oder noch nie bereitgestellter Service wird nicht von selbst neu gebaut; führe lizard redeploy aus.

Build-Zeit-Variablen

Lizard schreibt VITE_*- und NEXT_PUBLIC_*-Variablen in zwei Fällen als ENV-Zeilen in die Dockerfile:

  • GitHub-Services ohne dockerfilePath: Die lizardpack-Dockerfile oder die Dockerfile im Stammverzeichnis des Repos erhält sie.
  • Services mit buildCommand oder startCommand, deren synthetisierte Dockerfile ein Node-Build ist.

Services, die mit lizard up und ohne Build- oder Startbefehl bereitgestellt werden, erhalten zur Build-Zeit keine Lizard-Variablen. Kein Service erhält andere Build-Argumente als COMMIT_SHA, daher bleibt ein ARG in deiner Dockerfile leer. Für öffentliche Werte mit lizard up committe sie in .env.production (prüfe, dass .gitignore die Datei nicht ausschließt), schreibe sie in deine Dockerfile oder setze bei einer Node-Server-App sowohl buildCommand als auch startCommand.

Einen Build beobachten

Build-Logs werden während lizard up gestreamt. Für jeden Service:

lizard logs --build            # the most recent build's logs
lizard events                  # deploy history + replica status

Wenn ein Build fehlschlägt, lies lizard logs --build, behebe die Ursache (in deinem Repo oder durch Anpassen von buildCommand / startCommand per lizard service set) und führe dann lizard redeploy aus.

Hinweise zur Laufzeit

  • Keine Docker-HEALTHCHECK. Die Laufzeit führt keine Docker-Healthcheck-Schleife aus, daher werden HEALTHCHECK-Direktiven ignoriert. Lizard führt stattdessen einen TCP-Probe gegen deinen Port aus (im worker mode übersprungen).
  • Schreibe nicht ungefragt eine Dockerfile. lizardpack erkennt die meisten Stacks automatisch — versuche zuerst ein Bereitstellen und füge nur dann eine Dockerfile hinzu (oder setze dockerfilePath), wenn der Auto-Build nicht passt.

Referenz der Build-Konfiguration

FeldBeschreibung
buildCommandBefehl zum Bauen deiner App → wählt den Pfad synthetisierte Dockerfile, sofern dockerfilePath nicht gesetzt ist
startCommandBefehl zum Starten deiner App zur Laufzeit; ersetzt ENTRYPOINT und CMD des Images
preDeployCommandWird zu Beginn jedes Containers ausgeführt (jedes Replikat, jeder Neustart), vor startCommand; läuft nur, wenn startCommand gesetzt ist. Sorge dafür, dass er sich mehrfach und gleichzeitig sicher ausführen lässt
dockerfilePathPfad zu einer Dockerfile im Repo, die unverändert verwendet wird; hat beim Image-Build Vorrang vor buildCommand / startCommand
rootDirectoryUnterverzeichnis, aus dem gebaut wird (Monorepos)
watchPatternsNur neu deployen, wenn sich passende Pfade ändern
containerPortTCP-Port, auf dem deine App lauscht (Standard 3000; 0 = worker)

Setze beliebige davon mit lizard service set <svc> --set <field>=<value>. Leere ein Feld mit einem leeren Wert, etwa --set buildCommand=. Siehe lizard service.

Aktualisiert