Giriş
Apple Silicon (ARM64) makinelerin ve bulut ortamlarında ARM sunucuların yaygınlaşmasıyla, tek mimariye (örneğin yalnızca AMD64) derlenen imajlar kullanıcı deneyimini ve dağıtımı zorlaştırıyor. Docker Buildx, tek komutla birden fazla mimari için (AMD64, ARM64, ARMv7 vb.) imaj üretmeyi ve tek bir manifest altında yayımlamayı kolaylaştırıyor. Bu yazıda, yerelde ve GitHub Actions ile CI/CD hattında çok mimarili imaj oluşturmayı, cache kullanmayı, SBOM/provenance üretmeyi ve sık karşılaşılan sorunları çözmeyi adım adım ele alacağım.
Neden Çok Mimarili İmaj?
- Kullanıcı kapsama alanı: Hem x86_64 (AMD/Intel) hem ARM64 (Apple M-serisi, Graviton) sistemlerde sorunsuz çalışır.
- Performans ve maliyet: ARM altyapılarında daha düşük maliyet ve daha iyi watt başına performans elde edilebilir.
- Tek etiket, çok platform: Manifest listesi sayesinde docker pull myorg/app:latest komutu, çalıştığınız platforma uygun imajı otomatik çeker.
Ön Koşullar
- Docker 24+ ve Buildx etkin (Docker Desktop kullanıyorsanız Buildx varsayılan gelir).
- Registry erişimi: Docker Hub, GitHub Container Registry (GHCR) veya özel bir OCI uyumlu kayıt defteri.
- Yerel testlerde emülasyon gerekebilir; QEMU binfmt kurulu olmalı. Docker Desktop bunu genellikle otomatik sağlar.
Yerelde Buildx ile Çok Mimarili Build
1) Bir Buildx builder oluşturun ve kullanın: docker buildx create --name multiarch --use ve ardından docker buildx inspect --bootstrap. Bu adım BuildKit’i ve platform desteğini başlatır.
2) Emülasyon (gerekiyorsa): Linux makinelerde yoksa docker run --privileged --rm tonistiigi/binfmt --install all komutuyla QEMU kurabilirsiniz. Docker Desktop kullananlar çoğu zaman bu adımı atlayabilir.
3) Çoklu platform build ve push: Örneğin docker login ile kayıt defterine giriş yaptıktan sonra docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/kullanici/uygulama:1.0 -t ghcr.io/kullanici/uygulama:latest --push . komutunu çalıştırın. Bu komut, her iki mimari için imaj üretir, registry’ye yükler ve tek bir manifest altında birleştirir.
4) Doğrulama: docker buildx imagetools inspect ghcr.io/kullanici/uygulama:latest çıktısında manifest içinde AMD64 ve ARM64 platformlarını görmelisiniz.
Dockerfile İpuçları (TARGETPLATFORM ve BUILDPLATFORM)
- Çok mimaride tutarlı build’ler için Dockerfile’ın başına ARG TARGETPLATFORM ve ARG BUILDPLATFORM ekleyin. Bazı taban imajlarını seçerken bu argümanlar kritik olabilir.
- Derleme araçları içeren çok aşamalı bir yaklaşım kullanın: “builder” aşamasında derleyin, “runtime” aşamasında minimal taban imajına kopyalayın.
- Go/Node/Python gibi ekosistemlerde platforma duyarlı bağımlılıklar için koşullu adımlar planlayın. Örneğin Go’da CGO kullanıyorsanız uygun CC ve GOARCH ayarlarını set edin.
GitHub Actions ile Otomasyon
CI/CD sürecinde multi-arch build için tipik adımlar: QEMU kurulum, Buildx hazırlığı, registry’ye giriş, build-push ve cache. Örnek akış şu şekildedir:
- QEMU: docker/setup-qemu-action@v3 ile arm64 ve amd64 emülasyonunu etkinleştirin.
- Buildx: docker/setup-buildx-action@v3 ile bir builder oluşturun.
- Registry Login: docker/login-action@v3 ile Docker Hub veya GHCR’a giriş yapın.
- Build & Push: docker/build-push-action@v5 ile platforms=linux/amd64,linux/arm64, push=true, tags alanlarını doldurun. Ön bellek için cache-from=type=gha ve cache-to=type=gha,mode=max kullanın. Yazılım tedarik zinciri metadatası için provenance=mode=max ve sbom=true parametrelerini etkinleştirin.
- Semantik etiket: 1.2.3, 1.2 ve latest gibi çoklu etiket yayınlayarak tüketimi kolaylaştırın.
Cache ve Performans
- Build sürelerini kısaltmak için katmanları sabitleyin ve gereksiz dosyaları kopyalamayın (örn. .dockerignore kullanın).
- Registry tabanlı cache ile farklı runner’larda bile hız kazanın. BuildKit GHA cache, büyük monorepo’larda ciddi fayda sağlar.
- Dil/araç cache’leri (Go mod, npm ci, pip cache) için katman sırasını optimize edin; bağımlılıkların daha az değiştiği katmanları üstte tutun.
Güvenlik: SBOM ve Provenance
- SBOM (Software Bill of Materials) ve provenance, tedarik zinciri görünürlüğü sağlar. Buildx ile oluşturulan attestation’lar, imaj içeriğini ve nasıl üretildiğini kanıtlar.
- Gerektiğinde imza eklemek için Cosign gibi araçları entegre edin. İmajlarınızı politikalarla (örn. Kyverno, Tekton Chains) doğrulayabilirsiniz.
Yaygın Hatalar ve Çözümleri
- Exec format error: Genellikle QEMU/binfmt kurulmadığında veya emülasyon devre dışı olduğunda görülür. QEMU’yu yeniden yükleyin ve Buildx builder’ı --bootstrap ile yenileyin.
- Yerel bağımlılıklar: Node-gyp, Python C uzantıları gibi bileşenler mimariye duyarlıdır. Derleme aşamasında uygun derleyicilerin ve kütüphanelerin kurulduğundan emin olun.
- Taban imaj uyumsuzluğu: Bazı hafif taban imajlar (distroless, alpine) belirli mimarilerde ek paket gerektirebilir. İmaj seçiminde --platform ile test edin, mümkünse resmi çok mimarili taban imajları tercih edin.
- Performans: Emülasyon ile derleme yavaştır. Mümkünse native ARM64 ve AMD64 runner’lar kullanın (örn. karma self-hosted runner filosu).
Sonuç
Docker Buildx, modern dağıtım ihtiyaçları için kritik olan çok mimarili imajları üretmenin en pratik yolu. Yerelde basit bir builder ve gerektiğinde QEMU ile başlayabilir, üretim ortamında GitHub Actions gibi bir CI/CD hattı üzerinden cache, SBOM ve provenance özellikleriyle güvenli ve hızlı yayın yapabilirsiniz. Sonuçta tek bir etiketle her platformda çalışan imajlar sunar, kullanıcı deneyimini iyileştirir ve operasyonel karmaşıklığı azaltırsınız.