Minimale Basis-Images richtig auswählen
AI generated
FROM
RUN
Docker · Basis-Images · Alpine · Image Building
Minimale Basis-Images richtig auswählen
Alpine, Debian-Slim, Distroless und Scratch im Entscheidungsrahmen

Die Wahl des minimalen Basis-Images entscheidet über Kompatibilität, Debugging-Fähigkeit und Wartungsaufwand für die gesamte Lebensdauer eines Docker-Images. Alpine mit musl-libc, Debian-Slim mit vollem glibc-Ökosystem, Distroless ohne jede Shell und Scratch als komplett leeres Fundament lösen unterschiedliche Probleme und passen jeweils zu unterschiedlichen Projektanforderungen.

18 Min. Lesezeit Alpine · Debian-Slim · Distroless · Scratch musl vs. glibc · Image Building

1. Warum die Basis-Image-Wahl mehr ist als Image-Größe

Die Wahl eines minimalen Basis-Images wird in vielen Teams allein anhand der Image-Größe getroffen, meist zugunsten von Alpine, weil es in Größenvergleichen fast immer gewinnt. Diese Betrachtung greift zu kurz, weil die C-Standard-Bibliothek, die Paketverfügbarkeit und die Debugging-Möglichkeiten im laufenden Betrieb genauso entscheidend sind wie die reine Anzahl der Megabyte im Layer.

Ein falsch gewähltes minimales Basis-Image führt in der Praxis zu subtilen Bugs, die erst in Produktion auftreten, etwa wenn eine PHP-Extension unter Alpines musl-libc anders reagiert als unter Debians glibc, oder zu unnötigem Betriebsaufwand, wenn ein Distroless-Image ohne vorherige Kubernetes-Ephemeral-Container-Strategie eingeführt wird. Die richtige Entscheidung hängt von mehreren Dimensionen gleichzeitig ab: verfügbare Debugging-Werkzeuge, Kompatibilität mit nativen Erweiterungen, Team-Erfahrung und die tatsächliche CVE-Reduktion, die im konkreten Projekt erreichbar ist.

Dieser Artikel liefert einen strukturierten Entscheidungsrahmen für die Wahl zwischen Alpine, Debian-Slim, Distroless und Scratch als minimale Basis-Images, mit besonderem Fokus auf die musl-vs-glibc-Kompatibilitätsfrage, die in der Praxis die meisten überraschenden Probleme verursacht.

2. Alpine Linux: klein durch musl-libc und BusyBox

Alpine Linux erreicht seine geringe Größe von etwa fünf Megabyte durch zwei fundamentale Entscheidungen: musl als schlanke Alternative zur glibc-Standardbibliothek und BusyBox als kompakte Sammlung von Unix-Kommandozeilenwerkzeugen in einer einzigen Binary. Diese Kombination macht Alpine zum beliebtesten minimalen Basis-Image für einfache Anwendungen ohne komplexe native Abhängigkeiten.

Für PHP-Container bringt der Umstieg auf Alpine jedoch Kompilierungsaufwand mit sich, weil offizielle PHP-Alpine-Images alle Extensions selbst aus dem Quellcode gegen musl kompilieren müssen, statt vorkompilierte glibc-Pakete aus Debian-Repositories zu nutzen. Das apk-Paketformat von Alpine ist zudem kleiner sortiert als Debians apt-Ökosystem, sodass manche spezialisierten Bibliotheken für bestimmte PHP-Extensions unter Alpine schlicht fehlen oder manuell nachgebaut werden müssen.


FROM php:8.4-fpm-alpine AS base

# Alpine uses apk instead of apt, and package names often differ
RUN apk add --no-cache \
    libzip-dev \
    icu-dev \
    libpng-dev \
    && docker-php-ext-install -j$(nproc) \
       zip intl gd pdo_mysql

# musl-based Alpine images compile extensions from source,
# which increases build time compared to glibc-based Debian images

3. musl vs. glibc: die unterschätzte Kompatibilitätsfalle

Der wichtigste technische Unterschied zwischen Alpine und den meisten anderen minimalen Basis-Images ist die C-Standard-Bibliothek. musl implementiert dieselbe POSIX-Schnittstelle wie glibc, weicht aber in Detailverhalten ab, etwa bei der DNS-Auflösung, bei Locale-Handling und bei bestimmten mathematischen Funktionen mit Randfällen. Diese Unterschiede sind in den meisten PHP-Anwendungen unsichtbar, treten aber bei bestimmten Extensions wie intl mit komplexer Unicode-Verarbeitung oder bei Anwendungen mit eigenem C-Code gelegentlich als schwer reproduzierbare Bugs zu Tage.

Ein bekanntes Beispiel: musl reserviert standardmäßig einen deutlich kleineren Thread-Stack als glibc, was bei rekursiven PHP-Funktionen mit tiefer Verschachtelung zu Stack-Overflow-Fehlern führen kann, die unter Debian-basierten Images nicht auftreten. Wer ein minimales Basis-Image mit musl wählt, sollte diese Fehlerklasse kennen und im Zweifel mit erhöhtem Stack-Limit testen, statt stundenlang ein vermeintliches Anwendungsproblem zu debuggen.


# Detect the C library used inside a running container
docker exec my-container ldd --version
# musl: shows "musl libc" and a much shorter usage text
# glibc: shows "GNU C Library" with version and copyright block

# Increase the default thread stack size under musl if deep recursion
# in PHP or a native extension triggers stack overflow errors
docker run --ulimit stack=8388608:8388608 my-alpine-image

4. Debian-Slim: der pragmatische Mittelweg

Debian-Slim-Images, etwa php:8.4-fpm ohne den -alpine-Suffix, behalten das vollständige glibc-Ökosystem bei, entfernen aber Dokumentation, Man-Pages und selten benötigte Pakete gegenüber dem Standard-Debian-Image. Für PHP-Anwendungen ist das oft die reibungsloseste Wahl unter den minimalen Basis-Images, weil praktisch jede PHP-Extension und jedes Composer-Paket mit nativem Code gegen glibc getestet und dokumentiert ist.

Der Kompromiss liegt in der Image-Größe: Ein Debian-Slim-basiertes PHP-Image liegt typischerweise bei 150 bis 250 Megabyte, während ein vergleichbares Alpine-Image oft nur 60 bis 100 Megabyte erreicht. Für Teams, die primär auf Kompatibilität und geringes Debugging-Risiko Wert legen und für die Image-Größe eine untergeordnete Rolle spielt, ist Debian-Slim häufig die richtige Wahl unter den minimalen Basis-Images.

5. Distroless und Scratch: minimal ohne Betriebssystem

Distroless-Images gehen einen Schritt weiter als Alpine oder Debian-Slim, indem sie Shell und Paketmanager komplett weglassen und nur die Anwendung selbst mit direkten Laufzeitabhängigkeiten enthalten. Scratch ist das theoretische Minimum: ein komplett leeres Basis-Image ohne jede Datei, das nur für vollständig statisch gelinkte Binaries wie Go-Programme oder statisch kompiliertes PHP funktioniert.

Für PHP-Anwendungen ist Scratch als minimales Basis-Image nur mit vollständig statischer PHP-Kompilierung über static-php-cli praktikabel, weil selbst die grundlegendsten Laufzeitbibliotheken sonst fehlen würden. Distroless-Varianten mit glibc-Unterstützung, etwa gcr.io/distroless/base, bieten einen Mittelweg, der etwas mehr Bibliotheksunterstützung bereitstellt, ohne auf Shell oder Paketmanager zurückzugreifen.

6. Ein Entscheidungsrahmen für die Basis-Image-Wahl

Die Auswahl eines minimalen Basis-Images lässt sich anhand von vier Leitfragen strukturieren: Erstens, wie kritisch ist Debugging-Fähigkeit direkt im laufenden Container. Zweitens, wie viele native Extensions oder Compiler-Abhängigkeiten hat die Anwendung. Drittens, wie stark wiegt die CVE-Reduktion als Sicherheitsargument gegenüber operativem Mehraufwand. Viertens, wie viel Erfahrung hat das Team mit Ephemeral-Debug-Containern und Kubernetes-Tooling.

Teams mit hohem Debugging-Bedarf und wenig Kubernetes-Erfahrung fahren mit Debian-Slim am sichersten. Teams mit einfachen Anwendungen ohne komplexe native Abhängigkeiten und Fokus auf Image-Größe profitieren von Alpine. Teams mit strengen Sicherheitsanforderungen und etablierter Kubernetes-Debugging-Praxis sollten Distroless in Betracht ziehen. Scratch bleibt Nischenfällen mit vollständig statischen Binaries vorbehalten.

In der Praxis empfiehlt sich, die Entscheidung nicht einmalig und endgültig zu treffen, sondern als iterativen Prozess zu behandeln. Ein pragmatischer Startpunkt ist häufig Debian-Slim, verbunden mit einer klaren Messung der tatsächlichen Image-Größe und der gemeldeten CVE-Anzahl in der eigenen CI-Pipeline. Erst wenn diese Zahlen tatsächlich zum Problem werden, etwa weil ein Sicherheitsaudit eine harte CVE-Obergrenze fordert, lohnt sich der Mehraufwand eines Wechsels zu Alpine oder Distroless als minimales Basis-Image. Diese datenbasierte Herangehensweise verhindert vorschnelle Migrationen, die mehr Betriebsrisiko erzeugen, als sie an Sicherheitsgewinn einbringen.

7. PHP-Extensions und Basis-Image-Kompatibilität in der Praxis

Für Magento- oder Symfony-typische Extensions wie gd, intl, bcmath, soap und pdo_mysql bestehen zwischen den minimalen Basis-Images deutliche Unterschiede in Build-Aufwand und Laufzeit-Robustheit. Debian-Slim benötigt für diese Extensions in der Regel nur apt-get install von Entwicklungspaketen, gefolgt von docker-php-ext-install, ohne exotische Fehlerbilder.

Unter Alpine treten gelegentlich Locale-bezogene Probleme mit intl auf, weil musl standardmäßig keine vollständige ICU-Locale-Datenbank mitbringt und diese explizit über musl-locales nachinstalliert werden muss. Für imagick, das gegen ImageMagick linkt, ist die Paketverfügbarkeit unter Alpine historisch schwächer als unter Debian, was regelmäßig zu manuellen Kompilierungsschritten führt, die bei Debian-Slim entfallen.


# Alpine: intl often needs an explicit locale data package
FROM php:8.4-fpm-alpine
RUN apk add --no-cache icu-dev icu-data-full \
    && docker-php-ext-install intl

# Debian-Slim: intl works with the standard development package,
# no extra locale data package needed in most cases
FROM php:8.4-fpm
RUN apt-get update && apt-get install -y libicu-dev \
    && docker-php-ext-install intl

8. Wartungsaufwand über die Lebensdauer eines Images

Die anfängliche Entscheidung für ein minimales Basis-Image bindet ein Team über die gesamte Lebensdauer des Projekts, weil ein späterer Wechsel oft eine Neukompilierung aller nativen Extensions und ausführliche Regressionstests erfordert. Alpine-basierte Images benötigen tendenziell häufigere kleine Anpassungen, wenn neue musl-Versionen subtile Verhaltensänderungen mitbringen, während Debian-Slim von der breiteren Testbasis der glibc-Welt profitiert.

Sicherheitsupdates unterscheiden sich ebenfalls im Rhythmus: Alpine veröffentlicht sicherheitsrelevante Paket-Updates oft schneller als Debian-Stable, was für Teams mit hoher Update-Frequenz ein Vorteil ist, für Teams mit seltenen Wartungsfenstern aber häufigere ungeplante Rebuild-Zyklen bedeutet. Diese betrieblichen Aspekte sollten in die Wahl des minimalen Basis-Images genauso einfließen wie die reine technische Kompatibilität.


# Quick way to compare reported CVEs across candidate base images
# before committing to a migration
trivy image --severity CRITICAL,HIGH php:8.4-fpm
trivy image --severity CRITICAL,HIGH php:8.4-fpm-alpine
trivy image --severity CRITICAL,HIGH gcr.io/distroless/base-debian12

# Compare resulting image sizes side by side
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" \
  | grep -E "php|distroless"

Diese einfache Vergleichsmessung liefert innerhalb weniger Minuten belastbare Zahlen für die eigene Entscheidung, statt sich auf pauschale Aussagen aus Blogartikeln zu verlassen. Für Magento- und Symfony-Projekte mit mehreren Basis-Image-Kandidaten lohnt es sich, diesen Vergleich als festen Schritt vor jeder größeren Docker-Migration zu wiederholen, weil sich die CVE-Lage einzelner Basis-Images über Monate deutlich verschieben kann.

9. Alle Basis-Image-Typen im direkten Vergleich

Die folgende Tabelle fasst die wichtigsten Entscheidungskriterien für die vier gängigsten Kategorien minimaler Basis-Images zusammen. Sie dient als Ausgangspunkt für die eigene Bewertung, ersetzt aber keinen projektspezifischen Test mit den tatsächlich genutzten Extensions und Composer-Paketen.

Bei der Interpretation der Tabelle lohnt sich ein Blick auf die eigene Betriebsrealität: Ein Team, das bereits heute Kubernetes mit Ephemeral-Debug-Containern produktiv einsetzt, bewertet die fehlende direkte Shell in Distroless-Images deutlich milder als ein Team, das ausschließlich mit klassischem docker exec arbeitet. Ebenso wiegt die musl-Kompatibilitätsfrage bei Alpine für ein reines Symfony-API-Projekt ohne exotische Extensions weniger schwer als für einen komplexen Magento-Shop mit Bildverarbeitung, Volltextsuche und mehreren nativen Bibliotheken gleichzeitig.

Kriterium Alpine Debian-Slim Distroless Scratch
Typische Größe 60 bis 100 MB 150 bis 250 MB 40 bis 80 MB Nur App-Größe
C-Bibliothek musl glibc glibc oder keine Keine
Debugging direkt im Container Ja, ash Ja, bash Nein Nein
PHP-Extension-Kompatibilität Gut, gelegentliche Ausnahmen Sehr gut Nur mit Static-PHP Nur mit Static-PHP
Empfohlen für Einfache Anwendungen, Größe wichtig Komplexe Extensions, Kompatibilität wichtig Hohe Sicherheitsanforderungen Statische Binaries

Kein einzelnes minimales Basis-Image ist für alle Projekte die beste Wahl. Die Tabelle macht sichtbar, dass die Entscheidung immer eine Abwägung zwischen Größe, Kompatibilität und operativer Reife des Teams ist, nicht eine reine Optimierungsaufgabe nach Megabyte.

Mironsoft

Docker-Basis-Image-Auswahl und Migrationsberatung für PHP-Projekte

Das richtige Basis-Image für euer Projekt finden?

Wir analysieren eure PHP-Extensions und nativen Abhängigkeiten, bewerten musl- und glibc-Kompatibilität und begleiten die Migration zwischen Alpine, Debian-Slim und Distroless ohne überraschende Laufzeitfehler.

Kompatibilitäts-Check

Extensions und Composer-Pakete auf musl-vs-glibc-Risiken prüfen

Basis-Image-Migration

Umstieg zwischen Alpine, Debian-Slim und Distroless sauber begleiten

Regressionstests

Automatisierte Tests gegen das neue Basis-Image vor dem Produktivumstieg

10. Zusammenfassung

Minimale Basis-Images richtig auswählen bedeutet, über die reine Image-Größe hinauszudenken und Kompatibilität, Debugging-Fähigkeit und Wartungsaufwand gleichwertig zu berücksichtigen. Alpine überzeugt durch geringe Größe, bringt aber mit musl-libc eine eigene Kompatibilitätsklasse an Fehlern mit sich, die unter glibc-basierten Systemen nicht existiert. Debian-Slim bleibt für PHP-Anwendungen mit vielen nativen Extensions oft die robusteste Wahl.

Distroless und Scratch als radikalste Formen minimaler Basis-Images liefern die größte Sicherheitsreduktion, verlangen aber etablierte Ephemeral-Debug-Praktiken, bevor sie produktiv sinnvoll einsetzbar sind. Die richtige Entscheidung ergibt sich immer aus dem Zusammenspiel von Anwendungsanforderungen, Team-Erfahrung und den tatsächlichen Sicherheitszielen des Projekts, nicht aus einer pauschalen Empfehlung.

Minimale Basis-Images richtig auswählen — Das Wichtigste auf einen Blick

musl vs. glibc

Alpines musl-libc weicht in Detailverhalten von glibc ab, etwa bei DNS-Auflösung und Thread-Stack-Größe.

Debian-Slim

Bester Kompromiss für PHP-Anwendungen mit vielen nativen Extensions und geringem Debugging-Risiko.

Distroless

Maximale Sicherheitsreduktion, aber nur mit etablierten Ephemeral-Debug-Praktiken praxistauglich.

Entscheidungsrahmen

Debugging-Bedarf, native Abhängigkeiten, Team-Erfahrung und Sicherheitsziele gemeinsam bewerten.

11. FAQ: Minimale Basis-Images richtig auswählen

1Alpine vs. Debian-Slim, was ist der Unterschied?
Alpine nutzt musl-libc und BusyBox für minimale Größe, Debian-Slim behält volle glibc-Kompatibilität.
2Warum ist musl vs. glibc wichtig?
musl weicht bei DNS, Locale und Thread-Stack von glibc ab, was zu schwer reproduzierbaren Bugs führen kann.
3Wann Alpine wählen?
Für einfache Anwendungen ohne komplexe native Abhängigkeiten, wenn Größe wichtig ist.
4Wann Debian-Slim besser?
Bei vielen nativen Extensions wie imagick, wo Kompatibilität wichtiger ist als Größe.
5Was ist ein Scratch-Image?
Ein komplett leeres Basis-Image, nur für vollständig statisch gelinkte Binaries geeignet.
6Ist Distroless dasselbe wie Scratch?
Nein, Distroless enthält grundlegende Laufzeitbibliotheken, Scratch ist vollständig leer.
7Warum intl-Probleme unter Alpine?
musl bringt keine vollständige ICU-Locale-Datenbank mit, muss separat über icu-data-full installiert werden.
8Wie prüfe ich die C-Bibliothek?
Mit docker exec container ldd --version, musl zeigt eine kurze Ausgabe, glibc einen längeren Copyright-Block.
9Wie viel kleiner ist Alpine?
Typisch 60 bis 100 MB gegenüber 150 bis 250 MB bei einem vergleichbaren Debian-Slim-Image.
10Kann ich später wechseln?
Nicht ohne Aufwand, ein Wechsel erfordert meist Neukompilierung und ausführliche Regressionstests.