Giriş
Monorepo yapısında birden fazla servis için Docker imajı üretmek, özellikle hem amd64 hem de arm64 mimarilerini hedeflemek istediğinizde çabucak karmaşıklaşır. GitHub Actions ve Docker Buildx, doğru yapılandırıldığında bu süreci hem hızlı hem de güvenli hale getiriyor. Bu yazıda, çoklu platform (multi-arch) imaj oluşturma, build önbelleği (cache) kullanma, SBOM üretme ve imaj imzalama adımlarını pratik bir akış üzerinden anlatacağım. Amacım, “tek seferde kurulup unutulan” bir CI/CD hattı kurmanıza yardımcı olmak.
Neden Çoklu Platform İmaj?
Apple Silicon (arm64) yaygınlaştıkça geliştiriciler ve üretim ortamları farklı mimarilerde çalışabiliyor. İmajlarınızı linux/amd64 ve linux/arm64 için aynı anda yayınlamak, hem geliştirici deneyimini iyileştirir hem de edge/IoT gibi arm tabanlı cihazlarda dağıtımı kolaylaştırır. Buildx, bu geçişi QEMU emülasyonu ile otomatikleştirebilir, böylece tek bir komutla iki mimariyi de üretebilirsiniz.
Gereksinimler ve Gizli Anahtarlar
Başlamadan önce bir container registry belirleyin (Docker Hub veya GHCR). GitHub deposunda Secrets bölümüne aşağıdaki bilgileri ekleyin: REGISTRY_USERNAME, REGISTRY_TOKEN (veya GHCR için GHCR_PAT). Eğer imaj imzalayacaksanız, Cosign anahtar çiftinizi ya da keyless (OIDC) yöntemi kullanacaksanız ilgili izinleri de ayarlayın. Monorepo kullanıyorsanız her servis için bir context yolu tanımlayın (ör. services/api, services/web).
Workflow’un İskele Yapısı
Tipik bir akışta, tetikleyiciler push (özellikle tag ile sürümleme), pull_request ve isteğe bağlı olarak workflow_dispatch olur. Adımlar sırasıyla şöyle ilerler: kodun çekilmesi (actions/checkout), QEMU kurulumu (çoklu platform için), Buildx kurulumu, registry’e giriş, build ve push. Performans için BuildKit önbelleğini GitHub Actions içi önbellek (type=gha) ile kullanmanızı öneririm. Bu sayede aynı katmanları tekrar tekrar derlemek zorunda kalmazsınız.
Örnek akış mantığı şu sırayı izler: “Checkout → QEMU kur → Buildx kur → Registry login → Çoklu platform build + push → SBOM üret → İmza → Artefact yükleme”. YAML dosyasında docker/build-push-action için platforms: linux/amd64,linux/arm64, cache-from: type=gha, cache-to: type=gha,mode=max gibi ayarları etkinleştirin. Etiketlemede semantik sürüm (örn. v1.4.2) ile latest tag’ini birlikte yayınlayın; branch tabanlı tag’ler (örn. edge) test ortamlarına akış sağlar.
SBOM ve Tedarik Zinciri Güvenliği
Güncel güvenlik süreçlerinde SBOM (Software Bill of Materials) zorunluluğa yakın bir standart haline geldi. Buildx/BuildKit ile attest=type=sbom kullanarak imajın içine SBOM gömebilir veya Syft gibi bir araçla ayrı bir dosya olarak üretip CI artefact’ı olarak saklayabilirsiniz. Ben genellikle her ikisini de yapıyorum: imaj attestation, dışa aktarılan bir SBOM ve basit bir HTML rapor; böylece hem makine hem de insan odaklı kontroller kapsanmış oluyor.
İmza tarafında, Cosign ile imajınızı imzalamak, üretim registry’nizde kimlik doğrulanmış ve değişmez bir iz bırakır. Keyless imza (OIDC) kullanıyorsanız GitHub Actions koşusunda sağlanan kimlik belirteçleriyle etkileşimsiz imza atabilirsiniz. Üretim tarafında ise; admission controller’lar veya politika motorları (örn. Kyverno, Connaisseur) ile “sadece imzalı imajlar” kuralını uygulamak, supply chain risklerini ciddi oranda azaltır.
Monorepo ve Build Matrisi
Monorepo’da birden çok dizini tek akışta derlemek için matris kullanın. Her matris girdisi bir servis yolunu ve hedef imaj adını taşısın. Değişiklik bazlı build için paths-filter ile dosya/dizin değişikliklerini algılayan bir ön adım ekleyip sadece etkilenen servisleri derlemek, gereksiz build’lerin önüne geçer. Bu, özellikle cache etkinleştirilmiş Buildx ile birleştiğinde, PR başına dakikalarca zaman tasarrufu sağlar.
Önbellek (Cache) İncelikleri
Build performansı, doğru katmanlaşmış bir Dockerfile ve doğru cache stratejisi ile dramatik biçimde iyileşir. Bağımlılık kurulumunu (örn. npm ci, pip install, go mod download) kaynak kodundan önceki katmanlarda tutun ve sadece lock dosyası değiştiğinde invalid olsun. GitHub Actions içinde type=gha cache’i kullanırken mode=max seçimi daha agresif bir yeniden kullanım sağlar. Pull request build’lerinde push: false ile imajı registry’ye itmeden cache’i yine de güncelleyebilirsiniz.
Sürümleme ve Etiket Stratejisi
Üretim tutarlılığı için semantik sürümleme öneririm. Tag’lerinizden dinamik olarak şu etiketleri çıkarın: vX.Y.Z, vX.Y, vX ve latest. Ana branş için edge veya canary etiketi de ekleyebilirsiniz. Bu yaklaşım tüketen taraflara esnek güncelleme kanalları sunar ve geri dönüş (rollback) senaryolarını netleştirir.
Sık Karşılaşılan Sorunlar
QEMU tabanlı derlemelerde nadiren de olsa bellek/süre limitine takılabilirsiniz; çözüm olarak job’a daha yüksek zaman limiti tanımlayın veya daha küçük base image’lar kullanın. “manifest list” hataları genellikle eksik push veya yanlış tag kombinasyonundan kaynaklanır; multi-arch push’un tek adımda yapılmasına dikkat edin. SBOM/attestation çıktılarının registry tarafından desteklenip desteklenmediğini kontrol edin; bazı özel registry’ler attestation’ı farklı isimlendirme ile saklayabiliyor.
Sonuç
GitHub Actions + Docker Buildx ikilisiyle monorepo’nuzda çoklu platform imaj üretmek, cache ile hızlandırmak, SBOM ve imza ile güvence altına almak zor değil; ancak birkaç temel ayrıntıyı doğru ayarlamak şart. Yukarıdaki iskelet yaklaşımı kendi proje yapınıza uyguladığınızda, hem geliştirici geri bildirim döngünüz hızlanacak hem de tedarik zinciri güvenliği gereksinimlerini karşıladığınızı bilerek daha rahat uyuyacaksınız. İleride bu akışı, imaj tarama, imza doğrulama ve politika kontrolü adımlarıyla genişleterek uçtan uca güvenli bir dağıtım hattına dönüştürmeniz mümkün.