Bir junior geliştirici, bir Python Docker imajını 1,2 GB'tan 85 MB'a düşürerek CI hattını 11 dakikadan 90 saniyeye indirdi. Daha küçük imajlar daha hızlı indirilir, depolanması daha az maliyetlidir ve daha az güvenlik açığına maruz kalır.

İmaj boyutu neden önemlidir

Bir konteyner her çekildiğinde (pull), registry tüm imajı akış olarak gönderir. 85 MB'lık bir katman saniyeler içinde iner; 1,2 GB'lık bir katman mütevazı bir ağda dakikalar alabilir. Build ajanlarının ayrıca tam imajı yüklemesi ve önbelleğe alması gerekir, bu da CI süresini ve bulut depolama faturalarını artırır. Her ekstra paket potansiyel bir güvenlik açığıdır, bu nedenle tabanı budamak saldırı yüzeyini küçültür.

Şişkinlik nereden kaynaklanır

  • Uygulamanın çalıştığı aynı aşamada (stage) yüklendikleri takdirde, gcc gibi derleme araçları nihai imajda kalır.
  • Paket yöneticisi önbellekleri (örneğin, apt veya pip önbellekleri) diskte yer kaplar ve varsayılan olarak asla temizlenmez.
  • Her RUN talimatı yeni bir salt okunur katman oluşturur; katmanlar arasındaki yinelenen dosyalar birikir.
  • ubuntu:latest gibi büyük taban imajları, minimal bir Python çalışma zamanının (runtime) ihtiyaç duyduğundan çok daha fazlasını içeren tam bir işletim sistemiyle birlikte gelir.

Üç adımlı küçültme

Adım Taban imajı Derleme yaklaşımı Sonuç boyutu
1 Standart Python (tam) Tek aşamalı, tüm araçlar mevcut 1,18 GB
2 python:slim Çok aşamalı: gcc içeren builder, nihai aşama yalnızca derlenmiş paketleri kopyalar 210 MB
3 python:alpine Kendisi de çok küçük olan Alpine Linux üzerinde çok aşamalı 85 MB

Adım 1 – temel çizgi

Varsayılan Python imajıyla başlayarak, geliştirici 1,18 GB'lık bir artifact gördü. İmaj; tam Debian yığını, geliştirme başlıkları (headers) ve pip önbelleğini içeriyordu.

Adım 2 – builder ile slim

python:slim imajına geçmek işletim sistemi ayak izini azalttı ancak derleme araçları kalmaya devam etti. Bir builder aşaması eklemek; gcc, make ve diğer derleme zamanı bağımlılıklarının yüklenmesini, derlenmesini ve ardından ortadan kalkmasını sağladı. Nihai aşama, yalnızca derlenmiş wheel dosyalarını ve çalışma zamanı dosyalarını çekmek için COPY --from=builder komutunu kullanarak boyutu 210 MB'a düşürdü.

Adım 3 – Alpine kazanıyor

Alpine Linux, musl libc ve busybox üzerine inşa edilmiştir. Alpine üzerinde çok aşamalı deseni tekrarlamak, orijinalinden %93 oranında bir azalmayla 85 MB'lık bir imaj sağladı. Geliştirici, Kubernetes'in imajı saniyeler içinde çektiğini ve CI işinin 90 saniyede tamamlandığını belirtti.

Gerçek dünya etkisi

  • Düşük depolama maliyetleri – Registry depolama alanı küçülür.
  • Gelişmiş güvenlik – Daha az paket, takip edilecek daha az CVE anlamına gelir. Alpine imajı yalnızca Python çalışma zamanını ve uygulama kodunu içerir.
  • Daha hızlı CI – Pipeline çalışma süresi 11 dakikadan 90 saniyeye düştü.

Dockerfile dosyanızı budamak için pratik ipuçları

  • :latest etiketlerinden kaçının; ihtiyaçlarınıza uygun :slim veya :alpine varyantlarını seçin.
  • Çok aşamalı (multi-stage) derlemeler kullanın: derleme için özel bir builder aşaması, yalnızca gerçekten ihtiyacınız olan çıktıları alan bir runtime aşaması.
  • COPY --from=builder /path/to/installed /path/in/final ile seçici olarak kopyalayın.
  • Komutları, bağımlılık kurulumu kaynak kod kopyalanmadan önce çalışacak şekilde sıralayın; bu, katman önbelleğe almayı (layer caching) maksimize eder.
  • Önbellekleri açıkça temizleyin, örneğin: rm -rf /var/lib/apt/lists/* ~/.cache/pip.

Alpine kullanmaya karar verirseniz, uygulamanız DNS çözümleme sorunları yaşadığında nss paketini ekleyin. pip ile yükleme yaparken, yerel olarak yüklenen betiklerin çalışma zamanında bulunabilmesi için /root/.local/bin dizinini PATH değişkeninin başına ekleyin.

Uyarılar

Alpine'in musl libc'si, glibc için derlenmiş binary wheel dosyalarıyla çakışarak çalışma zamanı hatalarına neden olabilir. Bu durumlarda wheel dosyalarını Alpine builder içinde yeniden derleyin veya slim tabanına geri dönün. Ek nss paketi, DNS güvenilirliği için küçük bir bedeldir.

Bundan sonra neye dikkat edilmeli?

  • Mevcut imajlarınızı, çok aşamalı bir yeniden yazım için aday olabilecek büyük katmanlar açısından tarayın.
  • İmaj şişkinliğini tespit etmek için yükleme ve indirme süreleri için CI günlüklerini (logs) izleyin.
  • Seçtiğiniz taban dağıtım için güvenlik açığı raporlarını takip edin.

Ders açık: Disiplinli bir Dockerfile, hafif bir taban ve bir builder aşaması, bir Python imajını bir büyüklük mertebesinden daha fazla küçültebilir; işlevsellikten ödün vermeden somut hız ve maliyet avantajları sağlar.