Distroless Images – minimalne obrazy kontenerów dla bezpiecznych aplikacji produkcyjnych
W świecie kontenerów istnieje prosta zasada:
Im mniej elementów znajduje się w obrazie, tym mniejsza jest potencjalna powierzchnia ataku.
Tradycyjny obraz Docker często zawiera kompletny system operacyjny:
id="distr1"
Ubuntu
├── Shell (bash)
├── Package manager (apt)
├── Utilities
├── Libraries
├── Debug tools
└── Application
Problem?
Aplikacja zazwyczaj potrzebuje tylko:
id="distr2"
Runtime
+
Biblioteki
+
Aplikacja
Nie potrzebuje:
- powłoki bash,
- kompilatora,
- narzędzi sieciowych,
- menedżera pakietów,
- edytorów tekstu.
Tutaj pojawia się koncepcja Distroless Images.
Czym są Distroless Images?
Distroless Images to minimalne obrazy kontenerów zawierające wyłącznie elementy wymagane do uruchomienia aplikacji.
Nazwa pochodzi od:
„distribution-less”
czyli:
bez klasycznej dystrybucji Linux.
Nie oznacza to jednak, że obraz nie posiada systemu plików.
Zawiera:
- niezbędne biblioteki,
- runtime,
- certyfikaty CA,
- aplikację.
Nie zawiera:
- shell,
- package manager,
- narzędzi administracyjnych.
Klasyczny obraz vs Distroless
Standardowy kontener
id="distr3"
Container
├── Debian
│
├── bash
├── curl
├── wget
├── apt
├── python tools
│
└── Application
Distroless
id="distr4"
Container
├── Runtime
│
├── Libraries
│
└── Application
Dlaczego Distroless zwiększa bezpieczeństwo?
Załóżmy scenariusz:
Atakujący wykorzystuje podatność w aplikacji.
Przejmuje proces:
id="distr5"
Application vulnerability
↓
Remote Code Execution
↓
Container access
W klasycznym obrazie:
id="distr6"
bash
curl
wget
python
apt
Atakujący ma narzędzia do dalszej eksploracji.
W Distroless:
id="distr7"
/
├── app
├── libraries
└── certs
Próba:
bash
kończy się:
bash: not found
Distroless nie jest „magicznym zabezpieczeniem”
Ważne:
Distroless nie chroni przed podatnością aplikacji.
Jeżeli aplikacja posiada:
- SQL Injection,
- błędną autoryzację,
- podatną bibliotekę,
problem nadal istnieje.
Distroless ogranicza:
co może zrobić atakujący po przejęciu procesu.

Kto stworzył Distroless?
Koncepcję oraz popularne obrazy rozwija:
Projekt jest dostępny jako:
GoogleContainerTools distroless images
Obrazy są szeroko wykorzystywane w środowiskach:
- Kubernetes,
- Google Cloud,
- DevSecOps,
- środowiskach produkcyjnych.
Przykładowy Distroless Image
Zwykły Dockerfile:
FROM python:3.12
COPY app.py /
CMD ["python","/app.py"]
Problem:
Obraz posiada:
- pip,
- shell,
- narzędzia developerskie.
Podejście Distroless:
FROM python:3.12 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install \
--target=/install \
-r requirements.txt
FROM gcr.io/distroless/python3
COPY --from=builder /install /app
COPY app.py /app/
WORKDIR /app
CMD ["app.py"]
Multi-stage build + Distroless
Najczęściej Distroless stosuje się razem z:
Multi-stage builds
Schemat:
id="distr8"
Builder Image
├── Compiler
├── Dependencies
├── Source Code
↓
Build
↓
Distroless Image
├── Runtime
└── Application
Przykład Go:
FROM golang:1.23 AS builder
WORKDIR /src
COPY .
RUN CGO_ENABLED=0 \
go build -o app
FROM gcr.io/distroless/static
COPY --from=builder /src/app /
ENTRYPOINT ["/app"]
Finalny obraz:
Nie zawiera:
❌ Go
❌ gcc
❌ bash
❌ git
Zawiera:
✅ aplikację
Distroless i brak Shell
To największa różnica podczas administracji.
Normalnie:
docker exec -it container bash
Distroless:
exec failed:
bash not found
Czy to wada?
W produkcji często jest to zaleta.
Zmniejsza ryzyko:
- reverse shell,
- pobierania narzędzi przez atakującego,
- lateral movement.
Jak debugować Distroless?
Ponieważ nie ma narzędzi diagnostycznych, stosuje się inne metody.
1. Debug image
Przykład:
Production:
distroless
Debug:
alpine + tools
2. Ephemeral containers
W Kubernetes:
Running Pod
+
Temporary Debug Container
3. Monitoring zewnętrzny
Zamiast:
wejdź do kontenera
stosuje się:
- logi,
- metryki,
- tracing.
Distroless Images a Kubernetes
W Kubernetes jest to bardzo popularne podejście:
id="distr9"
Pod
├── Application Container
│
│ Distroless Image
│
└── Monitoring Agent
Przykład bezpieczeństwa:
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
Połączenie:
Distroless
+
Non-root
+
Read-only FS
+
Seccomp
daje bardzo mocny poziom zabezpieczeń.
Distroless vs Alpine
Częste pytanie:
Czy Alpine jest tym samym?
Nie.
Alpine
Posiada:
id="distr10"
Alpine
├── BusyBox
├── Shell
├── apk
└── Libraries
Distroless
id="distr11"
Application
+
Required runtime
Porównanie:
| Cecha | Alpine | Distroless |
|---|---|---|
| Shell | Tak | Nie |
| Package manager | apk | Nie |
| Rozmiar | Mały | Bardzo mały |
| Debugowanie | Łatwe | Trudniejsze |
| Bezpieczeństwo | Dobre | Bardzo dobre |
Kiedy stosować Distroless?
Dobry wybór dla:
✅ API REST
✅ mikroserwisów
✅ aplikacji Go
✅ aplikacji Java
✅ aplikacji Node.js
✅ usług Kubernetes
✅ systemów produkcyjnych
Kiedy nie stosować?
Może być problematyczny dla:
- aplikacji wymagających narzędzi systemowych,
- intensywnego debugowania,
- środowisk developerskich.
Przykład:
Development:
Alpine/Debian
Production:
Distroless
To często najlepszy kompromis.
Image Hardening z Distroless
Profesjonalny pipeline:
id="distr12"
Developer
↓
Git
↓
BuildKit
↓
Multi-stage Build
↓
Distroless Image
↓
Trivy Scan
↓
SBOM
↓
Image Signing
↓
Production
Bezpieczeństwo Supply Chain
Distroless pomaga ograniczyć ryzyko:
Mniejszy obraz
↓
mniej komponentów
↓
mniej CVE
↓
łatwiejszy audyt
↓
mniejsze ryzyko
Praktyczna checklista Distroless
✅ aplikacja nie działa jako root
✅ obraz nie posiada shell
✅ brak package managera
✅ używany multi-stage build
✅ wersje zależności kontrolowane
✅ obraz skanowany CVE
✅ SBOM generowany
✅ podpis obrazu stosowany
Podsumowanie
Distroless Images to kolejny etap ewolucji kontenerów.
Klasyczne podejście:
Mam system Linux i uruchamiam aplikację
Nowoczesne podejście:
Mam aplikację i dostarczam tylko to,
czego potrzebuje do działania
W połączeniu z:
- Multi-stage Builds
- Image Hardening
- Rootless Docker
- Seccomp
- AppArmor/SELinux
- Docker Secrets
- SBOM
- Image Signing
Distroless staje się jednym z fundamentów bezpiecznych wdrożeń DevSecOps oraz środowisk produkcyjnych opartych o kontenery.






