Was tatsächlich in Ihre Umgebungen ausgeliefert wird (und warum das wichtig ist)

Stellen Sie sich vor: Ihr Team hat gerade einen Sprint abgeschlossen. Alle sind erschöpft, aber das Release muss heute Nacht raus. Ein Entwickler baut die Anwendung auf seinem Laptop, testet sie lokal und schiebt das Artefakt ins Staging. Die Staging-Tests bestehen. Die Zuversicht ist groß.

Dann sagt jemand: „Ich baue für die Produktion nochmal neu, nur um sicherzugehen. Ich packe den aktuellen Konfigurations-Fix mit rein.“

Der Produktions-Build unterscheidet sich vom Staging-Build. Anderer Zeitstempel. Andere Kompilierung. Vielleicht wurde eine leicht abweichende Bibliotheksversion eingezogen.

Eine Stunde später geht die Produktion down. Jetzt haben Sie eine Frage, die Sie nicht beantworten können: Liegt der Bug im Code, der anders war, oder in der Umgebungskonfiguration? Sie haben die Gewissheit verloren.

Das ist das Problem, das unveränderliche Artefakte lösen. Aber bevor wir dazu kommen, sprechen wir darüber, was ein Artefakt eigentlich ist.

Quellcode ist nicht das, was auf Servern läuft

Wenn Entwickler Code schreiben, produzieren sie Quellcode. Dieser Quellcode ist Rohmaterial. Es ist menschenlesbarer Text, der transformiert werden muss, bevor ein Server ihn ausführen kann.

Dieser Transformationsprozess heißt Build. Und die Ausgabe eines Builds nennt man Artefakt.

Wie ein Artefakt aussieht, hängt davon ab, was Sie bauen:

  • Eine Java-Anwendung produziert eine .jar- oder .war-Datei.
  • Eine Python-Anwendung produziert eine Wheel-Datei oder einen gepackten Ordner.
  • Eine Node.js-Anwendung produziert einen dist-Ordner mit minifizierten Dateien.
  • Eine Go-Anwendung produziert eine einzelne binäre ausführbare Datei.

In jedem Fall ist das Artefakt eine Sammlung von Dateien, die bereit sind, auf einem Server abgelegt und ausgeführt zu werden. Keine Kompilierung nötig. Keine Abhängigkeitsauflösung. Einfach ausführen.

Die Build-Pipeline produziert das Artefakt

Im modernen Software-Delivery läuft der Build-Prozess automatisch ab. Ein Entwickler pusht Code in ein Repository. Eine CI-Pipeline wird getriggert. Sie kompiliert den Code, führt Tests aus und produziert ein Artefakt. Dieses Artefakt wird dann an Umgebungen gesendet – beginnend mit Staging, dann Produktion und allem dazwischen.

Hier ist ein visueller Vergleich des korrekten Ansatzes mit dem riskanten Anti-Pattern:

flowchart TD A["Quellcode"] --> B["Build"] B --> C["Artefakt"] C --> D["Artefakt-Repository"] D --> E["Staging"] E --> F["Produktion"] B -.-> G["Neubau für Staging"] G -.-> H["Artefakt A"] H -.-> I["Staging"] B -.-> J["Neubau für Produktion"] J -.-> K["Artefakt B"] K -.-> L["Produktion"] style A fill:#e6f3ff,stroke:#333 style B fill:#e6f3ff,stroke:#333 style C fill:#d4edda,stroke:#333 style D fill:#d4edda,stroke:#333 style E fill:#d4edda,stroke:#333 style F fill:#d4edda,stroke:#333 style G fill:#f8d7da,stroke:#333 style H fill:#f8d7da,stroke:#333 style I fill:#f8d7da,stroke:#333 style J fill:#f8d7da,stroke:#333 style K fill:#f8d7da,stroke:#333 style L fill:#f8d7da,stroke:#333

Hier haben die meisten Teams eine Wahl. Und die meisten Teams treffen die falsche Wahl, ohne es zu merken.

Das Problem mit dem Neubau für jede Umgebung

Hier ist ein häufiges Muster: Für Staging bauen, testen, dann für Produktion neu bauen. Die Logik klingt vernünftig – „wir wollen sicherstellen, dass die Produktion den frischesten Build bekommt.“

Aber dieses Muster schafft ein verstecktes Risiko. Jeder Build ist ein kleines bisschen anders. Der Compiler könnte eine andere Ausgabe produzieren. Abhängigkeiten könnten in leicht unterschiedlichen Versionen aufgelöst werden. Der Build-Zeitstempel ändert sich. Selbst die Reihenfolge der Dateischreibvorgänge kann variieren.

Wenn die Produktion ausfällt, haben Sie zwei Variablen: das Artefakt und die Umgebung. Sie können nicht sagen, welche das Problem verursacht hat. Lag es an der Code-Änderung oder an etwas in der Produktionsumgebung, das das Staging nicht hatte?

Sie haben die Gewissheit verloren. Und Gewissheit ist das Wertvollste, was Sie während eines Incidents haben können.

Unveränderliche Artefakte stellen die Gewissheit wieder her

Ein unveränderliches Artefakt ist eines, das sich nach dem Bau nie mehr ändert. Sobald der Build es produziert hat, ist dieses Artefakt eingefroren. Keine Modifikationen. Keine Neubauten. Keine manuellen Bearbeitungen.

Dasselbe Artefakt – gleicher Hash, gleiche Größe, gleiche Dateien – geht in jede Umgebung, die diese Version ausführt.

Das gibt Ihnen eine mächtige Garantie: Wenn das Artefakt die Tests im Staging bestanden hat, wird es sich in der Produktion genauso verhalten, vorausgesetzt die Umgebungen sind ähnlich konfiguriert. Wenn die Produktion ausfällt, wissen Sie, dass das Problem nicht im Artefakt liegt. Es liegt in der Konfiguration, den Daten oder der Umgebung selbst.

Hier ist eine schnelle Möglichkeit zu überprüfen, ob dasselbe Artefakt überall deployed wurde:

# Auf dem Build-Rechner nach Abschluss des Builds
sha256sum myapp-v1.2.3.jar
# Ausgabe: a1b2c3d4e5f6...  myapp-v1.2.3.jar

# Auf dem Staging-Server nach dem Deployment
sha256sum /opt/myapp/myapp-v1.2.3.jar
# Ausgabe: a1b2c3d4e5f6...  /opt/myapp/myapp-v1.2.3.jar

# Auf dem Produktions-Server nach dem Deployment
sha256sum /opt/myapp/myapp-v1.2.3.jar
# Ausgabe: a1b2c3d4e5f6...  /opt/myapp/myapp-v1.2.3.jar

Wenn die Prüfsummen übereinstimmen, haben Sie überall das exakt gleiche Artefakt deployed.

Sie haben eine Variable eliminiert. Das macht das Debugging schneller und sicherer.

Unveränderliche Artefakte machen Rollbacks einfach

Wenn Sie unveränderliche Artefakte haben, wird ein Rollback trivial. Wenn die neue Version kaputt geht, müssen Sie die alte Version nicht neu bauen. Sie müssen nicht den richtigen Commit finden und die Pipeline erneut anstoßen. Sie deployen einfach das Artefakt, das bereits existiert.

Dieses Artefakt wurde vor Wochen oder Monaten gebaut. Es wurde getestet. Es ist schon einmal in der Produktion gelaufen. Sie wissen genau, was es tut. Sie holen es einfach aus dem Speicher und deployen es.

Ohne unveränderliche Artefakte bedeutet ein Rollback, den alten Code neu zu bauen. Dieser Neubau könnte ein anderes Artefakt produzieren als das, das ursprünglich lief. Sie deployen etwas, das in seiner aktuellen Form noch nie getestet wurde. Das ist ein Glücksspiel.

Wo speichern Sie Artefakte?

Artefakte brauchen einen zentralen, sicheren und zuverlässigen Speicherort. Das nennt man Artefakt-Repository. Übliche Optionen sind:

  • Nexus oder Artifactory für allgemeine Artefakt-Speicherung
  • Docker Registry für Container-Images
  • S3-Buckets oder Azure Blob Storage für rohe Artefakt-Dateien
  • Package-Registries wie npm, PyPI oder Maven Central

Jedes Artefakt sollte mit Metadaten gespeichert werden: Versionsnummer, Commit-Hash, Build-Zeitstempel und relevante Tags. Diese Metadaten ermöglichen es, jedes Artefakt zurück zu seinem Quellcode und seiner Build-Pipeline zu verfolgen.

Das Artefakt-Repository wird zur einzigen Quelle der Wahrheit dafür, was wo läuft. Wenn jemand fragt „Welche Version läuft gerade in der Produktion?“, schauen Sie auf das Artefakt, nicht auf den Server.

Was an Umgebungen ausgeliefert wird

Nachdem der Build abgeschlossen ist, wird nur das Artefakt an die Umgebungen gesendet. Nicht der Quellcode. Keine neu gebaute Version. Keine manuell bearbeitete Datei.

Ein Artefakt für alle Umgebungen. Konsistent, nachvollziehbar und unveränderlich.

Dieses Prinzip gilt, ob Sie einen Java-Microservice, eine Python-Daten-Pipeline, ein Node.js-Frontend oder ein Go-CLI-Tool deployen. Das Verpackungsformat ändert sich, aber die Idee bleibt dieselbe: Einmal bauen, überall deployen.

Eine kurze Checkliste für Ihr Team

Wenn Sie Ihre Artefakt-Strategie einrichten oder überprüfen, hier ein paar Dinge, die Sie verifizieren sollten:

  • Jeder Build produziert ein versioniertes Artefakt mit einer eindeutigen Kennung (Commit-Hash, Build-Nummer oder semantische Version)
  • Dasselbe Artefakt wird ohne Neubau durch alle Umgebungen promoted
  • Artefakte werden in einem zentralen Repository gespeichert, nicht auf Entwickler-Laptops oder Build-Servern
  • Alte Artefakte werden mindestens für die Dauer Ihres Rollback-Fensters aufbewahrt
  • Metadaten (Commit-Hash, Build-Zeitstempel, Trigger-Grund) sind an jedes Artefakt angehängt

Die Erkenntnis

Wenn Ihr Team das nächste Mal ein Release vorbereitet, stellen Sie eine Frage: Ist das Artefakt, das im Staging läuft, exakt dieselbe Datei, die in der Produktion laufen wird? Wenn die Antwort nein ist, führen Sie ein Risiko ein, das Sie nicht messen können. Beheben Sie das zuerst, bevor Sie sich um irgendetwas anderes kümmern.

Einmal bauen. Dasselbe Artefakt überall deployen. Es unveränderlich halten. Diese eine Praxis wird mehr Produktionsausfälle verhindern als die meisten Monitoring-Tools es jemals könnten.