Container Images sicher zwischen Stufen bewegen
Image Promotion beschreibt, wie ein bereits gebautes Docker Image kontrolliert von Staging nach Produktion wandert, ohne neu gebaut zu werden. Retagging, Digest-Pinning und manuelle Freigaben ersetzen den fragilen Reflex, bei jedem Deploy einfach neu zu bauen und zu hoffen, dass nichts anders ist.
Inhaltsverzeichnis
- 1. Was Image Promotion von einem einfachen Deploy unterscheidet
- 2. Retagging statt Rebuild: das technische Grundprinzip
- 3. Digest-Pinning: Tags sind veränderlich, Digests nicht
- 4. Promotion zwischen mehreren Registries
- 5. Promotion-Gates: manuelle Freigaben und automatische Checks
- 6. Eine vollständige Promotion-Pipeline in GitLab CI
- 7. Nachvollziehbarkeit: welches Image lief wann wo
- 8. Typische Fehler bei der Image Promotion
- 9. Promotion-Strategien im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Was Image Promotion von einem einfachen Deploy unterscheidet
Image Promotion bezeichnet den kontrollierten Prozess, ein bereits gebautes und getestetes Docker Image von einer Umgebung in die nächste zu befördern, typischerweise von Staging nach Produktion, ohne es dabei neu zu bauen. Der Unterschied zu einem einfachen Deploy liegt in der Absicherung: Image Promotion beinhaltet in der Regel Freigabeschritte, Nachweise über bestandene Tests und eine unveränderliche Referenz auf genau das Artefakt, das befördert wird. Ein einfacher Deploy-Befehl ohne diese Kontrollen kann versehentlich ein anderes Image ausrollen als das, was tatsächlich getestet wurde.
Der Grund, warum Image Promotion als eigenständiges Konzept betrachtet werden sollte, liegt in der Rolle der Container Registry als Wahrheitsquelle. Anders als bei klassischen Artefakt-Repositories für JAR- oder ZIP-Dateien speichert eine Registry Images unter Tags, die standardmäßig veränderlich sind. Ein Tag wie staging kann jederzeit auf ein anderes Image zeigen. Image Promotion muss deshalb explizit dafür sorgen, dass die Referenz, die befördert wird, stabil und eindeutig bleibt, meist über einen Digest oder einen unveränderlichen Versions-Tag.
In gewachsenen Docker-Setups sieht man häufig, dass Image Promotion informell über Slack-Nachrichten oder manuelle SSH-Befehle abläuft. Das funktioniert eine Weile, bricht aber bei Personalwechsel oder Zeitdruck zusammen. Ein strukturierter Promotion-Workflow mit klaren Gates in der CI-Pipeline macht diesen Prozess wiederholbar, auditierbar und unabhängig von einzelnen Personen, die den genauen Ablauf im Kopf haben.
2. Retagging statt Rebuild: das technische Grundprinzip
Das technische Fundament von Image Promotion ist Retagging: Statt ein Image für die Zielumgebung neu zu bauen, wird derselbe Image-Inhalt lediglich mit einem neuen Tag versehen und in die Registry gepusht, oder es wird direkt auf denselben Digest referenziert. docker tag erzeugt keinen neuen Layer und keine neuen Bytes, es fügt nur einen zusätzlichen Namen für dieselbe Image-ID hinzu. Genau diese Eigenschaft macht Image Promotion sicher: Es gibt keine Möglichkeit, dass beim Retagging Code verändert wird.
Werkzeuge wie crane oder skopeo gehen bei Image Promotion einen Schritt weiter als das native docker tag, weil sie Images direkt zwischen Registries kopieren können, ohne sie lokal herunterzuladen und wieder hochzuladen. Das ist besonders relevant, wenn die Zielregistry in einem anderen Netzwerk oder bei einem anderen Cloud-Anbieter liegt. Für reines Retagging innerhalb derselben Registry reicht in den meisten Fällen ein einfacher docker pull, docker tag, docker push-Dreiklang.
#!/usr/bin/env bash
# promote.sh -- promote an existing image to a new stage tag, no rebuild
set -euo pipefail
SOURCE_TAG="${1:?Usage: promote.sh <source-tag> <target-tag>}"
TARGET_TAG="${2:?Usage: promote.sh <source-tag> <target-tag>}"
IMAGE="registry.example.com/myapp"
echo "[promote] Pulling ${IMAGE}:${SOURCE_TAG}"
docker pull "${IMAGE}:${SOURCE_TAG}"
# Retag -- zero new bytes, same digest, only a new reference
docker tag "${IMAGE}:${SOURCE_TAG}" "${IMAGE}:${TARGET_TAG}"
docker push "${IMAGE}:${TARGET_TAG}"
echo "[promote] ${SOURCE_TAG} -> ${TARGET_TAG} done, same content"
# Cross-registry copy without a local docker daemon (using crane)
# crane copy registry-a.example.com/myapp:1.4.2 registry-b.example.com/myapp:1.4.2
3. Digest-Pinning: Tags sind veränderlich, Digests nicht
Ein zentrales Problem bei Image Promotion: Tags in Docker-Registries sind per Definition veränderlich. Nichts hindert einen zweiten Build daran, denselben Tag erneut zu pushen und den bisherigen Inhalt zu überschreiben. Wenn eine Deploy-Konfiguration nur auf den Tag verweist, kann sich zwischen Freigabe und tatsächlichem Deploy der Inhalt hinter diesem Tag unbemerkt ändern. Genau dieses Problem löst Digest-Pinning: Jedes Image hat zusätzlich zum Tag einen kryptografischen Digest (sha256:...), der sich aus dem Inhalt ergibt und garantiert unveränderlich ist.
Für sichere Image Promotion sollte die Deploy-Referenz deshalb nicht nur den Tag, sondern den vollständigen Digest enthalten. Ein Deployment, das myapp@sha256:a1b2c3... statt myapp:staging referenziert, kann sich nicht mehr durch nachträgliches Überschreiben des Tags ändern. Viele Registries und Orchestrierungswerkzeuge unterstützen dieses Muster nativ, Kubernetes etwa löst Image-Referenzen intern ohnehin auf Digest-Ebene auf, sobald imagePullPolicy: Always zusammen mit einem Digest verwendet wird.
# Resolve the digest for a given tag before promotion
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' registry.example.com/myapp:1.4.2)
echo "Resolved digest: ${DIGEST}"
# registry.example.com/myapp@sha256:a1b2c3d4e5f6...
# Deploy by digest, not by mutable tag -- guarantees the exact same bytes
kubectl set image deployment/app app="${DIGEST}" -n production
# Verify the digest matches the one validated in staging before promoting
STAGING_DIGEST=$(kubectl get deployment app -n staging \
-o jsonpath='{.spec.template.spec.containers[0].image}')
if [[ "${STAGING_DIGEST}" != "${DIGEST}" ]]; then
echo "[ERROR] Digest mismatch -- refusing to promote" >&2
exit 1
fi
4. Promotion zwischen mehreren Registries
Nicht jedes Setup hat nur eine Registry. Größere Organisationen betreiben oft getrennte Registries pro Umgebung, etwa eine interne Entwicklungsregistry und eine strenger abgesicherte Produktionsregistry mit eingeschränktem Zugriff. Image Promotion zwischen Registries bedeutet dann, das Image explizit aus der Quellregistry zu ziehen und in die Zielregistry zu kopieren, wobei Digest und Inhalt identisch bleiben müssen, nur der Speicherort und eventuell der Repository-Pfad ändern sich.
Bei dieser Art von Image Promotion ist es wichtig, dass der Kopiervorgang selbst durch einen dedizierten CI-Job mit eingeschränkten, auditierbaren Credentials erfolgt, nicht durch einen einzelnen Entwickler mit persönlichem Zugang zur Produktionsregistry. Tools wie crane copy oder regctl image copy übertragen Manifest und Layer direkt zwischen Registries, ohne lokalen Zwischenspeicher, was sowohl schneller ist als auch die Angriffsfläche reduziert.
5. Promotion-Gates: manuelle Freigaben und automatische Checks
Ein Promotion-Gate ist der Kontrollpunkt, an dem Image Promotion entweder automatisch fortfährt oder auf eine explizite Freigabe wartet. In GitLab CI wird das über when: manual in Kombination mit environment-Blöcken abgebildet, in GitHub Actions über Environment Protection Rules mit erforderlichen Reviewern. Beide Mechanismen stellen sicher, dass die Beförderung nach Produktion nicht automatisch bei jedem grünen Pipeline-Lauf passiert, sondern eine bewusste menschliche Entscheidung erfordert, zumindest für die kritischste Umgebung.
Automatisierte Gates ergänzen die manuelle Freigabe bei Image Promotion sinnvoll: ein Sicherheitsscan, der kritische Schwachstellen blockiert, ein Smoke-Test gegen die Staging-Instanz, oder eine Prüfung, ob alle Datenbank-Migrationen bereits angewendet wurden. Erst wenn alle automatisierten Gates grün sind, wird die manuelle Freigabe überhaupt angeboten, statt Personen mit offensichtlich fehlschlagenden Checks zu konfrontieren.
# .gitlab-ci.yml -- promotion gate: automated checks, then manual approval
promote-to-production:
stage: promote
environment:
name: production
url: https://shop.example.com
when: manual
needs:
- job: security-scan
artifacts: false
- job: smoke-test-staging
script:
- echo "Promoting ${CI_COMMIT_SHA} to production"
- crane copy
registry.example.com/myapp:${CI_COMMIT_SHA}
registry.example.com/myapp:production
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
6. Eine vollständige Promotion-Pipeline in GitLab CI
Eine ausgereifte Image Promotion Pipeline besteht aus mehreren aufeinander folgenden Stufen: Build, automatisierte Tests gegen das gebaute Image, Deploy nach Staging, automatisierte und manuelle Freigabe, und schließlich Promotion nach Produktion durch Retagging oder Digest-Referenz. Jede Stufe referenziert dasselbe unveränderliche Artefakt, das im ersten Schritt entstanden ist, und fügt lediglich zusätzliche Nachweise hinzu, dass dieses Artefakt für die nächste Stufe bereit ist.
Bei der Umsetzung sollte die Image Promotion Pipeline immer nachvollziehbar protokollieren, wer wann welche Freigabe erteilt hat. GitLab und GitHub speichern diese Informationen standardmäßig im Deployment-Verlauf, was bei Audits oder Incident-Reviews unverzichtbar ist. Ergänzend kann ein Slack- oder E-Mail-Hook bei jeder Produktions-Promotion eine Benachrichtigung an das gesamte Team senden, damit niemand von einem Produktions-Deploy überrascht wird.
7. Nachvollziehbarkeit: welches Image lief wann wo
Ein oft unterschätzter Nutzen konsequenter Image Promotion ist die Nachvollziehbarkeit im Nachhinein. Wenn jede Beförderung über die Registry-API oder das CI-System protokolliert wird, lässt sich jederzeit rekonstruieren, welcher Commit zu welchem Zeitpunkt in welcher Umgebung lief. Das ist bei Incident-Analysen Gold wert: Statt zu raten, ob ein Bug durch einen kürzlichen Deploy verursacht wurde, zeigt die Promotion-Historie exakt, wann welches Artefakt in Produktion ankam.
Für Image Promotion empfiehlt es sich, Labels im Image selbst zu setzen, etwa org.opencontainers.image.revision mit dem Git-Commit-Hash und org.opencontainers.image.created mit dem Build-Zeitstempel. Diese OCI-Standard-Labels lassen sich mit docker inspect jederzeit aus einem laufenden Container auslesen, unabhängig davon, welches Deployment-Tool die Promotion durchgeführt hat.
8. Typische Fehler bei der Image Promotion
Der häufigste Fehler bei Image Promotion ist, den latest-Tag als Promotion-Ziel zu verwenden. Da latest per Konvention immer wieder überschrieben wird, verliert jede darauf basierende Promotion jede Nachvollziehbarkeit. Ein zweiter häufiger Fehler: Die Staging-Umgebung wird mit einem Tag deployt, aber die Produktions-Promotion referenziert versehentlich einen anderen, ähnlich benannten Tag, weil ein Pipeline-Skript die Variable falsch weiterreicht.
# WRONG: promoting via a mutable, ambiguous tag
docker pull registry.example.com/myapp:latest
docker tag registry.example.com/myapp:latest registry.example.com/myapp:production
# "latest" could be anything by the time this runs
# RIGHT: promote by the exact digest validated in staging
STAGING_DIGEST="sha256:a1b2c3d4e5f6..."
docker pull "registry.example.com/myapp@${STAGING_DIGEST}"
docker tag "registry.example.com/myapp@${STAGING_DIGEST}" registry.example.com/myapp:production
docker push registry.example.com/myapp:production
Ein dritter Fehler ist, Promotion-Gates rein prozessual im Kopf des Teams zu verankern, ohne sie technisch zu erzwingen. Wenn theoretisch jeder Entwickler mit ausreichenden Registry-Rechten manuell einen Tag umschreiben kann, ist das Gate wirkungslos, egal wie gut die Pipeline dokumentiert ist. Zugriffsrechte auf die Produktionsregistry sollten deshalb strikt auf die CI-Service-Accounts beschränkt werden, die die Promotion durchführen.
9. Promotion-Strategien im direkten Vergleich
Die folgende Tabelle vergleicht verbreitete Ansätze für Image Promotion, von der unsicheren manuellen Variante bis zur vollautomatisierten Digest-basierten Pipeline.
| Ansatz | Unsicher | Empfohlene Image Promotion | Vorteil |
|---|---|---|---|
| Referenz beim Deploy | myapp:latest |
myapp@sha256:... |
Unveränderlich, exakt reproduzierbar |
| Übergang Staging zu Prod | Neuer Build für Produktion | Retag / Digest-Copy | Kein Risiko unterschiedlicher Artefakte |
| Freigabe | Manueller SSH-Zugriff | Promotion-Gate in CI | Auditierbar, an Person gebunden |
| Registry-Zugriff | Persönliche Credentials | Dedizierter CI-Service-Account | Eingeschränkte, protokollierte Rechte |
| Nachvollziehbarkeit | Nur informell bekannt | OCI-Labels + Deployment-Log | Jederzeit rekonstruierbar |
Der Aufwand für eine sauber automatisierte Image Promotion Pipeline zahlt sich vor allem bei Incidents aus. Ein Team, das binnen Sekunden sagen kann, welcher Commit gerade in Produktion läuft und wann er dorthin befördert wurde, verkürzt die Mean Time to Resolution spürbar gegenüber einem Team, das erst manuell recherchieren muss.
Mironsoft
Docker-Registries, Promotion-Pipelines und Container-Sicherheit
Vertrauenswürdige Image Promotion aufsetzen?
Wir richten Promotion-Pipelines mit Digest-Pinning, automatisierten Gates und protokollierten Freigaben ein, damit jede Beförderung von Staging nach Produktion nachvollziehbar und sicher bleibt.
Promotion-Pipeline
Retagging, Digest-Copy und Gates in GitLab CI oder GitHub Actions
Registry-Härtung
Zugriffsrechte auf CI-Service-Accounts beschränken, Tags absichern
Audit-Trail
OCI-Labels und Deployment-Logs für vollständige Nachvollziehbarkeit
10. Zusammenfassung
Image Promotion löst ein konkretes Vertrauensproblem in Container-Pipelines: Wie stellt man sicher, dass ein in Staging getestetes Image bit für bit identisch in Produktion landet. Retagging statt Rebuild, Digest-Pinning statt veränderlicher Tags, und Promotion-Gates mit automatisierten Checks sowie protokollierten manuellen Freigaben bilden zusammen einen Prozess, der sowohl sicher als auch nachvollziehbar ist.
Wer Image Promotion konsequent über Digests statt Tags abwickelt und den Zugriff auf Produktionsregistries auf dedizierte CI-Service-Accounts beschränkt, eliminiert eine ganze Klasse von Fehlern, die durch versehentlich überschriebene Tags oder unklare Freigabeprozesse entstehen. Die Investition in eine saubere Promotion-Pipeline zahlt sich besonders bei Incidents aus, wenn schnelle, zweifelsfreie Antworten über den aktuellen Produktionsstand gefragt sind.
Image Promotion — Das Wichtigste auf einen Blick
Retag statt Rebuild
docker tag oder crane copy erzeugen keine neuen Bytes, nur eine zusätzliche Referenz auf dasselbe Image.
Digest-Pinning
Deploy-Referenzen sollten den Digest, nicht nur den veränderlichen Tag enthalten, für garantierte Reproduzierbarkeit.
Promotion-Gates
Automatisierte Checks und manuelle Freigaben in der CI-Pipeline erzwingen, nicht nur dokumentieren.
Nachvollziehbarkeit
OCI-Labels und Deployment-Logs machen jederzeit rekonstruierbar, welches Artefakt wann wo lief.