7 Aralık 2025 Pazar

Kubernetes’te Horizontal Pod Autoscaler (HPA) ile Otomatik Ölçeklendirme: Adım Adım Kurulum ve İpuçları

Giriş

Kubernetes üzerinde çalışan uygulamalarınızın trafiğe göre otomatik ölçeklenmesi, maliyet ve performans dengesini korumak için kritik öneme sahiptir. Horizontal Pod Autoscaler (HPA), pod sayısını metriklere göre dinamik olarak artırıp azaltarak bu dengeyi sağlar. Bu rehberde, Kubernetes’te HPA’yı adım adım nasıl kuracağınızı, doğru metrikleri nasıl seçeceğinizi ve üretim ortamlarında dikkat edilmesi gereken noktaları paylaşacağım.

Neden HPA?

HPA, belirli bir hedefe (örneğin CPU kullanımının %70’te kalması) göre pod sayısını yatayda (horizontal) değiştirir. Ani trafik artışlarında hızlıca ölçeklenmek, düşük trafik saatlerinde ise maliyeti kısmak için idealdir. Üstelik Kubernetes 1.26+ sürümlerinde autoscaling/v2 API’si ile birden fazla metriği aynı anda değerlendirerek daha akıllı kararlar verebilir.

Önkoşullar

HPA’nın doğru çalışması için kümenizde bazı bileşenlerin hazır olması gerekir. En kritik bağımlılık metrics-server’dır. Bu bileşen, CPU ve bellek gibi kaynak metriklerini Kubernetes API üzerinden ulaşılabilir kılar.

Ayrıca Deployment’ınızdaki container’ların resource requests/limits alanlarının tanımlı olması gerekir. Aksi hâlde HPA CPU/Bellek bazlı hedefleri doğru hesaplayamaz.

Metrics Server Kurulumu (Örnek)

Çoğu yönetilen Kubernetes hizmeti (GKE, AKS, EKS) metrics-server’ı hazır getirir. Kendi kümenizde kurmanız gerekiyorsa, resmi manifest veya Helm chart kullanabilirsiniz.

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl get apiservices | grep metrics
kubectl top nodes
kubectl top pods -A

Yukarıdaki komutlar hatasız çalışıyorsa, metrik akışı sağlanmıştır ve HPA için hazırsınız.

Örnek Uygulama ve HPA Tanımı

Aşağıdaki örnekte CPU hedefi %70 olan bir HPA tanımı bulunuyor. API sürümü olarak autoscaling/v2 kullanıyoruz. Bu sürüm, ölçeklendirme davranışını (behavior) detaylı kontrol etmeye izin verir.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-api-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-api
  minReplicas: 2
  maxReplicas: 15
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
        - type: Percent
          value: 100
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 20
          periodSeconds: 60
      selectPolicy: Min

Bu yapılandırma, ihtiyaç durumunda pod sayısını hızlı artırırken (burst trafiği yakalama), azaltma işlemlerinde daha konservatif davranır (ani düşüşlerde dalgalanmayı engelleme).

Gelişmiş Metrikler: CPU, Bellek, Özel ve Harici

HPA, birden fazla metrikle çalışabilir ve ölçeklendirme kararını en baskın sinyale göre verir:

CPU/Bellek (Resource): averageUtilization ile yüzdesel hedefler verilir. CPU için genellikle %60–70, bellek için uygulama karakteristiğine göre %60–80 yaygındır.

Object/Pods: Uygulama seviyesinde RPS (request per second) gibi metrikleri pod başına normalize ederek ölçeklenebilir. Örneğin Nginx Ingress üzerinden istek sayısı.

External: Prometheus Adapter gibi bir adaptörle gecikme süresi, kuyruk uzunluğu, Kafka lag gibi harici metriklere göre ölçeklendirme yapılabilir.

Test: Yük Üreterek Doğrulama

HPA’nın doğru tepki verip vermediğini anlamak için kısa süreli bir yük testi yapabilirsiniz. Örneğin hey veya k6 ile endpoint’lerinize istek gönderebilir, ardından aşağıdaki komutla HPA durumunu izleyebilirsiniz:

kubectl describe hpa web-api-hpa
kubectl get hpa
kubectl top pods -n default

Çıkışta “Current” ve “Target” metrikleri ile “Desired Replicas” alanının beklenen şekilde değiştiğini gözlemlemelisiniz.

En İyi Pratikler

1) Doğru resource requests/limits: “request” değerlerini gerçekçi belirleyin. Çok düşük değerler HPA’yı gereğinden fazla tetikler; çok yüksek değerler ise ölçeklenmeyi geciktirir.

2) Stabilizasyon pencereleri: behavior.scaleDown altında 300–600 saniye aralığı çoğu web uygulaması için uygundur. Bu, titremeyi (flapping) azaltır.

3) Çoklu metrik kullanın: CPU’ya ek olarak RPS veya kuyruk uzunluğu gibi iş metrikleri eklemek daha doğru ölçeklendirme sağlar. Baskın metrik prensibini unutmayın: en yüksek gereksinimi işaret eden metrik kazanır.

4) Soğuk başlangıç sürelerini hesaba katın: Container başlatma süresi uzunsa scaleUp politikalarını daha agresif yapın; ör. Percent 100 veya Pods 4 gibi.

5) Pod Disruption Budget (PDB) ve Readiness: HPA ile birlikte PDB ve readinessProbe ayarlarını gözden geçirerek ölçeklenme ve dağıtım sırasında kesinti riskini azaltın.

6) VPA ve HPA birlikte kullanım: HPA yatay, VPA dikey ölçekleme yapar. Aynı kaynağı aynı anda hedeflememek için VPA’yı “recommendation” modunda çalıştırmayı değerlendirin.

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

Hata: HPA metrik okuyamıyor. Çözüm: metrics-server’ın sağlıklı çalıştığını doğrulayın; API erişim hatalarını ve TLS ayarlarını kontrol edin.

Hata: Pod sayısı artmıyor. Çözüm: Deployment’ın replicas alanı başka bir kontrolcü tarafından sabitlenmiş olabilir. Ayrıca node kapasitesi yetersizse Cluster Autoscaler gerekebilir.

Hata: Ölçeklendirme çok agresif veya çok yavaş. Çözüm: behavior.policies ve stabilizationWindowSeconds değerlerini gözden geçirin; metrik hedeflerini (averageUtilization) gerçek yük profiline göre ayarlayın.

Sonuç

Doğru yapılandırılmış bir HPA, Kubernetes ortamınızda esneklik ve maliyet verimliliği sağlar. Metrics-server, isabetli resource ayarları ve davranış politikaları ile desteklendiğinde, yük dalgalanmalarına hızla uyum sağlayan, istikrarlı ve performanslı bir mimari kurabilirsiniz. Üretime geçmeden önce küçük bir yük testiyle ayarları doğrulamak, canlıya çıktıktan sonra ise metrikleri izleyip ince ayar yapmak en sağlıklı yaklaşımdır.

6 Aralık 2025 Cumartesi

WebGPU ile Tarayıcıda Gerçek Zamanlı Makine Öğrenmesi: TensorFlow.js ile Adım Adım

WebGPU neden önemli?

Tarayıcıda makine öğrenmesi denildiğinde yıllardır WebGL ve WebAssembly (WASM) üzerinden çalışan çözümler öne çıkıyordu. Ancak bu yaklaşımlar, genel amaçlı hesaplama tarafında ciddi kısıtlar içeriyordu. WebGPU, modern grafik API’lerinin (Vulkan/Metal/Direct3D 12) üzerine inşa edilmiş, düşük gecikmeli ve yüksek verimli bir standarda dayanır. Bu sayede tensör işlemleri, matris çarpımları ve konvolüsyon gibi ML çekirdekleri doğrudan GPU üzerinde, daha az ara kopya ve daha iyi paralellik ile çalışır. Kısacası WebGPU, tarayıcıda gerçek zamanlı çıkarım (inference) yapmayı pratik hale getirir ve mobil dahil geniş bir cihaz yelpazesinde daha istikrarlı performans sağlar.

Tarayıcı desteği ve gereksinimler

WebGPU bugün Chrome 113+ ve Edge 113+ sürümlerinde varsayılan olarak kullanılabilir. Safari tarafında macOS ve iOS’in yeni sürümlerinde destek giderek olgunlaşıyor; Firefox içinse Nightly üzerinde bayrak ile etkinleştirme gerekebiliyor. Projenizi yayına almayı düşünüyorsanız, özellik tespiti (feature detection) yaparak WebGPU desteklenmiyorsa WASM veya WebGL’e otomatik düşüş sağlamanız kritik. Kullanıcı tarafında ekstra bir eklenti gerekmiyor; tek koşul güncel bir tarayıcı ve yeterli GPU/driver desteği.

TensorFlow.js ile WebGPU backend’i etkinleştirme

TensorFlow.js, WebGPU için resmi bir backend sunuyor. Uygulama başlangıcında WebGPU özelliğini tespit edip uygun backend’i seçmeniz en sağlıklı yaklaşım. Genel akış şudur: WebGPU destekleniyorsa TF.js’i webgpu backend ile başlatın, aksi durumda wasm veya webgl’e geri dönün. Başlangıçta bir “ısınma” (warm-up) adımı uygulamak da önemlidir; bir sahte giriş (dummy input) ile modeli bir kez çalıştırarak shader derlemelerinin tamamlanmasına izin verirsiniz. Bu sayede ilk gerçek tahmin sırasında yaşanabilecek ani gecikme önemli ölçüde azalır.

Model seçimi: boyut, hassasiyet ve gecikme dengesi

Gerçek zamanlı çıkarım hedefliyorsanız model seçimi kadar nicemleme (quantization) stratejisi de önemlidir. MobilNet tabanlı sınıflandırıcılar, BlazeFace veya MediaPipe tabanlı hafif yüz/eldeneyim modelleri ve COCO-SSD gibi optimize edilmiş nesne tespit ağları tarayıcı için uygundur. FP16 veya INT8 nicemleme ile model boyutu azalırken bellek kullanımınız düşer ve GPU bant genişliği tasarrufu sağlanır. Ancak nicemleme ile birlikte doğruluk payında ufak düşüşler olabilir; hedef senaryonuza göre tatlı noktayı bulmak için A/B testleri yapın.

Veri yolu ve gecikme: Kamera, Canvas ve sıfır kopya stratejileri

Gerçek zamanlı senaryolarda darboğaz genellikle GPU hesaplama gücünden ziyade veri aktarımıdır. Kamera akışını almak için getUserMedia kullanıyor, görüntüyü bir canvas’a çiziyor ve ardından tensöre dönüştürüyorsanız, gereksiz kopyalardan kaçınmalısınız. Modern tarayıcılarda OffscreenCanvas ve WebCodecs ile birlikte “zero-copy”a yakın akışlar kurulabiliyor; ancak API’ler platforma göre farklı olgunlukta. Her adımda gereksiz yeniden boyutlandırma ve renk uzayı dönüşümlerinden kaçınmak, çerçeve başına gecikmeyi düşürür. Ayrıca requestAnimationFrame ile çıkarımı ekran yenileme döngüsüne bağlamak yerine, sabit bir çıkarım frekansı belirleyip sonuçları görsel katmana asenkron taşımak çoğu zaman daha kararlı FPS verir.

Performans ipuçları

- Tek seferlik tensör tahsisleri yapın, tekrar kullanılan tensörleri yeniden yaratmak yerine cache’leyin. Bu yaklaşım hem GC baskısını hem de GPU bellek fragmentasyonunu azaltır.

- Batched çıkarım (ör. birden fazla çerçeveyi tek seferde işlemek) her zaman yararlı olmayabilir; gecikme duyarlı uygulamalarda mikro-batch yerine tekil çerçeve akışı daha iyi tepki süresi verir.

- Modeli hedef cihaza göre değiştirmek için koşullu yükleme yapın. Masaüstünde daha büyük bir model, mobilde hafif bir varyant seçmek kullanıcı deneyimini dengeler.

- WebGPU sürücülerindeki farklılıklardan etkilenmemek için düzenli olarak Chrome, Edge ve Safari üzerinde duman testleri (smoke test) koşturun.

Hata ayıklama ve ölçüm

Performansı yönetemediğiniz şeyi optimize edemezsiniz. Tarayıcının Performance paneli ile kare zaman çizelgesini (timeline) inceleyerek GPU tarafında beklenmedik duraklamaları tespit edin. TensorFlow.js, çıkarım sırasında bellek kullanımını ve kernel sürelerini profil etmeye yardımcı olacak yardımcı işlevler sunar; bu sayede hangi adımın darboğaz olduğunu netleştirirsiniz. Ayrıca FPS, gecikme (p95/p99) ve tahmin doğruluğunu aynı anda izleyebileceğiniz hafif bir telemetri katmanı kurmak, üretimde sorunları hızla yakalamanıza yardım eder.

Uyumluluk ve erişilebilirlik

Bazı kurumsal cihazlarda GPU erişimi kısıtlı olabilir veya kullanıcılar enerji tasarrufu modunda çalışıyor olabilir. Uygulamada “Gelişmiş hızlandırmayı aç/kapat” seçeneği sunarak WebGPU’yu kullanıcı tercihine bırakın. Erişilebilirlik açısından, çıkarım sonuçlarını yalnızca görsel olarak göstermek yerine metin çıktısı ve ARIA canlı bölgeleri üzerinden ekran okuyuculara iletmek, ML özelliklerini daha geniş kullanıcı kitlesine ulaştırır.

Güvenlik ve gizlilik

WebGPU, sitenin izni olmadan cihaz verilerine erişim sağlamaz; ancak yine de uzun süreli yoğun GPU kullanımı pil tüketimini artırabilir ve cihaz sıcaklığını yükseltebilir. Gerçek zamanlı uygulamalarda etkinlik algılama (ör. sekme arka plana geçince frekansı düşürme) ve otomatik duraklatma mekanizmaları ekleyin. Gizlilik açısından, modeli istemci tarafında çalıştırmak veriyi sunucuya göndermeden işleme imkânı sunduğu için hassas senaryolarda güçlü bir artıdır.

Sonuç

WebGPU, tarayıcıda makine öğrenmesini hobi projesi seviyesinden üretim kalitesine taşıyan bir dönüm noktası. TensorFlow.js ile birleştiğinde, kamera tabanlı gerçek zamanlı analitikten etkileşimli multimedya deneyimlerine kadar geniş bir yelpazede düşük gecikme ve yüksek kare hızına ulaşmak artık mümkün. Doğru model seçimi, dengeli nicemleme, dikkatli veri yolu tasarımı ve kapsamlı profil ile bugün dahi pek çok cihazda akıcı bir kullanıcı deneyimi sunabilirsiniz. WebGPU desteklenmeyen ortamlara zarifçe düşüş sağlamayı da unutmayın; böylece tüm kullanıcılar için çalışır bir çözüm elde edersiniz.

5 Aralık 2025 Cuma

WebGPU ile Tarayıcıda Makine Öğrenimi: ONNX Runtime Web ile Görsel Sınıflandırma (Adım Adım)

Giriş

WebGPU, modern tarayıcılarda GPU gücünden standart ve güvenli bir şekilde yararlanmayı sağlayan yeni bir web standardı. Bu yazıda, ONNX Runtime Web ve WebGPU kullanarak tarayıcı içinde tamamen istemci tarafında çalışan bir görsel sınıflandırma uygulamasını adım adım kuracağız. Sunucuya veri göndermeden, gizliliğe saygılı ve düşük gecikmeli bir makine öğrenimi deneyimi elde edeceğiz. Bu yaklaşım, SEO açısından da kıymetli; zira “tarayıcıda makine öğrenimi”, “WebGPU”, “ONNX Runtime Web”, “görsel sınıflandırma” gibi anahtar kelimelerle teknik kitlelere doğrudan hitap ediyor.

Ön Koşullar

- Güncel bir tarayıcı: Chrome 113+ sürümlerinde WebGPU masaüstünde varsayılan olarak açıktır. Safari’de ve Firefox’ta destek durumu değişebilir; deneysel bayraklar gerekebilir. Mobilde destek kısmi durumdadır.

- Node.js 18+ (geliştirme sunucusu ve paket yönetimi için)

- Temel HTML/JS bilgisi

Proje Kurulumu

1) Vite ile boş bir proje oluşturun:

npm create vite@latest webgpu-ml -- --template vanilla
cd webgpu-ml
npm install

2) ONNX Runtime Web paketini ekleyin:

npm i onnxruntime-web

3) Basit bir dosya yapısı hazırlayın: index.html, main.js ve bir models/ klasörü. Örnek olarak mobilenetv2.onnx gibi 224x224 giriş alan bir sınıflandırma modelini models/ altına yerleştirin. ONNX model arşivlerinden (örn. ResNet, MobileNet) hafif bir model tercih edin.

index.html İskeleti

Aşağıdaki minimal HTML, bir görsel yükleme alanı ve sonuçları göstermek için basit bir arayüz içerir.

<!doctype html>
<html lang="tr">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>WebGPU ile Görsel Sınıflandırma</title>
  </head>
  <body>
    <h1>WebGPU + ONNX Runtime Web</h1>
    <input type="file" id="file" accept="image/*" />
    <button id="predict">Sınıflandır</button>
    <div id="status">Hazır</div>
    <div id="result"></div>
    <canvas id="canvas" width="224" height="224" style="display:none"></canvas>
    <script type="module" src="/main.js"></script>
  </body>
</html>

WebGPU ve ONNX Runtime Web ile Çalıştırma

Aşağıdaki kodda, tarayıcıda WebGPU desteği kontrol edilir, ONNX modeli yüklenir, görsel 224x224 boyutuna ölçeklenir ve ImageNet ortalama/standart sapma değerleri ile normalize edilerek tensöre dönüştürülür. Ardından model çıkarımı yapılır ve en yüksek olasılıklı sınıf ekrana yazdırılır.

// main.js
import * as ort from 'onnxruntime-web/webgpu';

const statusEl = document.getElementById('status');
const resultEl = document.getElementById('result');
const fileInput = document.getElementById('file');
const predictBtn = document.getElementById('predict');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

let session;

// WebGPU desteğini kontrol edin
if (!('gpu' in navigator)) {
  statusEl.textContent = 'WebGPU desteklenmiyor. Varsayılan WASM ile deneyin.';
}

// Modeli başlat
async function initModel() {
  statusEl.textContent = 'Model yükleniyor...';
  // Fallback ile: önce WebGPU, olmazsa WASM
  session = await ort.InferenceSession.create('/models/mobilenetv2.onnx', {
    executionProviders: ['webgpu', 'wasm']
  });
  statusEl.textContent = 'Model yüklendi.';
}

function imageToTensor(img) {
  const size = 224;
  ctx.clearRect(0, 0, size, size);
  // Görseli 224x224'e çiz
  ctx.drawImage(img, 0, 0, size, size);
  const { data } = ctx.getImageData(0, 0, size, size);

  // NHWC(RGBA) -> NCHW, normalize [0,1], ImageNet mean/std
  const mean = [0.485, 0.456, 0.406];
  const std = [0.229, 0.224, 0.225];

  const input = new Float32Array(1 * 3 * size * size);
  let idx = 0;
  for (let y = 0; y < size; y++) {
    for (let x = 0; x < size; x++) {
      const i = (y * size + x) * 4;
      const r = data[i] / 255;
      const g = data[i + 1] / 255;
      const b = data[i + 2] / 255;
      // Kanal sırası: [R plane][G plane][B plane]
      input[0 * size * size + idx] = (r - mean[0]) / std[0];
      input[1 * size * size + idx] = (g - mean[1]) / std[1];
      input[2 * size * size + idx] = (b - mean[2]) / std[2];
      idx++;
    }
  }
  return new ort.Tensor('float32', input, [1, 3, size, size]);
}

function softmax(arr) {
  const max = Math.max(...arr);
  const exps = arr.map(v => Math.exp(v - max));
  const sum = exps.reduce((a, b) => a + b, 0);
  return exps.map(v => v / sum);
}

async function runInference(img) {
  if (!session) await initModel();

  statusEl.textContent = 'Çıkarım yapılıyor...';
  const tensor = imageToTensor(img);

  const inputName = session.inputNames[0];
  const output = await session.run({ [inputName]: tensor });

  const outputName = session.outputNames[0];
  const logits = Array.from(output[outputName].data);
  const probs = softmax(logits);

  // En yüksek olasılıklı sınıfı bul
  let bestIdx = 0;
  for (let i = 1; i < probs.length; i++) {
    if (probs[i] > probs[bestIdx]) bestIdx = i;
  }

  // Label dosyanız varsa fetch edip eşleyebilirsiniz (örn. imagenet-labels.txt)
  resultEl.textContent = `Tahmin sınıf index: ${bestIdx}, olasılık: ${(probs[bestIdx] * 100).toFixed(2)}%`;
  statusEl.textContent = 'Bitti';
}

// Görsel seç ve çıkarım başlat
predictBtn.addEventListener('click', async () => {
  const file = fileInput.files?.[0];
  if (!file) {
    alert('Lütfen bir görsel seçin.');
    return;
  }
  const img = new Image();
  img.onload = () => runInference(img);
  img.src = URL.createObjectURL(file);
});

// Sayfa yüklenince modeli hazırlayın (isteğe bağlı)
initModel().catch(err => {
  console.error(err);
  statusEl.textContent = 'Model yüklenirken hata oluştu.';
});

Performans İpuçları

- WebGPU genellikle WASM/WASM SIMD’e göre daha yüksek paralellik ve throughput sunar. Ancak küçük modellerde fark az olabilir. Model boyutu ve katman türleri sonucu etkiler.

- Modeli mümkün olduğunca küçük seçin (MobileNet, EfficientNet-Lite gibi). Büyük modeller hem ağdan indirmede hem de bellek kullanımında sorun çıkarabilir.

- İlk çıkarım (warm-up) genellikle daha yavaştır. Gerçek kullanıcı deneyimi için ikinci/üçüncü çıkarımı da ölçün.

- Vite yerine üretime alırken kodu küçültün ve model dosyasını CDN veya HTTP/2 ile hızlı sunun. Cache-Control başlıklarını doğru ayarlayın.

Sorun Giderme

- “WebGPU desteklenmiyor”: Tarayıcınızı güncelleyin veya chrome://flags içinde WebGPU ile ilgili bayrakları kontrol edin. Kurumsal politikalar GPU erişimini kısıtlayabilir.

- “Model giriş/çıkış adı uyuşmuyor” hatası: session.inputNames ve session.outputNames üzerinden gerçek isimleri alın, manuel isim yazmayın.

- Görselin renkleri veya sonuçlar beklenenden farklıysa, normalize adımlarını (mean/std) ve kanal sırasını (NCHW vs NHWC) model dokümantasyonuna göre doğrulayın.

- Bazı platformlarda WebGPU var ama belirli doku formatları kısıtlı olabilir. Fallback olarak WASM sağlayıcısını eklediğinizden emin olun.

Sonuç

WebGPU ve ONNX Runtime Web ile tarayıcıda makine öğrenimi artık gerçek bir seçenek. İstemci tarafında görsel sınıflandırma gibi görevlerde gizlilik, düşük gecikme ve çevrimdışı çalışma avantajları sunar. Bu rehberle temel bir iskelet kurdunuz; bundan sonra model çeşitliliğini artırabilir, etiket dosyaları ile daha anlaşılır sonuçlar gösterebilir, hatta Web Workers kullanarak arayüzü bloklamadan çoklu çıkarım senaryolarını deneyebilirsiniz. Kısacası, WebGPU sayesinde modern web uygulamaları, yapay zeka kabiliyetlerini kullanıcıya en yakın yerde, doğrudan tarayıcıda sunabiliyor.

4 Aralık 2025 Perşembe

WebGPU ile Tarayıcıda Yapay Zeka Çalıştırma: ONNX Runtime Web ve Transformers.js ile Adım Adım Rehber

Tarayıcıda yapay zeka modelleri çalıştırmak, son iki yılda WebGPU’nun olgunlaşmasıyla pratik hale geldi. WebGL ve saf WebAssembly çözümleri artık yerini daha modern, düşük seviye ve yüksek performanslı WebGPU’ya bırakıyor. Bu rehber, WebGPU destekli ONNX Runtime Web ve Transformers.js kullanarak istemci tarafında model çalıştırmayı adım adım anlatır; kurulum, performans ipuçları, geriye uyumluluk ve sorun giderme başlıklarını içerir.

WebGPU neden önemli?

WebGPU, GPU’ya daha doğrudan erişim sağlar, bellek kopyalamayı azaltır ve paralel işlemleri daha verimli yürütür. Görüntü sınıflandırma, metin gömme (embedding), duygu analizi, hatta küçük dil modelleri gibi görevlerde CPU’ya kıyasla ciddi hızlanma sağlayabilirsiniz. Üstelik tüm bunlar, veriyi sunucuya göndermeden, gizliliği koruyarak gerçekleşir.

Önkoşullar ve tarayıcı desteği

Güncel Chrome/Edge (121+), Safari 17+ (veya Technology Preview) ve Firefox Nightly, değişen derecelerde WebGPU desteği sunar. Chrome’da sorun yaşarsanız chrome://flags altında “Unsafe WebGPU” seçeneğini kontrol edin. Kurumsal cihazlarda kısıtlamalar olabilir. Destek yoksa ONNX Runtime Web’in WASM sağlayıcısına otomatik geçiş yapabilirsiniz.

Proje kurulumu (Vite + NPM)

Hızlı başlamak için Vite ile bir ön yüz projesi kurabilir ve hem düşük seviyeli API (onnxruntime-web) hem de yüksek seviyeli bir sarmalayıcı (Transformers.js) ekleyebilirsiniz. Aşağıdaki komutlar, örnek bir React projesi içindir; framework bağımlı değilsiniz, vanilla JS ile de kullanabilirsiniz.

# Proje oluşturma
npm create vite@latest webgpu-ai -- --template react
cd webgpu-ai

# Bağımlılıklar
npm i onnxruntime-web @xenova/transformers

# Geliştirme sunucusu
npm run dev

ONNX Runtime Web ile WebGPU’da model çalıştırma

ONNX Runtime Web (ORT Web), aynı API ile birden fazla yürütme sağlayıcısını (WebGPU, WebGL, WASM) destekler. Aşağıda WebGPU var ise onu, yoksa WASM’i kullanacak minimal bir örnek yer alıyor. Burada mobilenet gibi hafif bir görüntü sınıflandırma modeli varsayılmıştır.

import * as ort from 'onnxruntime-web';

async function loadSession() {
  const hasWebGPU = typeof navigator !== 'undefined' && !!navigator.gpu;

  const session = await ort.InferenceSession.create('/models/mobilenetv2.onnx', {
    executionProviders: hasWebGPU ? ['webgpu'] : ['wasm'],
    graphOptimizationLevel: 'all'
  });

  return session;
}

async function run(session, inputTensor) {
  const [inputName] = session.inputNames;
  const [outputName] = session.outputNames;
  const feeds = { [inputName]: inputTensor };

  const results = await session.run(feeds);
  const output = results[outputName]; // ort.Tensor
  return output;
}

// Basit ön işleme (örnek): 224x224, [1,3,224,224], normalize edilmiş Float32Array
// Gerçek uygulamada resmi canvas ile yeniden boyutlandırıp kanalları CHW formatına çevirin.

Modelin giriş/çıkış adları modellere göre değişir; yukarıdaki gibi session.inputNames ve session.outputNames kullanmak en güvenli yoldur. Performans için FP16’ye dönüştürülmüş modeller ve 224x224 gibi küçük giriş boyutları tercih edin. Ayrıca tek seferde birden fazla örnek (batch) işletecekseniz tarayıcı GPU belleği sınırlamalarını aklınızda tutun.

Transformers.js ile “yüksek seviyeli” kullanım

@xenova/transformers, tarayıcıda hazır NLP ve bazı görsel modelleri kolayca çalıştırmanızı sağlar. Arkada ONNX Runtime Web ve uygun olduğunda WebGPU kullanır. Aşağıdaki örnek duygu analizi içindir:

import { pipeline } from '@xenova/transformers';

async function runSentiment() {
  const hasWebGPU = typeof navigator !== 'undefined' && !!navigator.gpu;
  const device = hasWebGPU ? 'webgpu' : 'cpu'; // 'cpu' = WASM

  const pipe = await pipeline(
    'text-classification',
    'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
    { device }
  );

  const out = await pipe('Bu film şaşırtıcı derecede iyiydi!');
  console.log(out);
}

Transformers.js, ilk çalıştırmada modeli indirip tarayıcı önbelleğine alır. Üretim ortamında model dosyalarını kendi CDN’inizden sunmak ve sürümleri sabitlemek iyi bir pratiktir. Bazı modeller büyük olduğundan, başlangıç gecikmesini azaltmak için “tiny” veya “base” sürümleri tercih edin.

Performans ipuçları

1) Doğru veri türü: FP16 modeller WebGPU’da bellek ve bant genişliği avantajı sağlar. Mümkünse ağırlıkları FP16’ya dönüştürün. 2) Boyutlandırma: Görsel görevlerde 160–224 piksel aralığı mobil cihazlar için iyi bir dengedir. 3) Ön bellekleme: Uygulama açılışında session’ı yükleyip sıcak tutmak (warm-up) soğuk başlangıç gecikmesini azaltır. 4) I/O bağlama: ORT Web’de (sürümünüze bağlı) tensörleri GPU belleğinde tutmak için IOBindings seçeneklerini inceleyin. 5) Paralellik: WASM’a düşerseniz SIMD ve çok iş parçacığı hız kazandırır; bunun için COOP/COEP başlıklarıyla cross-origin isolation etkin olmalı.

Geriye uyumluluk ve düşüş (fallback) stratejisi

Her cihaz WebGPU desteklemeyebilir. Bu yüzden navigator.gpu kontrolüyle otomatik geçiş uygulayın: WebGPU → WASM. Kullanıcıya “hızlandırma kapalı” gibi basit bir durum göstergesi sunmak, deneyimi şeffaf kılar. Mobilde pil ve termal kısıtlar için bir “düşük güç modu” eklemek de değerlidir.

Güvenlik ve gizlilik

İstemci tarafı çıkarım (inference), verinin cihazdan çıkmamasını sağlar. Ancak model dosyaları herkese açık sunuluyorsa, telif ve lisans koşullarını gözden geçirin. Ayrıca büyük modeller cihaz belleğini hızla tüketebilir; kademeli yükleme (lazy load) ve dinamik boşaltma (dispose) uygulayın.

Sorun giderme

WebGPU görünmüyor: Kurumsal politikalar veya eski tarayıcı sürümü olabilir; flags ve sürüm kontrolü yapın. GPU belleği yetersiz: Giriş çözünürlüğünü ve batch boyutunu düşürün, FP16 kullanın. Yavaş ilk çalıştırma: Modeli önden ısıtın ve CDN’de sıkıştırma (gzip/br) + cache headers kullanın. WASM fallback çok yavaş: cross-origin isolation ile WASM SIMD/threads’i etkinleştirin ve daha hafif bir model seçin.

Sonuç

WebGPU, tarayıcıda yapay zekayı gerçek zamanlıya yaklaştırıyor. ONNX Runtime Web ile ince ayarlı, Transformers.js ile hızlı ve pratik bir deneyim kurabilirsiniz. Doğru model boyutu, FP16, akıllı ön/son işlem ve sağlam fallback stratejisiyle hem masaüstü hem mobilde akıcı bir kullanıcı deneyimi sunmak mümkün.

3 Aralık 2025 Çarşamba

Next.js ile Passkey (WebAuthn) Entegrasyonu: Parolasız Girişe Adım Adım Rehber

Giriş: Neden Passkey (WebAuthn)?

Parolalar hem kullanıcılar hem de geliştiriciler için baş ağrısı. Zayıf parolalar, kimlik avı, sızıntılar ve unutma problemi derken, güvenli ve sorunsuz bir deneyim için endüstri Passkey (FIDO2/WebAuthn) standartına hızla geçiyor. Passkey ile kullanıcılar biyometri (Face ID, Touch ID), donanım güvenlik anahtarı veya cihaz PIN’iyle güvenli ve parolasız giriş yapabiliyor. Bu rehberde, Next.js ve simplewebauthn kullanarak uçtan uca bir Passkey akışını nasıl kurabileceğinizi adım adım anlatıyorum.

Gereksinimler ve Kurulum

Başlamadan önce Node.js 18+, Next.js 13/14 App Router, bir veri tabanı (PostgreSQL veya MongoDB) ve HTTPS (localhost için Chrome’da güvenilir sertifika veya bir tünel aracı) gerekli. WebAuthn, origin ve rpID değerlerine duyarlıdır; yerel geliştirmede localhost ve üretimde gerçek alan adını kullanın. Kütüphaneler için npm i @simplewebauthn/server @simplewebauthn/browser komutunu çalıştırın.

Mimari: Kayıt ve Giriş Akışı

Passkey iki ana akıştan oluşur: Kayıt (Registration) ve Doğrulama (Authentication). Kayıtta sunucu bir challenge üretir, istemci bu veriyi cihazın güvenli donanımına kaydeder ve attestation verisini sunucuya geri yollar. Girişte ise sunucu yeni bir challenge üretir, istemci cihazı bunu imzalar ve imzalı assertion sunucuda doğrulanır. Tüm süreçte challenge değerini oturum (session, Redis) gibi geçici ve güvenli bir yerde tutmak önemlidir.

Sunucu Tarafı: Endpoints ve Doğrulama

Next.js App Router’da app/api altında iki çift endpoint tanımlayın: /register/generate ve /register/verify, /login/generate ve /login/verify. @simplewebauthn/server içindeki generateRegistrationOptions, verifyRegistrationResponse, generateAuthenticationOptions ve verifyAuthenticationResponse yardımcıları işinizi hızlandırır.

Önemli alanlar: rpID alan adınız (ör. example.com), origin tam kök adresiniz (ör. https://example.com). Üretimde bunların sabit ve doğru olması gerekir. Kayıt doğrulandıktan sonra veritabanında şu alanları saklayın: kullanıcı kimliği, credential ID (base64url), publicKey, counter, transports, backupEligibility/backupState bilgileri. Girişte doğrulama sonrası karşılaştırma için counter değerini güncelleyerek yeniden oynatma saldırılarını engelleyin.

İstemci Tarafı: Tarayıcı API’leriyle Etkileşim

Tarayıcı tarafında @simplewebauthn/browser kütüphanesinin startRegistration ve startAuthentication fonksiyonlarını kullanın. Kayıt için önce /register/generate endpoint’inden seçenekleri alın, startRegistration çağrısını yapın ve sonucu /register/verify’e gönderin. Giriş için benzer şekilde /login/generatestartAuthentication/login/verify akışını izleyin. Bu işlemler sırasında kullanıcı, cihazında biyometrik doğrulama veya güvenlik anahtarına dokunuş gibi bir etkileşimle süreci tamamlar.

Pratik İpuçları ve Sık Hatalar

- Origin/RP ID uyuşmazlığı: En yaygın hata budur. Geliştirmede https://localhost:3000 origin ile rpID=localhost kullanın. Üretimde https://alanadiniz.com ve rpID=alanadiniz.com şart.

- Challenge saklama: Challenge’ı oturumda tutmazsanız doğrulama başarısız olur. Kısa ömürlü bir store (Redis, Signed Cookie) güvenlidir.

- Discoverable credentials: Kullanıcının e-posta girmeden giriş yapabilmesi için resident keys (discoverable) açılabilir. Gizlilik ve UX dengesini iyi düşünün; bazı senaryolarda kullanıcı kimliğini yine de isteyebilirsiniz.

- Platform desteği: iOS/Android, Chrome/Safari/Edge yeni sürümlerde destekler iyi durumdadır; ancak eski cihazlarda güvenlik anahtarı (YubiKey) fallback’i planlayın.

Güvenlik ve Uyum Notları

WebAuthn, kimlik avını ciddi ölçüde azaltır; çünkü imza domain’e (origin) bağlıdır. Yine de bazı ek önlemler gerekir: her istek için CSRF koruması, üretimde HTTPS zorunluluğu, gelen yanıtlar için origin doğrulaması, güvenli cookie ayarları (HttpOnly, SameSite=Lax/Strict, Secure). Kullanıcının birden fazla cihazda passkey kullanabilmesi için hesap başına birden fazla credential kaydına izin verin ve kolay yönetim ekranları oluşturun.

Kurumsal ortamlarda enforce MFA ve politika tabanlı kayıt akışlarını düşünebilirsiniz. Ayrıca, backup/icloud passkey senkronizasyonu devredeyse, cihaz değişiminde kullanıcı deneyimi daha pürüzsüz olur. Bu arada, userVerification modunu required olarak ayarlamak, cihazda biyometrik/PIN doğrulamasını zorunlu kılarak güvenliği artırır.

Örnek Veri Modeli ve Loglama

Basit bir credential tablosu şu alanları içerebilir: id, userId, credentialId (unique), publicKey, counter, deviceType (platform/cross-platform), backupState, transports, createdAt, lastUsedAt. Her doğrulamada lastUsedAt ve counter değerlerini güncelleyin. Üretimde başarısız doğrulamalar için detaylı ancak kişisel veriyi ifşa etmeyen loglar tutun; PII saklamamaya özen gösterin.

Performans ve UX İyileştirmeleri

İlk boyamada kullanıcıya cihazın passkey desteklediğini hızlıca göstermek için PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() ile bir özellik kontrolü yapabilirsiniz. Desteklenmiyorsa alternatif girişi (OTP/Magic Link) otomatik önerin. SSR yerine istemci tarafında akışı tetikleyip, istekleri mutate eden bir data fetching yaklaşımı (SWR/React Query) ile ağ hatalarında kullanıcıya net geri bildirim sağlayın.

Sonuç

Passkey (WebAuthn) entegrasyonu, hem güvenliği hem de dönüşüm oranlarını artıran çağdaş bir yaklaşım. Next.js ve simplewebauthn ile kurulum nispeten hızlı; kritik nokta ise rpID/origin doğruluğu, challenge yönetimi ve credential saklama stratejisi. Bu rehberdeki adımları izleyerek parolasız deneyimi projenize ekleyebilir, kullanıcılarınıza modern ve güvenli bir giriş akışı sunabilirsiniz.

2 Aralık 2025 Salı

Passkey (WebAuthn/FIDO2) ile Parolasız Giriş: Next.js Üzerinde Adım Adım Kurulum

Passkey nedir ve neden önemlidir?

Parolasız kimlik doğrulama, son yılların en önemli güvenlik trendlerinden biri. Passkey teknolojisi (WebAuthn/FIDO2), kimlik doğrulamayı klasik parolaların ötesine taşıyarak kimlik avına dayanıklı ve kullanıcı dostu bir deneyim sunuyor. Apple, Google ve Microsoft’un ekosistemleriyle entegre çalışan passkey’ler; cihazdaki güvenli donanım veya güvenli alanı kullanarak anahtar çifti üretir ve web sitelerine girişte yalnızca özel anahtar cihazda kalır. Böylece kullanıcılar Touch ID/Face ID, Windows Hello veya Android’in biyometrik yöntemleriyle tek dokunuşla güvenli giriş yapabilir.

Nasıl çalışır? (Kısa teknik özet)

Passkey, tarayıcıların sunduğu WebAuthn API üzerinden etkileşim kurar. Site (Relying Party), kayıt sırasında tarayıcıya bir “challenge” ve alan adı (rpID) gönderir. Kullanıcının cihazı bir anahtar çifti üretir; genel anahtar sunucuya kaydedilir, özel anahtar cihazda kalır. Giriş esnasında sunucu yeni bir “challenge” üretir; cihaz bu “challenge”ı özel anahtarla imzalar ve sunucu imzayı doğrular. Bu yapı sayesinde şifre sızması, parola doldurma saldırıları ve kimlik avı riskleri önemli ölçüde azalır.

Önkoşullar ve mimari

Bu rehberde Next.js 14 (App Router) üzerinde örnek bir passkey akışı kuracağız. İhtiyacınız olanlar: Node.js 18+, Next.js projesi, HTTPS (geliştirirken localhost desteklenir), bir veritabanı (ör. PostgreSQL, MongoDB) ve WebAuthn yardımcı kütüphaneleri. Üretimde rpID değeriniz, gerçek alan adınız (ör. example.com) olmalı; doğrulama başarısızlıklarının büyük kısmı rpID/domain uyumsuzluğundan kaynaklanır.

Adım 1: Kurulum ve bağımlılıklar

Örnek projeyi başlatmak için npx create-next-app@latest passkey-demo komutunu kullanın. Ardından sunucu ve istemci tarafı için popüler bir yardımcı set olan @simplewebauthn/server ve @simplewebauthn/browser paketlerini ekleyin: npm i @simplewebauthn/server @simplewebauthn/browser. Ortam değişkenleri için RP_NAME ve RP_ID tanımlayın (ör. RP_NAME="Passkey Demo", RP_ID="localhost" veya üretimde example.com).

Adım 2: Kayıt (Registration) akışı

Kayıt akışı iki uç noktadan oluşur: seçenek üretimi ve doğrulama. Sunucuda önce generateRegistrationOptions ile kullanıcıya özel bir challenge ve seçenekler oluşturulur. Örnek kullanım: const opts = generateRegistrationOptions({ rpName, rpID, userID, userName, attestationType: 'none', authenticatorSelection: { residentKey: 'preferred', userVerification: 'preferred' } }). Bu opts istemciye döndürülür ve tarayıcıda startRegistration(opts) çağrısı yapılır. Tarayıcı, cihazın güvenli alanında anahtar çifti üretir ve sonucu (credential) sunucuya gönderir.

Doğrulama aşamasında sunucuda verifyRegistrationResponse ile imza ve köken (origin) kontrolü yapılır. Başarılıysa kullanıcının hesabına credentialID, publicKey, signCount gibi alanları kaydedin. Birden fazla cihaza passkey eklenmesini desteklemek için kullanıcı başına birden çok credential saklamak iyi bir pratiktir.

Adım 3: Giriş (Authentication) akışı

Giriş için benzer şekilde önce generateAuthenticationOptions çağrılır. Kullanıcıya ait credential’lar biliniyorsa allowCredentials listesi ile sınırlandırabilir veya cihazın keşfedilebilir kimlik bilgilerini (discoverable credentials) desteklemek için boş bırakabilirsiniz. İstemci tarafında startAuthentication(opts) çalıştırılır ve elde edilen yanıt sunucuya doğrulama için gönderilir.

Sunucuda verifyAuthenticationResponse ile imza, challenge, origin, rpID ve sayacın (signCount) ilerleyişi kontrol edilir. Başarılı doğrulamada kullanıcı oturumunu başlatın ve credential’ın signCount değerini güncelleyin. Geriye dönük saldırıları önlemek için aynı imzayı tekrar kabul etmeyin.

İyi uygulamalar (Security + UX)

- HTTPS zorunludur: Üretimde daima HTTPS kullanın; rpID alan adınız ile origin (ör. https://example.com) örtüşmelidir. Geliştirmede localhost istisna olarak desteklenir.
- Biyometrik doğrulama: userVerification: 'required' seçeneği güvenliği artırır ancak bazı eski cihazlarda uyumluluğu azaltabilir. Dengeli yaklaşım için 'preferred' iyi bir başlangıçtır.
- Platform ve geçiş anahtarları: Kullanıcılara hem cihaz içi (platform) hem de harici güvenlik anahtarlarıyla kayıt seçeneği sunun.
- Hesap kurtarma: Passkey harika bir deneyim sunar; yine de e‑posta tabanlı oturum açma bağlantısı veya sınırlı süreli OTP gibi bir kurtarma kanalı tutun.
- Çoklu cihaz: iCloud Anahtar Zinciri veya Google Password Manager senkronizasyonu sayesinde kullanıcı farklı cihazlardan giriş yapabilir; bu durumda kullanıcı akışını basit ve yönlendirici metinlerle destekleyin.

Test, hata ayıklama ve dağıtım

Geliştirme sırasında WebAuthn’ı about://webauthn veya Chrome’un Geliştirici Araçları altındaki Sanal Kimlik Doğrulayıcı ile test edebilirsiniz. Gerçek cihaz testi için ngrok gibi tünelleme araçlarıyla geçici bir HTTPS alan adı edinip RP_ID’yi bu alan adına ayarlayın. iOS 16+, Android 9+ ve modern masaüstü tarayıcılar passkey’i destekler. Üretime alırken CORS, SameSite ve Secure bayraklı çerez ayarlarını kontrol edin; kimlik doğrulama uç noktalarınızı rate limit ve CSRF koruması ile güçlendirin.

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

- Invalid Relying Party ID: rpID ile sitenin alan adı eşleşmiyordur. Alt alan adlarında rpID üst etki alanı olabilir (ör. app.example.com için example.com).
- NotAllowedError: Kullanıcı tarayıcı diyalogunu iptal etmiştir veya zaman aşımı yaşanmıştır. İstemci tarafında daha anlaşılır hata mesajları ve tekrar dene düğmesi gösterin.
- User verification required: Sunucuda userVerification 'required' iken cihaz biyometrik doğrulama sunmuyorsa 'preferred' ile test edin.
- Counter mismatch: signCount geriye düştüyse credential’ı güvenlik gerekçesiyle askıya alın ve kullanıcıdan yeniden kayıt isteyin.

Sonuç

Passkey, güvenliği artırırken kullanıcı deneyimini hızlandıran güçlü bir yaklaşım. Next.js ile WebAuthn/FIDO2 entegrasyonu birkaç uç nokta ve doğru yapılandırmayla kısa sürede hayata geçebilir. Bu rehberdeki adımlarla kayıt ve giriş akışlarını kurabilir, üretimde HTTPS, rpID, sayım ve köken kontrolleriyle sisteminizi sertleştirebilirsiniz. Parolasız geleceğe geçiş için en iyi zaman, kullanıcılarınız hazır ve modern tarayıcılar destekliyorken bugündür.

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.