Image Promotion: Docker Images sicher zwischen Registries und Umgebungen bewegen
AI generated
FROM
RUN
Docker · Registry · CI/CD
Image Promotion
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.

17 Min. Lesezeit Retagging · Digest-Pinning · Promotion-Gates GitLab CI · GitHub Actions · Registries

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.

11. FAQ: Image Promotion mit Docker

1Was bedeutet Image Promotion konkret?
Ein getestetes Image wird kontrolliert in die nächste Umgebung befördert, ohne neu gebaut zu werden.
2Warum reicht einfaches Retagging nicht immer?
Tags sind veränderlich. Ohne Digest-Pinning kann sich der Inhalt unbemerkt ändern.
3Unterschied Tag und Digest?
Tag ist veränderlich und lesbar, Digest ist ein unveränderlicher Hash des Inhalts.
4Wie funktioniert ein Promotion-Gate in GitLab CI?
Über when: manual in einem environment-Block, kombiniert mit automatisierten Checks als Vorbedingung.
5Tag oder Digest in Deploy-Konfigurationen?
Für Produktion den Digest, garantiert unveränderlich, der Tag dient nur als lesbare Zusatzinfo.
6Wie kopiert man Images zwischen Registries?
Mit crane copy oder regctl image copy, direkt ohne lokalen Docker-Daemon.
7Wer sollte Registry-Zugriff haben?
Nur dedizierte CI-Service-Accounts mit eingeschränkten, protokollierten Rechten.
8Welche Labels helfen bei Nachvollziehbarkeit?
OCI-Labels wie image.revision und image.created, auslesbar mit docker inspect.
9Häufigster Fehler bei Image Promotion?
Der latest-Tag als Promotion-Ziel, dadurch geht jede Nachvollziehbarkeit verloren.
10Braucht jede Umgebung eine eigene Registry?
Nein, oft genügt eine Registry mit unterschiedlichen Tags oder Namespaces pro Umgebung.