GitHub Actions etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
GitHub Actions etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

1 Aralık 2025 Pazartesi

Docker Buildx ile Çok Mimarili Konteyner İmajı Oluşturma ve GitHub Actions ile Otomasyon

Giriş: Neden Çok Mimarili İmaj?

Apple Silicon (ARM64) cihazların, bulut sağlayıcıların ve edge cihazların yükselişi, tek mimariye derlenmiş konteyner imajlarının yeterli olmadığı bir dönemi başlattı. Uygulamanızı hem linux/amd64 hem de linux/arm64 üzerinde sorunsuz çalıştırmak istiyorsanız, Docker Buildx ve QEMU emülasyonu devreye giriyor. Bu yazıda, yerelde hızlıca çok mimarili imaj üretecek, ardından GitHub Actions ile her push veya tag’de otomatik olarak registry’ye yayınlayacak bir kurulum yapacağız.

Önkoşullar ve Temel Kavramlar

Başlamadan önce sisteminizde Docker Engine veya Docker Desktop’ın güncel bir sürümü kurulu olmalı. Buildx varsayılan olarak Docker ile gelir, ancak Linux kullanıcıları için docker buildx komutunun aktif olduğundan emin olun. Yerelde farklı mimariler için derleme yaparken QEMU desteği gerekir; Buildx bunu otomatik konfigüre edebilir. Ayrıca Docker Hub veya GHCR (GitHub Container Registry) gibi bir kayıt defterinde hesabınız ve kimlik bilgisi gerekecek. “Mimari” derken kastedilen: Intel/AMD tabanlı sunucular için amd64, Apple M serisi ve çoğu ARM tabanlı cihaz için arm64.

Dockerfile: Çok Aşamalı ve Mimariden Bağımsız

Örnek olarak küçük bir Go uygulaması için çok aşamalı bir Dockerfile kullanalım. Go, cross-compile’a yatkın olduğu için çok mimarili imajlarda pratiktir. Buildx, derleme sırasında TARGETPLATFORM ve TARGETARCH gibi değişkenleri otomatik olarak geçirir.

# syntax=docker/dockerfile:1.6
FROM golang:1.22-alpine AS build
WORKDIR /src
COPY . .
# CGO'yu kapatıp hedef mimariyi Buildx'ten alıyoruz
ARG TARGETARCH
ENV CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go build -o /out/app .

FROM alpine:3.20 AS runtime
RUN adduser -D -u 10001 app
USER app
COPY --from=build /out/app /app
EXPOSE 8080
ENTRYPOINT ["/app"]

Yukarıdaki Dockerfile, cache mount’larını kullanarak derlemeleri hızlandırır, root olmayan bir kullanıcı ile çalıştırır ve minimum imaj boyutu sağlar. Benzer bir yaklaşımı Node.js, Python veya Rust projelerinde de çok aşamalı yapı ile uygulayabilirsiniz.

Buildx’i Etkinleştirme ve Yerelde Test

Önce Buildx builder’ını oluşturun ve QEMU’yu başlatın:

docker buildx create --name xbuilder --use
docker buildx inspect --bootstrap

Ardından çok mimarili imajı derleyip bir kayıt defterine itin. Örnek olarak Docker Hub kullanıyorsanız:

docker login
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t KULLANICI_ADI/uygulama:1.0.0 \
-t KULLANICI_ADI/uygulama:latest \
--push .

İmajı emülasyonla farklı mimarilerde çalıştırmayı test edebilirsiniz:

docker run --rm --platform linux/arm64 KULLANICI_ADI/uygulama:1.0.0 --help

GitHub Actions ile Otomatik Yayın

Süreci otomatikleştirmek için depo köküne .github/workflows/build.yml adında bir iş akışı ekleyin. Aşağıdaki örnek, GHCR’ye push eder; Docker Hub için registry ve kimlik bilgilerini uyarlayın.

name: build-and-push-multi-arch
on:
push:
branches: ["main"]
tags: ["v*"]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=semver,pattern={{version}}
type=ref,event=branch
type=raw,value=latest,enable={{is_default_branch}}
- uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

Bu iş akışı; QEMU’yu kurar, Buildx’i etkinleştirir, GHCR’ye giriş yapar, semantik veya branch tabanlı etiketleri otomatik üretir ve iki mimari için imajı derleyip yayınlar. Docker Hub kullanıyorsanız registry satırını kaldırıp username/password için DOCKERHUB_USERNAME ve DOCKERHUB_TOKEN gibi secret’lar tanımlayın.

İnce Ayar: Performans, Güvenlik ve Boyut

Derlemeleri hızlandırmak için cache kullanımı kritik önemdedir. Yerelde --cache-to ve --cache-from bayrakları veya GitHub Actions’ta type=gha ile katmanları önbelleğe alın. .dockerignore dosyası ile gereksiz dosyaları dışarıda bırakın. Güvenlik açısından root olmayan kullanıcı kullanmak, yalnızca gerekli portları açmak, en küçük taban imajlarını (ör. alpine veya distroless) tercih etmek, SBOM ve kaynak kanıtı için --sbom=true ve --provenance=true kullanmak iyi pratiklerdir. İmajlarınızı imzalamak için cosign ile CI adımı ekleyebilirsiniz. Etiket stratejisinde hem latest hem de v1.2.3 gibi sürüm etiketlerini birlikte yayınlamak, geriye dönük izleme ve hızlı geri dönüş (rollback) sağlar.

Yayına Alındıktan Sonra Doğrulama

Yayınlanan imajın manifest listesine bakarak gerçekten çok mimarili olup olmadığını doğrulayın: docker buildx imagetools inspect ghcr.io/HESAP/REPO:latest. Çıktıda hem linux/amd64 hem de linux/arm64 gördüğünüzde her şey yolundadır. Üretim ortamında çekme yapan sistemlerin doğru mimariyi otomatik seçeceğini unutmayın.

Sonuç

Docker Buildx, modern çok mimarili dünyada tek komutla iki farklı platforma hitap eden imaj üretmeyi kolaylaştırır. GitHub Actions ile birleştirildiğinde, her commit veya sürümde otomatik ve tekrarlanabilir bir yayın hattı elde edersiniz. Bu yaklaşım, M serisi Mac’lerde yerel geliştirmeyi hızlandırırken, bulut ve edge ortamlarında tutarlı dağıtım sağlar. Küçük dokunuşlarla (önbellek, minimal taban imaj, imzalama) performansı artırabilir ve güvenliği güçlendirebilirsiniz.

26 Kasım 2025 Çarşamba

GitHub Actions ile Çok Mimarili (Multi-Arch) Docker İmajı Oluşturma: Adım Adım Rehber

Modern uygulamalar artık tek bir mimariyle sınırlı kalmıyor. Geliştiriciler, yerel ortamda Apple Silicon (ARM64) üzerinde çalışırken üretimde x86_64 (AMD64) tabanlı sunuculara dağıtım yapabiliyor. Bu çeşitlilikte sorunsuz dağıtım için tek etiket altında birden fazla mimariyi kapsayan "çok mimarili (multi-arch)" Docker imajları kritik hale geliyor. Bu rehberde, GitHub Actions kullanarak multi-arch Docker imajlarını otomatik derleme, imzalama ve kayıt (registry) ortamına gönderme sürecini adım adım anlatıyorum.

Hedefimiz: Her push sonrasında, Docker Buildx ve QEMU emülasyonu ile linux/amd64 ve linux/arm64 platformları için imaj üretmek, doğru etiketleri (tag) eklemek, cache kullanarak derleme süresini kısaltmak ve imajı GHCR (GitHub Container Registry) ya da seçtiğiniz herhangi bir registry'ye göndermek.

Neden Çok Mimarili İmaj?

- Kullanıcılarınızın farklı donanımlarda sorunsuz çalışması için tek imaj etiketi yeterli olur. "docker pull" komutunu çalıştıran istemci, platformuna uygun manifesti otomatik çeker.

- CI/CD süreçlerinde tek kaynaklı doğrulama, test ve güvenlik taraması ile operasyon karmaşıklığını azaltırsınız.

- Tekil sürüm yönetimi sayesinde SLAs ve geri dönüş (rollback) süreçleri sadeleşir.

Önkoşullar

- Proje kök dizininde çalışır bir Dockerfile.

- GitHub Actions kullanabileceğiniz bir depo.

- GHCR kullanacaksanız paket yazma izni; varsayılan GITHUB_TOKEN yeterli olur.

- Tercihen: Semver etiketleri (örn. v1.2.3) ve ana dal (main) akışı.

Adım Adım GitHub Actions Workflow

Aşağıdaki örneği .github/workflows/docker.yml olarak kaydedin. Bu akış, push ve manuel tetiklemede devreye girer, QEMU ve Buildx kurar, GHCR'ye giriş yapar, meta bilgileri üretir ve imajı çok mimarili olarak yayınlar.

name: Build & Push Multi-Arch Image

on:
  push:
    branches: [ "main" ]
    paths:
      - "Dockerfile"
      - "src/**"
      - ".github/workflows/docker.yml"
  workflow_dispatch:

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
      id-token: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to GHCR
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels)
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}
            type=sha
          labels: |
            org.opencontainers.image.source=${{ github.repositoryUrl }}

      - name: Build and push (multi-arch)
        id: build
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
          cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
          provenance: true
          sbom: true

      # İsteğe bağlı: Keyless imaj imzalama (Sigstore Cosign)
      - name: Install Cosign
        uses: sigstore/cosign-installer@v3

      - name: Sign image (keyless)
        run: cosign sign --yes ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}
        env:
          COSIGN_EXPERIMENTAL: "1"

Bu akış, Docker Buildx ile manifest listesi üretir; yani tek bir etikete push etseniz bile altında arm64 ve amd64 varyantları bulunur. "provenance: true" ve "sbom: true" seçenekleri tedarik zinciri şeffaflığı için yazılım malzeme listesi ve oluşturulma kanıtı ekler; güvenlik ve uyumluluk süreçlerinde büyük kolaylık sağlar.

Etiketleme Stratejisi ve Sürümleme

metadata-action, branch adına (örn. main), semantik sürüm etiketlerine (örn. v1.4.0) ve commit SHA'sına göre otomatik tag üretir. Üretimde "latest" tag'ini yalnızca yayın (release) akışlarında basmanızı öneririm; aksi halde test etiketleri ile karışabilir. Ayrıca, immutability sağlamak için SHA tabanlı tag'ler geri dönüş (rollback) senaryolarında hayati önem taşır.

Ön Bellekleme (Cache) ile Hız Kazanın

Build cache'i registry üzerinde saklamak, paralel ve ardışık derlemelerde ciddi zaman kazandırır. Dockerfile adımlarını, bağımlılık indirme ve derleme katmanlarını efektif kullanacak şekilde düzenleyin: Sık değişen kod katmanlarını sona, nadir değişen bağımlılık katmanlarını başa koymak cache verimini artırır.

Güvenlik: İmza, SBOM ve Tarama

Cosign ile keyless imzalama, GitHub'ın OIDC kimlik doğrulamasını kullanarak özel anahtar yönetimini basitleştirir. SBOM üretimi ise açık kaynak lisans takibi ve güvenlik açıkları yönetimi için temel veri sağlar. Buna ek olarak, ayrı bir adımda Trivy veya Grype ile imaj taraması yaparak pipeline'ınızı tamamlayabilirsiniz.

Hızlı Test: Pull ve Çalıştırma

Yerel makinenizde mimarinize göre doğru varyantı çekip çalıştırmak için:

# amd64 veya arm64 üzerinde aynı etiketi çekersiniz
docker pull ghcr.io/<kullanici>/<repo>:main
docker run --rm ghcr.io/<kullanici>/<repo>:main

Manifesti doğrulamak isterseniz "docker buildx imagetools inspect ghcr.io/<kullanici>/<repo>:main" komutunu kullanın; listede linux/amd64 ve linux/arm64 göreceksiniz.

Sık Karşılaşılan Hatalar ve Çözümler

- QEMU bulunamadı: setup-qemu-action adımını kaçırmış olabilirsiniz; sırayı kontrol edin.

- Permission denied (GHCR): packages: write izni ve login-action yapılandırmasını gözden geçirin. Özel registry kullanıyorsanız kullanıcı adı/şifre veya token değerlerini secrets altında tanımlayın.

- Cache çalışmıyor: "cache-from" ve "cache-to" referanslarının aynı olduğundan ve imaja erişim izniniz bulunduğundan emin olun. Ayrıca Dockerfile katman sırasını optimize edin.

- Çok büyük imaj boyutu: Multi-stage build, küçük base imajlar (alpine, distroless) ve "--strip" benzeri derleme optimizasyonlarıyla boyutu düşürün.

Sonuç

GitHub Actions ile multi-arch Docker imajları üretmek, hem geliştirme hem de üretim ortamlarında taşınabilirlik ve güvenilirlik sağlar. Buildx, QEMU, otomatik etiketleme, cache, SBOM ve isteğe bağlı imzalama adımlarıyla kurduğunuz bu zincir, modern DevOps pratiklerinin omurgasını oluşturur. Rehberi projelerinize uyarlayıp aşamalı olarak genişletirseniz, edge cihazlardan bulut altyapılarına kadar tek bir imaj politikasıyla yönetilebilir, sürdürülebilir bir dağıtım stratejisi elde edersiniz.

16 Kasım 2025 Pazar

Docker Buildx ile Çok Mimarili İmaj Oluşturma ve GitHub Actions ile Otomatik Yayınlama

Apple Silicon (ARM64) dizüstüler, bulut tarafında ise yaygın AMD64 sunucular derken, tek bir Docker imajıyla her yerde çalışmak artık bir zorunluluk. Bu yazıda, Docker Buildx kullanarak çok mimarili (multi-arch) imaj oluşturmayı ve GitHub Actions ile her push sonrasında otomatik olarak Docker Hub’a yayınlamayı adım adım anlatıyorum.

Amaç net: Tek bir tag altında linux/amd64 ve linux/arm64 manifest’leri içeren, hafif ve güvenilir bir imaj üretmek. Böylece ister ARM tabanlı bir Raspberry Pi, ister AMD64 bir Kubernetes node’u olsun, aynı etiketi çekip sorunsuz çalıştırabileceksiniz.

Gereksinimler ve Temel Kavramlar

Buildx, Docker’ın gelişmiş build sürücüsüdür. Çok mimarili build, cache yönetimi, manifest listeleri ve daha fazlasını destekler. QEMU ise farklı mimariler için kullanıcı modunda emülasyon sağlayarak tek bir makinede çoklu platform derleme yapmaya imkan verir. Yayınladığınız imajlar tek bir tag altında toplanır; client çektiğinde mimarisine uygun katmanı indirir.

Yerelde Buildx Kurulumu ve Hızlı Test

Önce Buildx’in etkin olduğundan emin olun. Modern Docker Desktop sürümlerinde varsayılan olarak geliyor. CLI ile yeni bir builder yaratıp kullanabilirsiniz:

docker buildx create --name multiarch --use
docker buildx inspect --bootstrap

Basit bir test için iki platforma birden build alıp registry’ye push edelim. Docker Hub’a giriş yapmayı unutmayın:

docker login
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t KULLANICI_ADI/uygulama:deneme \
  --push .

Bu komut, yerel makinenizde emülasyon üzerinden derleyerek manifest listesi içeren bir imaj yayınlar. İndirme sırasında doğru mimari otomatik seçilir.

Dockerfile İçin Pratik İpuçları

Çok mimarili build’lerde Dockerfile’ınızı platform farkındalığı ile yazmak önemlidir. Multi-stage kullanın ve base imajları mümkün olduğunca alpine veya distroless tercih edin. Ayrıca Buildx, bazı değişkenleri otomatik sağlar: TARGETOS, TARGETARCH, TARGETPLATFORM.

Örneğin Go tabanlı bir uygulama için minimal bir Dockerfile şöyle olabilir:

# syntax=docker/dockerfile:1.7
FROM --platform=$BUILDPLATFORM golang:1.22-alpine AS builder
ARG TARGETOS TARGETARCH
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /bin/app ./cmd/server

FROM gcr.io/distroless/static:nonroot
COPY --from=builder /bin/app /app
USER nonroot:nonroot
ENTRYPOINT ["/app"]

Burada GOOS/GOARCH değerlerini Buildx sağlıyor. Böylece tek seferde ARM64 ve AMD64 çıktıları üretiliyor. Node.js benzeri yorumlanan dillerde genellikle ekstra işlem gerekmese de, mimariye bağlı paketler (ör. native addon’lar) varsa platforma özel kurulum adımları eklemelisiniz.

GitHub Actions ile Otomatik Yayınlama

Her etiket veya ana dala push sonrası otomatik olarak çok mimarili imaj yayınlamak için aşağıdaki workflow’u kullanabilirsiniz. Repository > Settings > Secrets bölümünde DOCKERHUB_USERNAME ve DOCKERHUB_TOKEN sırlarını oluşturmayı unutmayın.

name: docker-multiarch
on:
  push:
    branches: [ "main" ]
    tags: [ "v*" ]

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Extract tags and labels
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ secrets.DOCKERHUB_USERNAME }}/uygulama
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}
            type=sha

      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
          provenance: true

Bu iş akışı; QEMU ve Buildx’i hazırlar, Docker Hub’a giriş yapar, branch/semver/commit’e göre etiketler üretir, iki platform için build alır ve imajı push eder. cache-to/cache-from ile katmanlar GitHub’ın cache’inde saklandığı için tekrar derlemeler belirgin şekilde hızlanır.

Yayın Sonrası Doğrulama

Manifest’i kontrol etmek için şu komutu çalıştırın:

docker buildx imagetools inspect KULLANICI_ADI/uygulama:latest

Çıktıda hem linux/amd64 hem de linux/arm64 listeleniyorsa her şey yolunda demektir. Ayrıca bir ARM makinede docker run ile test etmek, gerçek koşulları görmek açısından faydalıdır.

İpuçları ve Sık Görülen Hatalar

- Native bağımlılıklar: OpenSSL, libc farkları gibi platforma duyarlı paketler kullanıyorsanız, base imajlarınızı ve paket yöneticinizi tutarlı seçin. Alpine ile glibc tabanlı dağıtımların farklarını göz önünde bulundurun.

- Boyut optimizasyonu: Çok aşamalı build, .dockerignore ve distroless tabanlarını kullanın. Gerekirse --target ile üretim aşamasını ayrılayın.

- Güvenlik ve tedarik zinciri: provenance: true ile SBOM/attestation üretimini açtınız; ayrıca imajları imzalamak için cosign gibi araçları değerlendirin.

- Versiyonlama: latest etiketine ek olarak semver ile tag’lemek, geriye dönüşleri kolaylaştırır. metadata-action bu süreci oldukça pratik hale getiriyor.

Sonuç olarak, Docker Buildx ve GitHub Actions birlikte kullanıldığında hem geliştirici deneyimini iyileştiriyor hem de kullanıcılarınızın farklı donanımlarda aynı imajı sorunsuzca çalıştırmasını sağlıyor. Kurulumu bir kez yaptıktan sonra, çok mimarili yayın şirketinizin CI/CD zincirinin doğal bir parçası haline gelir.

13 Kasım 2025 Perşembe

GitHub Actions ile AWS’e Şifresiz Dağıtım (OIDC) Nasıl Kurulur? Adım Adım Rehber

Modern CI/CD süreçlerinde uzun ömürlü AWS erişim anahtarlarını projelerde saklamak hem riskli hem de yönetimi zahmetli. OpenID Connect (OIDC) sayesinde GitHub Actions, AWS’e şifresiz ve kısa ömürlü kimlik doğrulama ile bağlanabiliyor. Bu yazıda, GitHub Actions’ı kullanarak AWS’e OIDC tabanlı, güvenli ve pratik bir dağıtım hattını nasıl kuracağınızı adım adım anlatıyorum.

Özet: AWS tarafında GitHub’ı güvenilen kimlik sağlayıcısı olarak tanımlayacağız, belirli bir depo/branch için kısıtlı yetkili bir IAM rolü oluşturacağız ve GitHub Actions üzerinde bu rolü geçici olarak üstlenerek dağıtım yapacağız. Anahtar saklamaya gerek yok.

OIDC ile neden şifresiz dağıtım?

Klasik yaklaşımda, GitHub Secrets içine AWS_ACCESS_KEY_ID ve AWS_SECRET_ACCESS_KEY koyarız. Bu yöntem, anahtar sızıntısı, rotasyon zorluğu ve fazladan yetkiler gibi sorunlar yaratır. OIDC ile GitHub, çalıştırdığı iş akışı (workflow) için imzalı bir kimlik belirteci üretir; AWS bu belirteci doğrular ve yalnızca o an, o koşullarda geçerli kısa ömürlü kimlik bilgileri verir. Sonuç: Daha az gizli bilgi, daha sıkı yetkilendirme ve otomatik süre sonu.

Önkoşullar

- Bir AWS hesabı ve IAM üzerinde rol oluşturma yetkisi
- GitHub’da bir depo (public ya da private)
- Dağıtım hedefi: Örneğin S3 statik site, ECR + ECS/Fargate, ya da CloudFormation/SAM ile altyapı

AWS tarafı: IAM rolü ve güven ilişkisi (trust policy)

1) AWS IAM’de Identity providers bölümünden OpenID Connect sağlayıcısı olarak token.actions.githubusercontent.com ekleyin. Audience olarak sts.amazonaws.com kullanın.
2) Yeni bir IAM rolü oluşturun ve “Web identity” seçeneğiyle az önceki sağlayıcıyı seçin.
3) Aşağıdaki gibi bir trust policy tanımlayın. Bu örnek sadece belirli bir repo ve branch için yetki veriyor:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Federated": "arn:aws:iam::HESAP_IDNIZ:oidc-provider/token.actions.githubusercontent.com" },
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:ORGANIZASYON/DEPO_ADI:ref:refs/heads/main"
}
}
}
]
}

4) Role bağlayacağınız izinleri minimum ilke (least privilege) ile ayarlayın. Örneğin S3’e sadece belirli bir bucket’a yazma yetkisi veya ECR push izinleri. Örnek bir S3 dağıtım politikası (özet):

{
"Version": "2012-10-17",
"Statement": [
{ "Effect": "Allow", "Action": ["s3:PutObject","s3:DeleteObject"], "Resource": ["arn:aws:s3:::hedef-bucket/*"] },
{ "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": ["arn:aws:s3:::hedef-bucket"] }
]
}

GitHub tarafı: Workflow ile rolü üstlenmek

GitHub Actions, OIDC token’ı otomatik üretir. AWS ile konuşmak için aws-actions/configure-aws-credentials eylemini (action) kullanacağız ve IAM rolümüzü geçici olarak üstleneceğiz. Basit bir S3 dağıtımı örneği:

name: Deploy to S3 (OIDC)
on:
push:
branches: [ "main" ]
permissions:
id-token: write # OIDC token üretimi için şart
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Kodu çek
uses: actions/checkout@v4

- name: AWS kimlik bilgilerini yapılandır
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::HESAP_IDNIZ:role/GITHUB_OIDC_DEPLOY_ROLE
aws-region: eu-central-1

- name: Statik dosyaları derle
run: |
npm ci
npm run build

- name: S3'e senkronize et
run: |
aws s3 sync ./build s3://hedef-bucket --delete

Dikkat edilmesi gereken en kritik kısım permissions altında id-token: write yetkisinin verilmesi. Bu izin olmadan GitHub, OIDC belirteci oluşturmaz ve AWS rolünü üstlenemezsiniz.

Güvenlik ve en iyi uygulamalar

- Least privilege: Role bağlanan politikalar sadece gereken servis ve kaynaklara izin versin. “*” yerine spesifik ARN kullanın.
- Branch kısıtları: Trust policy içinde sub koşulunu belirli branch’lerle sınırlandırın (ör. refs/heads/main ve refs/tags/v*).
- Ortam ayrımı: Prod/staging için farklı rol ve politikalar tanımlayın; workflow’larda çevresel değişkenlerle hedefleri ayırın.
- Geçici kimlik: Varsayılan token süreleri kısadır. Bu, çalınsa bile etkisini sınırlar. Gereksiz session duration artırımı yapmayın.

Sık karşılaşılan hatalar ve çözümü

- AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity: Trust policy’de OIDC provider ARN’i, audience ve subject desenini kontrol edin.
- Invalid identity token: GitHub OIDC domain’i ve thumbprint otomasyonlarını doğru oluşturduğunuzdan emin olun; provider’ı tekrar eklemek çoğu kez sorunu çözer.
- Missing id-token permission: Workflow permissions kısmında id-token: write yoksa ekleyin.
- Bucket veya ECR erişim hataları: IAM rolüne eklediğiniz izin politikasının kaynak ARN’lerini ve region bilgisini doğrulayın.

Gelişmiş kullanım: ECR + ECS/Fargate dağıtımı

S3 yerine konteyner dağıtıyorsanız, aynı rol ile ecr:BatchCheckLayerAvailability, ecr:PutImage, ecr:GetAuthorizationToken gibi izinleri verip Docker imajını ECR’a push edebilir, ardından aws ecs update-service ile hizmeti yeni imaja yönlendirebilirsiniz. Tüm akış yine şifresiz ve OIDC tabanlı kalır.

Sonuç olarak, GitHub Actions + OIDC yaklaşımı, güvenliği artırırken bakım yükünü azaltır. API anahtarlarıyla uğraşmadan, denetlenebilir ve politikalarla sıkı şekilde sınırlandırılmış bir dağıtım boru hattı elde edersiniz. Yeni projelerde varsayılan tercih olarak OIDC’yi değerlendirmenizi öneririm.

6 Kasım 2025 Perşembe

Docker Buildx ile Çok Mimarili (AMD64 + ARM64) Container İmajı Yayınlama: Adım Adım Rehber

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.

11 Ekim 2025 Cumartesi

GitHub Actions ile Monorepo’da Çoklu Platform Docker İmajı, Önbellekli Build ve SBOM/İmza (Buildx Rehberi)

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.

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.

26 Eylül 2025 Cuma

GitHub Actions ile Docker Buildx Kullanarak Çok Mimarili İmaj (amd64 + arm64) Yayınlama Rehberi

Kapsayıcı tabanlı dağıtımların hızla arttığı günümüzde, tek bir mimariye bağlı kalmak ciddi bir kısıt olabilir. Özellikle bulut sağlayıcılar ve edge cihazları (Raspberry Pi gibi ARM tabanlı sistemler) söz konusu olduğunda, amd64 ve arm64 için tek bir sürüm hattından imaj üretebilmek büyük avantaj sağlar. Bu yazıda, GitHub Actions ve Docker Buildx kullanarak çok mimarili (multi-arch) imajı nasıl inşa edip hem Docker Hub hem de GHCR’ye nasıl yayınlayacağınızı adım adım anlatıyorum.

Neden Buildx? Buildx, BuildKit’i temel alır ve çoklu platform inşa, gelişmiş önbellekleme, yerleşik SBOM/provenance gibi özellikleri etkinleştirir. Bunun anlamı: Tek bir pipeline ile linux/amd64 ve linux/arm64 hedeflerini derleyebilir, tek bir manifest altında birleştirip push edebilirsiniz.

Önkoşullar ve depo ayarları

- GitHub repository’nizde Actions etkin olmalı.
- Docker Hub’a push edecekseniz bir erişim token’ı oluşturun ve GitHub’da Settings > Secrets and variables > Actions altında DOCKERHUB_USERNAME ve DOCKERHUB_TOKEN olarak ekleyin.
- GHCR (GitHub Container Registry) kullanacaksanız, secrets.GITHUB_TOKEN çoğu durumda yeterlidir. Özel bir PAT kullanıyorsanız gerekli scope’lar: write:packages ve read:packages.

Workflow mantığı

Pipeline’da sırasıyla QEMU etkinleştirmesi (arm64 emülasyonu için), Buildx builder kurulumu, metadata/etiket üretimi, cache ayarı, çok mimarili build ve push adımları yer alacak. Ek olarak SBOM ve provenance (inşa kanıtı) bilgilerini de ekleyebiliriz.

Örnek workflow (/.github/workflows/release.yml)

name: release-multi-arch
on:
push:
tags:
- 'v*.*.*'
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/<kullanici>/<imaj-adi>
<kullanici>/<imaj-adi>
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push multi-arch
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: true
sbom: true

Önemli noktalar ve iyi uygulamalar

• QEMU: Yerel runner’ınız x86 ise, arm64 imajı için QEMU emülasyonu gerekir. docker/setup-qemu-action bunu sizin yerinize yapar. Performans, yerel ARM runner’a göre daha düşük olabilir; kritik projelerde self-hosted ARM runner düşünebilirsiniz.

• Metadata ve etiketleme: docker/metadata-action; semver uyumlu etiketleri (v1.2.3, 1.2, latest) otomatik üretir. Böylece kullanıcılarınız ister sürüm sabitlemesi, ister “latest” ile hızlı çekim yapabilir.

• Cache: GHA (GitHub Actions) cache’i ile katmanlar arası hız kazanırsınız. Dockerfile’ınızı cache verimini maksimize edecek şekilde düzenleyin: bağımlılık kurulumunu, sık değişen dosyalardan önce konumlandırmayın. Örneğin, package.json kopyası ve “npm ci” adımları, uygulama kodlarından önce gelmeli.

• Güvenlik: provenance: true ve sbom: true ile tedarik zinciri bilgilerini imaja iliştirebilirsiniz. Cosign ile imzalama eklemek isterseniz OIDC tabanlı keyless imzayı tercih edin; sigstore/cosign-installer ve “cosign sign” adımıyla workflow’u genişletebilirsiniz.

• Çok kayıtlı push: Yukarıdaki örnek aynı anda hem GHCR hem Docker Hub’a push eder. Kimlik bilgileri doğru ise manifest listesi, her iki registry’de de aynı etiketlerle yer alır.

Sorun giderme

• “no match for platform in manifest” hatası: Çekmeye çalıştığınız hedef platform için imaj manifest’i yoktur. buildx ile push sonrası, “docker buildx imagetools inspect <image:tag>” çıktısında amd64 ve arm64 görünmelidir.

• QEMU ile yavaş derleme: Bazı bağımlılıklar (ör. kriptografik kütüphaneler) arm64 derlemede ciddi süre alabilir. Mümkünse çok aşamalı (multi-stage) Dockerfile kullanın ve ağır kısımları önbelleğe alın. Alternatif olarak self-hosted arm64 runner veya BuildKit’in uzak builder modlarını düşünebilirsiniz.

• Önbellek isabeti düşükse: “cache-from: type=gha” etkin olmasına rağmen isabet zayıfsa, Dockerfile adımlarının sıralamasını gözden geçirin. “COPY . .” gibi geniş kapsamlı kopyalar, küçük değişikliklerde bile önbelleği bozabilir. Yalnızca gerekli dosyaları kopyalayın.

• Docker Hub hız limitleri: Anonim veya düşük planlı hesaplarda rate limit’e takılabilirsiniz. Login adımı şarttır. Gerekiyorsa workflow’u yeniden deneme stratejisiyle (retry) sarmalayın.

Performans ve maliyet ipuçları

• Katman sayısını azaltın, gereksiz paketleri temizleyin (apk/apt ile “--no-cache” ve “rm -rf /var/lib/apt/lists/*”).
• Dil ekosistemlerinde üretim odaklı taban imajları (distroless, alpine, slim) tercih edin.
• Çok aşamalı derlemede builder imajını üretim katmanından ayırın; sadece çalışma zamanı için gereken dosyaları kopyalayın.

Sonuç

GitHub Actions ve Docker Buildx ikilisi, tek bir pipeline üzerinden hem amd64 hem de arm64 imajlarını üreterek modern dağıtım ihtiyaçlarınıza güçlü bir yanıt sunar. Doğru önbellekleme, tutarlı etiketleme ve güvenlik metadatalarıyla (SBOM, provenance) birlikte kullanıldığında, CI/CD hattınız hızlı, izlenebilir ve güvenli çalışır. Bu rehberi temel alarak projenizi kolayca ölçeklendirebilir, bulut ve edge senaryolarında tek bir imaj adını kullanarak tüm platformlara rahatlıkla dağıtım yapabilirsiniz.

24 Eylül 2025 Çarşamba

Docker Buildx ile Çok Mimarili (amd64/arm64) Container İmajı Oluşturma Rehberi

Giriş

Apple Silicon (ARM64), Raspberry Pi ve buluttaki x86 sunucular gibi farklı mimarileri hedeflemek artık modern uygulamalar için kaçınılmaz. Tek bir imajın hem amd64 hem de arm64 için çalışması, dağıtım ve bakım yükünü azaltır. Bu rehberde, Docker Buildx kullanarak çok mimarili (multi-arch) container imajı oluşturmayı, kayıt depolarına (registry) göndermeyi ve doğrulamayı adım adım anlatıyorum. Ayrıca pratik ipuçları ve sık karşılaşılan sorunlara da değineceğim.

Önkoşullar

- Docker Desktop 4.x (macOS/Windows) veya Docker Engine 24+ (Linux). Çoğu sistemde Buildx ve QEMU desteği dahili gelir.
- Registry hesabı (Docker Hub veya GitHub Container Registry: ghcr.io).
- Terminal erişimi ve temel Docker komutlarına aşinalık.

Adım 1: Buildx builder oluşturun

Linux sunucularda QEMU emülasyonu gerekebilir. Gerekirse şu komutla kurun:
docker run --privileged --rm tonistiigi/binfmt --install all

Buildx builder oluşturun ve varsayılan olarak atayın:
docker buildx create --name multi --driver docker-container --use
Kurulumun aktif olduğunu doğrulayın:
docker buildx ls

Adım 2: Örnek Dockerfile (Node.js)

Aşağıdaki Dockerfile, hem amd64 hem de arm64 için derlenebilen basit bir Node.js uygulamasını paketler. Dikkat edilmesi gereken nokta, derleme aşamasında --platform=$BUILDPLATFORM kullanımıdır; bu, builder konteynerinin mimarisine uygun taban imajı çekerek tutarlı derleme sağlar.

# syntax=docker/dockerfile:1.6
ARG NODE_VERSION=20-alpine
FROM --platform=$BUILDPLATFORM node:${NODE_VERSION} AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN npm run build || echo "derlenecek bir şey yok"

FROM node:${NODE_VERSION}
WORKDIR /app
COPY --from=builder /app ./
EXPOSE 3000
CMD ["node", "server.js"]

Not: Base imaj olarak node:20-alpine çok mimarili manifest içerir. Uygulamanız Go, Rust veya Python ise benzer yaklaşımla çok mimari derleme yapabilirsiniz. Go için CGO_ENABLED=0 gibi bayraklarla statik build tercih edilebilir.

Adım 3: Çok mimarili build ve push

Önce kayıt deposuna giriş yapın:
docker login ghcr.io

Tek komutla her iki mimari için imaj üretip manifest list olarak push edin:
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t ghcr.io/kullanici/uygulama:1.0 \
-t ghcr.io/kullanici/uygulama:latest \
--push .

Build süresini kısaltmak için --provenance=false veya uzak cache kullanabilirsiniz:
--cache-to type=registry,ref=ghcr.io/kullanici/uygulama:cache,mode=max
--cache-from type=registry,ref=ghcr.io/kullanici/uygulama:cache

Doğrulama

Manifest’ı inceleyin ve mimarileri kontrol edin:
docker buildx imagetools inspect ghcr.io/kullanici/uygulama:latest

Çıktıda Platforms: linux/amd64, linux/arm64 görmelisiniz. Farklı cihazlarda docker run çalıştırdığınızda, Docker otomatik olarak uygun mimariye karşılık gelen imajı çekecektir.

Çalıştırma

Yerelde test etmek için:
docker run -p 3000:3000 ghcr.io/kullanici/uygulama:latest
Sunucu başlatıldıktan sonra http://localhost:3000 üzerinden uygulamayı doğrulayın.

Sık karşılaşılan sorunlar ve ipuçları

Manifest bulunamadı: “no matching manifest” hatası alıyorsanız, seçtiğiniz base imajın çok mimarili desteği olmayabilir. Debian/Alpine gibi resmi imajların çoğu multi-arch’tır; özel imajlar için alternatife geçin.

Illegal instruction: Özellikle kriptografik kütüphaneler kullanan Node/Go projelerinde CPU özelliği uyumsuzluğu görülebilir. Derleme sırasında hedef mimarinin özellikleriyle uyumlu bayraklar kullanın veya musl/glibc farklarını göz önünde bulundurun.

Performans yavaşlığı: QEMU emülasyonu altında yerel olmayan mimariyi derlemek yavaş olabilir. Mümkünse arm64 runner (ör. Graviton) veya amd64 runner kullanarak native build tercih edin.

Deterministik build: npm ci, package-lock.json ve versiyon sabitleme kullanın. Go için mod dosyalarını kilitleyin, Python için requirements.txt sabitleyin.

--platform ve --build-arg: Dockerfile içinde FROM --platform=$BUILDPLATFORM kullanın, ancak çalışma katmanını mimari bağımsız tutmaya özen gösterin. Yer yer TARGETPLATFORM ile koşullu bağımlılık kurabilirsiniz.

GitHub Actions ile otomasyon (kısa örnek)

name: Build and Push Multi-Arch
on: [push]
jobs:
build:
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:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ghcr.io/kullanici/uygulama:latest

Sonuç

Docker Buildx ile çok mimarili imaj üretmek, farklı cihaz ve bulut altyapılarında aynı etiketle sorunsuz dağıtım yapmanızı sağlar. Doğru base imaj seçimi, QEMU/runner stratejisi ve cache kullanımıyla süreç hem hızlı hem de tekrarlanabilir hale gelir. Bu rehberdeki adımları CI/CD hattınıza taşıyarak, amd64 ve arm64 dünyalarını tek bir manifest altında birleştirebilirsiniz.

15 Eylül 2025 Pazartesi

Docker Buildx ile Çok Mimarili İmaj Oluşturma ve GitHub Actions ile Otomatik Yayınlama (2025 Rehberi)

Giriş

Apple Silicon (arm64) makineler, Raspberry Pi gibi ARM tabanlı cihazlar ve geleneksel x86_64 sunucuların aynı anda hedeflenmesi artık modern projeler için kaçınılmaz. Çok mimarili (multi-arch) Docker imajları, tek bir etiket altında hem amd64 hem de arm64 varyantlarını barındırarak bu ihtiyacı şık biçimde çözer. Bu rehberde, Docker Buildx ile yerelde çok mimarili imaj üretmeyi ve GitHub Actions üzerinden Docker Hub’a otomatik yayınlamayı adım adım anlatıyorum. Hedefimiz: sürtünmesiz bir CI/CD hattı, hızlı önbellekleme ve güvenilir üretim dağıtımları.

Ön Gereksinimler

Yerel ortamda Docker Engine veya Docker Desktop’ın güncel bir sürümünü (tercihen 24+) kullanın. BuildKit artık varsayılan, ancak gerekirse DOCKER_BUILDKIT=1 ile etkinleştirildiğinden emin olun. Bir Docker Hub hesabı ve GitHub deposu hazırlayın. Reponuzda hassas bilgileri GitHub Secrets ile saklayacağız (DOCKERHUB_USERNAME, DOCKERHUB_TOKEN vb.).

Yerelde Buildx ile Çok Mimarili İmaj Oluşturma

Önce Buildx sürümünü kontrol edin: docker buildx version. Özel bir builder oluşturup devreye alın: docker buildx create --name multi --use. Ardından QEMU emülasyonunu etkinleştirin ki yerel mimariniz dışında da derleme yapabilesiniz: docker run --privileged --rm tonistiigi/binfmt --install all. Builder’ı hazırlayın: docker buildx inspect --bootstrap. Artık çok mimarili derleme komutu hazır: docker buildx build --platform linux/amd64,linux/arm64 -t KULLANICI/IMAJ:1.0 --push . Bu komut Docker Hub’a doğrudan push yapacağından, önce docker login ile oturum açmayı unutmayın.

Dockerfile İpuçları (Mimariden Bağımsız ve Hızlı)

Temel imaj seçimi kritik: Hem amd64 hem arm64 desteği olan resmi imajları tercih edin (ör. node:20-alpine, python:3.12-slim, golang:1.22-alpine). Çok aşamalı (multi-stage) Dockerfile kullanarak build bağımlılıklarını runtime’dan ayırın; bu boyutu küçültür ve güvenliği artırır. Mimariye özel binary indiriyorsanız TARGETARCH veya TARGETOS argümanlarını kullanın. Örnek: ARG TARGETARCH satırından sonra, curl -L https://example.com/bin-$TARGETARCH -o /usr/local/bin/app gibi bir strateji uygulayabilirsiniz. Node.js projelerinde native modüller (ör. Sharp) için build araçlarını sadece builder aşamasında yükleyip, final aşamada minimal tabana geçmek iyi bir pratik.

Örnek Build Komutu ve Hızlı Doğrulama

Yerel denemede aşağıdaki tek satır oldukça pratik çalışır: docker buildx build --platform linux/amd64,linux/arm64 -t KULLANICI/IMAJ:latest --push -f Dockerfile . Yayın sonrası manifesti doğrulamak için: docker buildx imagetools inspect KULLANICI/IMAJ:latest. Çıktıda iki platformu birden görmelisiniz. Ayrıca farklı makinelerde docker pull yaparak gerçek koşullarda test edin (ör. bir M2 Mac ve bir x86_64 bulut sunucusu).

GitHub Actions ile Otomatik Yayınlama (CI/CD)

Depo köküne .github/workflows/docker.yml oluşturun ve şu adımları içeren bir iş akışı kurgulayın: kaynak kodu checkout, QEMU kurulumu, Buildx kurulumu, Docker Hub’a giriş, imaj etiketlerini otomatik üreten metadata, çok mimarili build ve push. Özet akış şöyle olmalı: checkout → setup-qemu → setup-buildx → login → metadata → build-push.

Önerilen ana adımlar: actions/checkout@v4 ile kodu çekin. docker/setup-qemu-action@v3 QEMU’yu kurar. docker/setup-buildx-action@v3 Buildx’i etkinleştirir. docker/login-action@v3 ile Docker Hub’a giriş yapın (secrets kullanın). docker/metadata-action@v5 commit SHA, branch, semver tag’lerden akıllı etiketler üretir. docker/build-push-action@v6 ile platforms: linux/amd64,linux/arm64, push: true parametreleriyle build ve yayın yapın.

Önbellek (cache) çok önemlidir. docker/build-push-action içinde cache-from: type=gha ve cache-to: type=gha,mode=max kullanarak GitHub’ın yerleşik önbelleğini devreye alın. Bu, aynı bağımlılıkları tekrar tekrar derlemeyi önleyerek build süresini ciddi ölçüde azaltır.

Sık Karşılaşılan Sorunlar ve Çözümleri

1) QEMU kaynaklı derleme hataları: setup-qemu-action adımının çalıştığını ve en güncel binfmt’nin kurulduğunu doğrulayın. Gerekirse yerelde tonistiigi/binfmt konteyneriyle tazeleyin.

2) Temel imajda arm64 desteği yok: Kullanılan base image’ın manifestini kontrol edin veya alternatif bir resmi imaja geçin (-alpine sürümleri genellikle çok mimarili gelir).

3) Native modül derleme sorunları: Build aşamasında gerekli paketleri (ör. build-base, python3, libvips-dev) kurup final aşamada temizleyin. Node projelerinde npm ci --omit=dev ve npm rebuild --arch=$TARGETARCH gibi çözümler işe yarar.

4) Büyük imaj boyutu: Multi-stage yapı, --chown ile katman optimizasyonu, gereksiz dosyaları .dockerignore ile hariç tutma ve distroless/slim tabanlar boyutu ciddi şekilde düşürür.

Performans ve Güvenlik İpuçları

- CI’da cache’i etkin kullanın; bağımlılıkların hash’lenmesi ve doğru katmanlama build’i hızlandırır. - Tek bir manifest altında birden çok mimari barındırmak, çekme (pull) sırasında istemcinin doğru varyantı otomatik seçmesini sağlar; bu da kullanıcı deneyimini iyileştirir. - Minimum yetkili kullanıcı oluşturun (USER node gibi) ve kök kullanıcıyla çalışmaktan kaçının. - Sürüm etiketlerine özen gösterin: latest yanında 1.2.3, 1.2 gibi semantik etiketler yayınlamak geriye dönük uyumluluk ve geri dönüş kolaylığı sağlar.

Sonuç

Docker Buildx ve GitHub Actions kombinasyonu, çok mimarili imajları üretme ve dağıtma işini otomatikleştirerek geliştirme ekiplerine önemli hız kazandırır. Bu rehberdeki adımları izleyerek hem yerelde hem de CI ortamında linux/amd64 ve linux/arm64 için tek komutta güvenilir, hızlı ve ölçeklenebilir bir yayın akışı kurabilirsiniz. Doğru taban imajı, akıllı önbellek, temiz Dockerfile ve iyi etiket yönetimiyle, 2025’te çok mimarili dağıtım stratejinizi gönül rahatlığıyla standart hale getirebilirsiniz.

7 Eylül 2025 Pazar

Docker Buildx ile Çok Mimarili İmaj Oluşturma ve GitHub Actions ile Otomatik Yayınlama (2025 Rehberi)

Giriş

Apple Silicon (ARM64), Raspberry Pi gibi cihazlarla birlikte “aynı imajı farklı mimarilerde çalıştırma” ihtiyacı günlük hayatın bir parçası oldu. Docker Buildx, tek bir komutla linux/amd64 ve linux/arm64 için çok mimarili (multi-arch) imajlar üretmenizi sağlıyor. Bu rehberde, yerelde Buildx ile derleme, doğru Dockerfile pratikleri, imajı Docker Hub’a itme ve son olarak GitHub Actions ile otomatik yayımlamayı adım adım anlatıyorum.

Önkoşullar

- Docker 24+ veya Docker Desktop (BuildKit varsayılan açık olmalı)
- Docker Hub veya GHCR hesabı (örneklerde Docker Hub kullanacağım)
- GitHub deposu (Actions için)

Buildx Kurulumu ve Kontrolü

Güncel Docker Desktop, buildx ve QEMU emülasyonu ile birlikte gelir. Terminalde aşağıdaki komutlarla Buildx’in aktif olduğunu kontrol edin:

docker buildx version
docker buildx ls

Gerekirse yeni bir builder oluşturabilirsiniz:

docker buildx create --name multiarch --use
docker buildx inspect --bootstrap

“qemu not registered” gibi bir hata alırsanız, Docker Desktop’ı güncelleyin veya Linux için QEMU’yu kurun. Çoğu yeni kurulumda ekstra adım gerekmeyecektir.

Örnek Dockerfile (Go ile statik ikili)

Dil bağımsız olarak çalışabilirsiniz; ancak Go ile statik ikili üretmek multi-arch derlemelerde idealdir. Minimal ve güvenli bir imaj için distroless veya scratch tabanını tercih edin.

# Dockerfile
# 1) Build aşaması
FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# CGO kapalı, statik derleme
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$(go env GOARCH) go build -ldflags="-s -w" -o app ./cmd/server

# 2) Minimal çalışma aşaması
FROM gcr.io/distroless/static:nonroot
WORKDIR /app
COPY --from=builder /src/app /app/app
USER nonroot:nonroot
EXPOSE 8080
ENTRYPOINT ["/app/app"]

Not: Go projesinde “./cmd/server” yolu örnektir. Projenize göre düzenleyin. Go dışındaki dillerde (Node.js, Python) multi-stage ve mimariye uygun resmi taban imajları kullanın. .dockerignore dosyasıyla gereksiz dosyaları dışarıda bırakmayı unutmayın.

Yerelde Çok Mimarili İmaj Derleme ve İtme

Önce Docker Hub’a giriş yapın:

docker login

Ardından Buildx ile iki mimariye birden derleyip tek bir çoklu manifest altında toplayın ve push edin:

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t KULLANICI_ADI/uygulama:1.0.0 \
  -t KULLANICI_ADI/uygulama:latest \
  --provenance=true --sbom=true \
  --push .

Manifest’i doğrulamak için:

docker buildx imagetools inspect KULLANICI_ADI/uygulama:latest

GitHub Actions ile Otomatik Yayınlama

Her push veya tag ile otomatik imaj üretmek için .github/workflows/docker.yml adında bir iş akışı oluşturun. Aşağıdaki örnek, semantik sürüm etiketlerini otomatik algılar ve iki mimariye birden push eder. Docker Hub kullanıcı adı ve erişim token’ınızı repo Secrets kısmında DOCKERHUB_USERNAME ve DOCKERHUB_TOKEN olarak saklayın.

name: Docker Multi-Arch

on:
  push:
    branches: [ "main" ]
    tags: [ "v*" ]

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
      id-token: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Docker metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: |
            ${{ secrets.DOCKERHUB_USERNAME }}/uygulama
          tags: |
            type=ref,event=branch
            type=ref,event=tag
            type=sha

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
          provenance: true
          sbom: true

Bu akışta setup-qemu-action emülasyon için, build-push-action ise derleme ve push için kullanılır. metadata-action, tag yönetimini kolaylaştırır; main branch için “latest” benzeri etiketler ve tag push için semantik sürümler üretir.

OCI Etiketleri, Güvenlik ve İpuçları

- OCI etiketleri (org.opencontainers.image.*) ile kaynak kod, lisans ve açıklama bilgilerini ekleyin. metadata-action bunu otomatik sağlar.
- sbom: true ve provenance: true ile tedarik zinciri görünürlüğünü artırın.
- .dockerignore ile node_modules, build çıktıları, test verileri gibi gereksiz klasörleri dışarıda tutun; imaj boyutu ve gizlilik açısından önemlidir.
- Çok aşamalı (multi-stage) Dockerfile ile sadece gereken dosyaları çalışma imajına kopyalayın.
- Bazı dil ekosistemlerinde mimariye özgü bağımlılıklar olabilir. Özellikle Python’da native modüller içeren paketlerde uygun taban imajını ve derleme araçlarını kullanın.

Yaygın Hatalar ve Çözümleri

- Hata: “no match for platform in manifest” — Kullandığınız baz imaj ilgili mimariyi desteklemiyor. Aynı imajın çok mimarili varyantını (ör. alpine, debian-slim) tercih edin.
- Hata: “exec format error” — Yanlış mimari için derlenmiş ikiliyi çalıştırıyorsunuz. Multi-stage içinde hedef GOARCH/GOOS (veya eşdeğerleri) doğru ayarlanmalı.
- Hata: “qemu not registered” — QEMU emülasyonu kurulu değil. GitHub Actions’ta setup-qemu-action kullanın; yerelde Docker Desktop güncel olsun.
- Hata: “denied: requested access to the resource is denied” — Registry girişiniz veya tag adı hatalı. docker login ve depo adını doğrulayın.

Sonuç

Buildx sayesinde tek bir komutla amd64 ve arm64 için üretim yapabilir, tek bir etiket altında birleştirip dağıtabilirsiniz. GitHub Actions ile bunu CI/CD’ye bağladığınızda yeni sürümleriniz saniyeler içinde Docker Hub’a düşer. Doğru baz imaj, temiz Dockerfile ve önbellekleme stratejileri ile hem derleme sürenizi hem de imaj boyutlarınızı önemli ölçüde iyileştirebilirsiniz.