konteyner güvenliği etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
konteyner güvenliği etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

27 Kasım 2025 Perşembe

Docker Buildx ile Çoklu Mimarili İmaj Üretimi, İmzalama ve SBOM: Uçtan Uca Rehber

Giriş

Apple Silicon (arm64) ve x86_64 (amd64) dünyasının iç içe geçtiği günümüzde, tek bir Docker imajını birden fazla mimari için üretmek artık bir lüks değil, gereklilik. Üstelik iş yalnızca imajı derlemekle bitmiyor; tedarik zinciri güvenliği gereksinimleri sebebiyle imajları imzalamak ve yazılım malzeme listesi (SBOM) üretmek de kritik hale geldi. Bu rehberde, Docker Buildx ile çoklu mimari imaj üretmeyi, cosign ile imzalamayı ve syft ile SBOM oluşturup imaja iliştirmeyi adım adım anlatıyorum.

Önkoşullar

Makinenizde güncel Docker (mümkünse 24+), Buildx eklentisi (Docker Desktop veya docker-buildx plugin), ve emülasyon için QEMU kurulu olmalı. Çapraz derleme için binfmt yardımıyla arm64/amd64 emülasyonu etkinleştirilebilir. Ayrıca imzalama için cosign, SBOM için syft ve opsiyonel zafiyet taraması için grype kurmanız faydalı olacaktır.

Kontrol komutları: docker buildx version, mevcut builder'ları görmek için docker buildx ls. Gerekirse yeni bir builder oluşturun: docker buildx create --name multiarch --driver docker-container --use. Emülasyon için: docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64.

Çoklu Mimarili İmaj Derleme ve Push

Çoklu mimari imaj üretmenin en pratik yolu Buildx ile manifest list oluşturmaktır. Örnek komut: docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/kullanici/uygulama:1.0 --push . Bu komut, her mimari için ayrı imaj derleyip registry'e yükler ve üzerinde mimari bilgisi bulunan tek bir etiket altında (manifest list) birleştirir.

İşin sorunsuz ilerlemesi için taban imajınızın da çoklu mimari desteklemesi gerekir. Örneğin alpine, debian ya da popüler dil imajlarının çoğu arm64/amd64 sürümleri sağlar. Derleme aşamasında Go/Node/Rust gibi dillerde hedef mimariyi belirtmek için ilgili araçların bayraklarından yararlanın; örneğin Go için --build-arg ile GOOS=linux, GOARCH=arm64 gibi değişkenler verilebilir.

Derleme süresini kısaltmak ve tekrarlayan işlerden kaçınmak için BuildKit cache’i kullanın: --cache-to type=registry,ref=ghcr.io/kullanici/uygulama:buildcache,mode=max --cache-from type=registry,ref=ghcr.io/kullanici/uygulama:buildcache. Bu, özellikle CI/CD boru hatlarında çok fark yaratır.

Manifest List Doğrulama

Push tamamlandığında manifest içeriğini şöyle inceleyebilirsiniz: docker buildx imagetools inspect ghcr.io/kullanici/uygulama:1.0. Çıktıda linux/amd64 ve linux/arm64 varyantlarını görmelisiniz. Her cihaz, kendi mimarisine uygun katmanı otomatik olarak çekecektir.

Cosign ile İmaj İmzalama ve Doğrulama

Tedarik zinciri güvenliğinde ilk adım imajları imzalamaktır. Cosign iki biçimde çalışabilir: anahtarlı (key-pair) ve keyless (OIDC). Hızlı başlangıç için keyless önerilir. GitHub veya Google hesabınızla kimlik doğrulama yaparak: COSIGN_EXPERIMENTAL=1 cosign sign ghcr.io/kullanici/uygulama:1.0. Bu komut, imza verisini registry üzerinde imaj referansına bağlı şekilde saklar.

Doğrulama için: cosign verify ghcr.io/kullanici/uygulama:1.0. Çıktıda sertifika zinciri ve imzanın geçerliliği görünmelidir. İmzalama politikanızı CI’da zorunlu kılmak, üretim öncesi kabul kriterlerinin önemli bir parçasıdır.

Syft ile SBOM Üretimi ve İliştirme

SBOM (Software Bill of Materials), imajın içindeki bağımlılıkların envanteridir. Syft ile tek satırda oluşturabilirsiniz: syft ghcr.io/kullanici/uygulama:1.0 -o spdx-json > sbom.spdx.json. Bu dosyayı imaja iliştirmek için cosign attest kullanın: cosign attest --predicate sbom.spdx.json --type spdx ghcr.io/kullanici/uygulama:1.0.

SBOM’u doğrulamak veya çekmek için: cosign verify-attestation ghcr.io/kullanici/uygulama:1.0 ve cosign download attestation ghcr.io/kullanici/uygulama:1.0. SBOM, güvenlik taraması (grype, trivy) ve uyumluluk kontrolleri için referans noktasıdır.

CI/CD Entegrasyonu (GitHub Actions Örneği)

GitHub Actions’da setup-buildx ve login adımlarını ekleyip ardından çoklu mimari derlemeyi tetikleyebilirsiniz. Tipik adımlar: registry’e giriş (docker/login-action), Buildx kurulum (docker/setup-buildx-action), cache ayarları, ardından docker/build-push-action ile platform: linux/amd64,linux/arm64 şeklinde build ve push. Sonraki adımlarda sigstore/cosign-installer ile cosign kurulumu, COSIGN_EXPERIMENTAL=1 cosign sign ve syft ile SBOM üretimi yer alabilir. Workflow gizli değişkenleriyle registry token’larını ve imza politikalarını yönetmeyi unutmayın.

İpuçları ve Yaygın Hatalar

- Taban imajı multi-arch değilse derleme bir mimaride başarılı olurken diğerinde başarısız olabilir. Alternatif taban imajları deneyin veya kendi tabanınızı üretin.

- QEMU emülasyonu derlemeyi yavaşlatabilir. Yerel arm64 runner veya native builder node’ları ile süreyi ciddi şekilde düşürebilirsiniz.

- Reproducible build için sabit sürümler ve kilit dosyaları (go.sum, package-lock.json, Cargo.lock) kullanın. Değişken sürümler, SBOM ve zafiyet taraması sonuçlarını dalgalandırır.

- Cache’i registry üzerinde tutmak, farklı runner’lar arasında tekrar derlemeyi azaltır. mode=max ile en agresif önbelleği etkinleştirebilirsiniz.

- İmza ve attestation objeleri için üretim ve test kayıtlarını ayırın. Etiketleme stratejinizde :dev, :staging, :prod gibi net kanallar oluşturun.

Sonuç

Docker Buildx ile çoklu mimari imaj üretmek, hem geliştirici deneyimini iyileştirir hem de farklı donanım platformlarında tek bir etiket üzerinden dağıtım yapmanızı sağlar. Cosign ile imzalama ve Syft ile SBOM üretimi ise tedarik zinciri güvenliğinizin bel kemiğidir. Bu üç adımı CI/CD boru hattınıza entegre ettiğinizde, yalnızca hızlı değil, aynı zamanda doğrulanabilir ve denetlenebilir bir yayın sürecine sahip olursunuz. Bugünden başlayın; manifest list, imza ve SBOM’u varsayılanınız haline getirin.

23 Ekim 2025 Perşembe

Docker Distroless ile Node.js API’nizi Hafif ve Güvenli Hale Getirme (Multi-Stage Build Rehberi)

Giriş

Üretim ortamında konteyner imaj boyutu, güvenlik yüzeyi ve başlatma hızı kritik öneme sahiptir. Geleneksel Node.js tabanlı imajlar (ör. Debian/Alpine) paket yöneticileri, shell ve gereksiz araçlar içerdiğinden hem büyük olur hem de CVE yüzeyi genişler. Bu yazıda, Docker Multi-Stage Build ve Distroless yaklaşımını birleştirerek, Node.js 20 tabanlı bir API’yi onlarca megabayta düşürüp, saldırı yüzeyini minimize etmeyi gösteriyorum.

Neden Distroless?

Distroless imajlar, uygulamanızı çalıştırmak için gerekli en minimal dosyaları içerir; shell, paket yöneticisi veya gereksiz araçlar yoktur. Bu sayede: (1) İmaj boyutu küçülür, (2) Potansiyel güvenlik açıkları azalır, (3) Soğuk başlatma hızlanır, (4) Tedarik zinciri şeffaflığı artar. Dezavantajı ise hata ayıklamanın klasik yöntemlerle (bash, curl) yapılamamasıdır; ancak doğru loglama ve metrikler bu ihtiyacı büyük ölçüde ortadan kaldırır.

Ön Koşullar

- Docker 24+ (BuildKit aktif önerilir)
- Node.js 20 LTS ile uyumlu bir proje (ör. Express, Fastify, NestJS)
- Üretim derlemesi yapan bir betik: npm run build (ör. TypeScript için tsc)

Multi-Stage Dockerfile Mantığı

Amaç, bağımlılıkları ve derlemeyi ağır bir builder evresinde yapmak, ardından sadece çalışması gereken artefaktları Distroless evresine kopyalamaktır. Aşağıda örnek bir Dockerfile yapısı yer alır:

# 1) Bağımlılıklar
FROM node:20-bookworm-slim AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

# 2) Derleme
FROM deps AS build
COPY . .
RUN npm run build && npm prune --production

# 3) Distroless (final)
FROM gcr.io/distroless/nodejs20-debian12 AS runner
WORKDIR /app
ENV NODE_ENV=production
# Distroless'ta yerleşik 'nonroot' kullanıcısı mevcut
USER nonroot
COPY --from=build /app/dist ./dist
COPY --from=build /app/package*.json ./
COPY --from=build /app/node_modules ./node_modules
EXPOSE 3000
# Distroless nodejs imajı 'node' ENTRYPOINT'i ile gelir
CMD ["dist/index.js"]

Adım Adım Kurulum

1) package.json’ı hazırlayın: Üretim derlemesi için "build" komutunuz olsun (ör. "build": "tsc"). Sunucuyu relative path ile başlatabileceğinizden emin olun (ör. "start": "node dist/index.js").

2) Dockerfile’ı ekleyin: Yukarıdaki örneği kök dizine Dockerfile adıyla koyun. TypeScript kullanıyorsanız dist klasörünün üretildiğinden emin olun.

3) İmajı derleyin: docker build -t api:distroless . komutuyla derleyin. Build cache’i hızlandırmak için package*.json dosyalarını erken kopyaladığımıza dikkat edin.

4) Konteyneri çalıştırın: docker run -p 3000:3000 api:distroless komutuyla ayağa kaldırın. Uygulamanız http://localhost:3000 üzerinden yanıt vermelidir.

Güvenlik ve İyileştirme İpuçları

Non-root çalıştırma: Distroless imajlarda USER nonroot kritik bir adımdır. Bu, olası bir ihlalde yetkileri sınırlar.

ENV ve gizli bilgiler: Üretimde sırları ENV ile bake etmeyin. Orkestratör (Kubernetes Secrets, ECS, Swarm) üzerinden enjekte edin. Yerel testte --env-file kullanabilirsiniz.

SBOM ve tarama: Tedarik zinciri görünürlüğü için Syft ile SBOM çıkarın (syft packages docker:api:distroless) ve Grype/Trivy ile tarayın. Distroless, raporlanan CVE sayısını anlamlı biçimde azaltır.

Boyut ve performans: Tipik bir Node imajı 300–900 MB olabilirken distroless ile 70–150 MB bandı sık görülür. Daha küçük imaj, daha hızlı pull ve daha hızlı ölçekleme demektir.

Healthcheck: Distroless’ta shell olmadığından curl yoktur. Sağlık kontrolünü uygulama içi /health endpoint’i ile orkestratörden yapın. Alternatif olarak Node ile bir komut yazabilirsiniz (ör. HEALTHCHECK CMD ["node","-e","require('http').request({host:'127.0.0.1',port:3000,path:'/health'},r=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1)).end()"]).

Sık Yapılan Hatalar

COPY sırası: COPY . . satırını npm ci’dan önce yazmak, her değişimde cache’i bozar ve build’i yavaşlatır. Önce package*.json, sonra bağımlılıklar, en sonda kaynak kod.

Gereksiz dev bağımlılıkları: Üretim imajına devDependencies taşımayın. npm prune --production veya npm ci --omit=dev kullanın.

Shell beklentisi: Distroless’ta /bin/sh yoktur. Debug için logs, structured logging (JSON) ve APM/Tracing (OpenTelemetry) tercih edin. İhtiyaç halinde aynı artefaktlarla ikinci bir “debug” imajı üretebilirsiniz (ör. Alpine tabanlı).

Güncel Pratikler

- Node 20 LTS kullanın ve düzenli güvenlik güncellemelerini takip edin.
- İmajınızı cosign ile imzalayıp politikalar aracılığıyla doğrulayın.
- Read-only root filesystem ve drop capabilities (Kubernetes) gibi kısıtlamalarla koşun.
- ROOTLESS Docker ya da Pod Security Standartlarıyla ek sertleştirme sağlayın.

Sonuç

Distroless ve Multi-Stage Build, Node.js servislerinizi hem hafif hem de güvenli hale getirmenin pratik bir yoludur. Daha küçük imajlar, daha hızlı dağıtım ve daha düşük saldırı yüzeyi anlamına gelir. Üretime geçerken non-root kullanıcı, SBOM, tarama ve gözlemlenebilirlik (logs/metrics/traces) gibi temel prensipleri uyguladığınızda, bakım maliyeti düşer ve ölçeklenebilirlik artar. Mevcut Dockerfile’ınızı yukarıdaki adımlarla iyileştirerek ilk günden somut kazanım elde edebilirsiniz.

30 Eylül 2025 Salı

Docker Buildx ile Çok Mimarili İmaj Oluşturma ve Cosign ile İmzalama (Güncel Rehber)

Giriş

Apple Silicon (ARM64) cihazların yaygınlaşması ve edge sunucuların çoğalmasıyla, tek bir mimariye derlenmiş konteyner imajları hızla demode oldu. Üretim ortamında aynı uygulamayı hem linux/amd64 hem de linux/arm64 üzerinde sorunsuz çalıştırmak için Docker Buildx ile çok mimarili (multi-arch) imaj üretmek artık bir zorunluluk. Bu yazıda, Buildx’i etkinleştirme, çok mimarili push, önbellek optimizasyonu ve imaj imzalama (Sigstore Cosign) adımlarını pratik ve güncel bir yaklaşımla anlatıyorum.

Neden Çok Mimarili İmaj?

M1/M2/M3 Mac’lerde lokal geliştirme yapıp, üretimde x86_64 (amd64) sunuculara deploy etmek en yaygın senaryo. Multi-arch sayesinde tek bir etiket ile iki mimariyi de içeren bir manifest yayınlarsınız; docker pull işlemi çalıştığı platforma uygun katmanı otomatik indirir. Böylece ayrı Dockerfile’lar, ayrı registry etiketleri ve karmaşık akışlar ortadan kalkar.

Önkoşullar

- Docker 20.10+ ve BuildKit etkin (varsayılan).
- QEMU emülasyonu için binfmt kurulumu (host’ta veya builder içinde).
- Bir container registry (Docker Hub, GHCR, ECR vb.).
- Opsiyonel: İmaj imzalama için Cosign ve SBOM üretimi.

Buildx’i Etkinleştirme ve Binfmt Kurulumu

Önce Buildx sürümünüzü kontrol edin: docker buildx version. Yeni bir builder oluşturup varsayılan yapın: docker buildx create --name multi --use. Gerekirse platform emülasyonu için docker run --privileged --rm tonistiigi/binfmt --install all komutunu çalıştırın. Bu adım, ARM64 makinede amd64 image derlemek gibi çapraz mimari senaryoları mümkün kılar.

Tek Komutta Çok Mimarili İmaj Üretme

Proje dizininizde basit bir Dockerfile olduğunu varsayalım. Multi-arch build ve push için şu kalıbı kullanabilirsiniz: docker buildx build --platform linux/amd64,linux/arm64 -t kullanici/uygulama:1.0 --push . Bu komut, her iki mimari için ayrı katmanlar üretir ve registry’e tek bir manifest altında yükler. Test etmek için docker buildx imagetools inspect kullanici/uygulama:1.0 çıktısında iki platformu görmelisiniz.

Performans ve Önbellek İpuçları

Yapı sürelerini kısaltmak için BuildKit cache kullanın. Registry tabanlı önbellek için: --cache-to type=registry,ref=kullanici/uygulama:cache,mode=max ve --cache-from type=registry,ref=kullanici/uygulama:cache seçeneklerini ekleyin. Ayrıca, Dockerfile’ı katman dostu yazmak (bağımlılıkları erken kopyalamak, --mount=type=cache kullanımı, çok aşamalı derleme) build sürelerini dramatik şekilde azaltır.

CI/CD’de Otomasyon (GitHub Actions Örneği)

CI’da tipik akış: checkout → docker/setup-qemu-action ile QEMU → docker/setup-buildx-action ile Buildx → registry’ye login → docker buildx build --platform linux/amd64,linux/arm64 --push. Sürüm etiketlerini v1.2.3, latest ve commit SHA gibi çoklu tag’lerle birlikte yayınlamak, tüketicilerin sağlam bir sürüm stratejisi izlemesine yardımcı olur.

Güvenlik: Cosign ile İmaj İmzalama ve SBOM

Supply chain güvenliği artık lüks değil. Cosign ile imajlarınızı imzalayarak, imajın sizden çıktığını kanıtlayabilirsiniz. Adımlar basit: cosign generate-key-pair ile bir anahtar çifti üretin; cosign sign --key cosign.key kullanici/uygulama:1.0 ile imzalayın; doğrulama için cosign verify --key cosign.pub kullanici/uygulama:1.0 çalıştırın. Build aşamasında SBOM eklemek için Buildx’in --sbom=true ve --provenance=mode=max seçeneklerini kullanabilir, yazılım bileşen envanterini otomatik üretip imajla ilişkilendirebilirsiniz.

Yaygın Hatalar ve Çözüm Yolları

- “no match for platform in manifest”: Multi-arch manifest push edilmemiş olabilir; --push bayrağını ve --platform listesini kontrol edin.
- Temel imaj arm64 yok: Kullandığınız base image’in her iki mimari için resmi desteği olduğundan emin olun. Örneğin alpine, debian ve ubuntu çoğunlukla multi-arch sunar.
- Yavaş build: QEMU emülasyonu doğal olarak yavaştır; mümkünse native runner kullanın (amd64 için amd64 runner). Cache’i registry’ye yazmayı ve tekrar kullanmayı unutmayın.
- İmza doğrulanmıyor: Doğru public key kullandığınızdan ve imzanın ilgili etikete uygulandığından emin olun. CI ortamında key yönetimi için OIDC ile keyless imzalama da değerlendirilmelidir.

En İyi Uygulamalar

- Tag stratejisi: semver (+ latest), commit SHA ve platform bağımsız tek etiket kullanın.
- Reproducible build: Sabit bağımlılık versiyonları ve belirli builder sürümleri seçin.
- Güvenlik: İmza ve SBOM’u pipeline’ın ayrılmaz parçası haline getirin, hatalı doğrulamada deploy’u durdurun.
- Gözlemlenebilirlik: Build süreleri, cache isabet oranı ve başarısızlık nedenlerini CI’da raporlayın.

Sonuç

Docker Buildx, çok mimarili konteyner üretimini günlük pratiğin doğal bir parçası haline getiriyor. Doğru yapılandırmayla tek komutta amd64 ve arm64 için imaj üretip push edebilir, CI/CD’de otomatikleştirip, Cosign ile imzalayarak supply chain güvenliğini güçlendirebilirsiniz. Bu yaklaşım, hem geliştirici deneyimini iyileştirir hem de üretim ortamlarında taşınabilirlik ve güvenilirliği artırır.