İçeriğe geç
Muhammet Şafak
en
Soran: Korhan Cevaplandı:

Docker imaj boyutunu multi-stage build ve distroless ile nasıl küçültürüm?


Soru

Üretime gönderdiğimiz Go veya PHP Docker imajları 1.2 GB'ı buluyor. Bu hem CI/CD'yi yavaşlatıyor (upload/download) hem de imajda gereksiz derleyici, bash gibi kütüphaneler olduğu için saldırı yüzeyi yaratıyor. Multi-stage build ile derleme araçlarını ilk aşamada bırakıp üretime sadece distroless veya alpine tabanlı minimal (mesela 50 MB) bir imaj çıkarmayı nasıl sağlarım?

Cevap

Kısa cevap: 1.2 GB imaj, tüm build toolchain’ini üretime taşıyor — hem yavaş hem de geniş bir saldırı yüzeyi. Multi-stage build ikisini birden çözer; final aşamaya sadece artefaktı ve runtime’ı koyarsın.

Kısa cevap

Problemin kaynağı tek: imajda olmaması gereken şeyler (derleyici, paket yöneticisi, shell) üretime sızıyor. Katmanların nasıl oluştuğunu ve .dockerignore mantığını Docker yazısında temelden anlatmıştım; buradaki optimizasyon o zeminin üstüne oturuyor.

Neden

  1. Bedel iki katlı: hız ve saldırı yüzeyi. 1.2 GB’lık bir imaj her build’de upload/download süresini şişirir; taşıdığı derleyici, bash ve paket yöneticisi de üretimde hiç ihtiyaç duyulmayacak bir saldırı yüzeyi bırakır.

  2. Multi-stage’in mantığı: builder aşaması üretir, final aşaması sadece kopyalar. İlk aşamaya derleyiciyi ve bağımlılıkları koy, artefaktı üret. Final aşamaya yalnızca binary/uygulama + çalışması için gereken runtime’ı COPY --from=builder ile al. Build araçları imaja hiç girmez.

  3. Go ile PHP’nin tabanı aynı yere inmez. Go binary’si kendi kendine yeter (statik linklenir), yani birkaç MB’lık bir imaj çıkar. PHP’de ise derlenmiş binary yok; PHP runtime + extension’lara ihtiyacın var, dolayısıyla hedef boyut da farklı olmak zorunda.

Ne yapmalı

  1. Go için final aşamayı scratch veya distroless/static yap. Distroless shell ve paket yöneticisi içermez — saldırı yüzeyi küçülür; debug gerekince :debug varyantını kullan.

  2. PHP’de hedefin php:8.x-fpm-alpine olsun. Build aşamasında composer install --no-dev çalıştır, final aşamaya yalnızca vendor/ + uygulamayı kopyala. Yine de yüzlerce MB değil, onlu MB seviyesine inersin.

  3. Boyut kadar güvenliği de sıkılaştır. Konteyneri non-root çalıştır, .dockerignore ile gereksiz dosyaları dışla, base imajı digest ile pinle, bağımlılık aşamasını registry layer cache’ine bıraktır ki her build’de yeniden çekilmesin.

Sonuç: Ben olsam multi-stage + Go’da distroless/static/scratch, PHP’de fpm-alpine kullanır; non-root çalışır ve .dockerignore’u sıkı tutardım. 1.2 GB’lık imaj böylece onlu MB seviyesine iner — CI/CD hızlanır, saldırı yüzeyi daralır. İmaj katmanlarının nasıl çalıştığını ve .dockerignore mantığını hub yazısında temelden anlattım; oradaki kurulum bu optimizasyonun zeminini oturtur.

İlgili Yazılar

Paylaş:

Yorumlar

Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.

Diğer Sorular

Tüm sorular

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi