Pinned Versions vs latest - wie man den richtigen Mittelweg findet
Pinned Versions vs latest - wie man den richtigen Mittelweg findet
latest ist unvorhersehbar, zu stark gepinnte Versionen verpassen Sicherheitsupdates – der richtige Mittelweg ist eine Frage der Strategie.
Das Problem mit latest
# Gefährlich in Produktion
image: nginx:latest
latest zeigt auf den neuesten Build zum Zeitpunkt des Pulls. Ein docker compose pull nächste Woche kann einen Breaking Change mitbringen. Auf verschiedenen Servern kann dieselbe Compose-Datei unterschiedliche Versionen ausführen.
Das Problem mit zu stark gepinnten Versionen
# Zu restriktiv
image: nginx:1.25.3
Sicherheitslücken in nginx 1.25.3 werden nicht automatisch behoben. Man muss jede Patch-Version manuell aktualisieren und weiss oft nicht wann eine neue rauskommt.
Der Mittelweg: Minor-Version pinnen
# Gut: bekommt Patch-Updates, keine Breaking Changes
image: nginx:1.25
image: postgres:16
image: node:20-alpine
- Die meisten Projekte folgen Semantic Versioning: Major.Minor.Patch.
- Patch-Updates (1.25.3 → 1.25.4): Nur Bug-Fixes, sichere automatische Updates
- Minor-Updates (1.25 → 1.26): Neue Features, abwärtskompatibel
- Major-Updates (1.x → 2.x): Breaking Changes möglich
Durch Pinnen auf die Minor-Version (nginx:1.25) erhält man Patch-Updates automatisch ohne Breaking Changes zu riskieren.
Digest-Pinning: Maximale Reproduzierbarkeit
# Byte-für-Byte identisch, immer
image: nginx@sha256:a480a496da64e3f8b8e5c89fa87958b7f37cfbd87cb64d41b90a30bb65a5ae0c
Der Digest ist der Hash des Image-Inhalts. Er ändert sich nie. Damit ist jeder Build identisch – ideal für kritische Produktivumgebungen.
# Digest eines Images ermitteln
docker inspect nginx:1.25 --format '{{index .RepoDigests 0}}'
# nginx@sha256:a480a496...
Nachteil: Sicherheitsupdates bekommt man nie automatisch. Man muss den Digest manuell aktualisieren.
Tagging-Strategie verschiedener Projekte
Nicht alle Images folgen Semantic Versioning – das muss man pro Image prüfen:
# Docker Hub: Tags eines Images anzeigen
curl -s https://hub.docker.com/v2/repositories/library/nginx/tags/ | python3 -m json.tool | grep name
linuxserver.io Images: Nutzen oft Datumsbasierte Tags (latest, nightly) – hier ist latest relativ sicher da sie Changelogs pflegen.
Bitnami: Nutzen vollständige Versionsnummern, sehr empfehlenswert zum pinnen.
Offiziell Postgres: postgres:16 = aktuellste Postgres 16.x, sicheres pinnen.
Empfehlung nach Umgebung
| Umgebung | Empfehlung | Beispiel |
|---|---|---|
| Produktion | Minor-Version + Renovate für PRs | nginx:1.25 |
| Staging | Minor-Version | nginx:1.25 |
| Development | Minor oder latest | nginx:latest |
| CI/CD Reproduzierbarkeit | Digest | nginx@sha256:... |
Mit Renovate automatisch PRs öffnen
// renovate.json
{
"packageRules": [
{
"matchDatasources": ["docker"],
"matchUpdateTypes": ["minor", "patch"],
"automerge": false
}
]
}
Renovate erkennt neue Minor/Patch-Releases und öffnet PRs – man reviewed den Changelog, merged, und docker compose pull erledigt den Rest.