Giriş
Docker Buildx, aynı Dockerfile’dan tek komutla AMD64 ve ARM64 gibi birden fazla mimari için imaj üretebilen güçlü bir eklentidir. Özellikle Apple Silicon (M1/M2) makinelere geçiş, edge cihazları ve farklı donanımlara sahip Kubernetes kümeleri göz önüne alındığında, çok mimarili (multi-arch) imaj oluşturmak hem performans hem de dağıtım kolaylığı açısından kritik hale geldi. Bu yazıda, Docker Buildx ile çok mimarili container imajı nasıl oluşturulacağını ve GitHub Actions kullanarak Docker Hub’a otomatik olarak nasıl yayınlanacağını adım adım anlatıyorum.
Neden Çok Mimarili İmaj?
Tek mimariye göre paketlenmiş bir imaj, farklı donanımlarda çalıştırılmak istendiğinde "no matching manifest for linux/arm64" gibi hatalara yol açar. Çok mimarili bir imaj ise manifest listesi sayesinde doğru platformu otomatik seçer. Bu sayede aynı etiketi (ör. latest veya 1.2.0) hem AMD64 sunucularda hem de ARM64 tabanlı cihazlarda sorunsuz kullanabilirsiniz. Sonuç: daha az bakım yükü, daha az sürpriz ve daha yüksek taşınabilirlik.
Önkoşullar
Gereksinimler: Docker 20.10+ (tercihen güncel), Buildx etkin, registry hesabı (Docker Hub veya GHCR). Apple Silicon kullanıyorsanız, emülasyon için QEMU desteği faydalıdır. Buildx çoğu modern Docker kurulumunda hazır gelse de aşağıdaki komutlarla kontrol edebilirsiniz.docker buildx versiondocker buildx ls
Yerelde Buildx ile Başlangıç
Önce bir builder oluşturup onu aktif kullanıma alalım. QEMU emülasyonunu mümkün kılmak için binfmt kurulumunu da yapabiliriz (Linux ortamlarında gerekebilir).docker run --privileged --rm tonistiigi/binfmt --install alldocker buildx create --use --name multiarch-builderdocker buildx inspect --bootstrap
Builder hazır olduğunda, tek komutla AMD64 ve ARM64 için imaj inşa edip registry’ye push edebiliriz.
Örnek Dockerfile ve Build Komutu
Aşağıdaki Node.js tabanlı örnek Dockerfile, BUILDPLATFORM/TARGETPLATFORM değişkenleriyle platforma duyarlı, küçük ve üretime uygun bir imaj üretir.# syntax=docker/dockerfile:1.6FROM --platform=$BUILDPLATFORM node:20-alpine AS buildWORKDIR /appCOPY package*.json ./RUN npm ci --only=productionCOPY . .RUN npm run buildFROM --platform=$TARGETPLATFORM node:20-alpineWORKDIR /appCOPY --from=build /app /appEXPOSE 3000CMD ["node", "dist/index.js"]
İmajı çok mimarili olarak inşa edip push etmek için:docker logindocker buildx build \ --platform linux/amd64,linux/arm64 \ -t KULLANICI_ADI/uygulama:1.0.0 \ -t KULLANICI_ADI/uygulama:latest \ --push .
Önbellek ve SBOM/Provenance
Build sürelerini kısaltmak için registry tabanlı önbellek kullanabilirsiniz. Ayrıca tedarik zinciri güvenliği bağlamında SBOM ve provenance meta verileri üretmek iyi bir pratiktir.docker buildx build \ --platform linux/amd64,linux/arm64 \ --cache-to=type=registry,ref=KULLANICI_ADI/uygulama:buildcache,mode=max \ --cache-from=type=registry,ref=KULLANICI_ADI/uygulama:buildcache \ --sbom=true --provenance=true \ -t KULLANICI_ADI/uygulama:1.0.0 \ --push .
GitHub Actions ile Otomasyon
CI/CD hattında her push veya tag için otomatik çok mimarili build almak için GitHub Actions iş akışı aşağıdaki gibi olabilir. Docker Hub kullanıcı adı ve token’ınızı repo Secrets bölümüne DOCKERHUB_USERNAME ve DOCKERHUB_TOKEN olarak eklemeyi unutmayın.name: build-and-pushon: push: tags: ["v*"]jobs: docker: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: docker/setup-qemu-action@v3 - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v6 with: context: . push: true platforms: linux/amd64,linux/arm64 tags: ${{ secrets.DOCKERHUB_USERNAME }}/uygulama:latest cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/uygulama:buildcache cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/uygulama:buildcache,mode=max
Etiketleme ve Sürümleme Stratejisi
Semantik versiyonlama (örn. 1.2.3) ile birlikte major, minor ve latest etiketlerini birlikte yayınlamak yaygın bir pratik. Örneğin v1.2.3 için şu