Traefik vs Nginx: nginx Kullanıcıları İçin Giriş
nginx bilen geliştiriciler için pratik Traefik rehberi: temel kavramlar, Docker kurulum örnekleri ve nginx'e kıyasla Traefik'i ne zaman seçeceğin.
Traefik, çalışırken değişen altyapılar için tasarlanmış bir reverse proxy ve load balancer. Container orchestrator’ünü izler ve routing kurallarını kendisi günceller; nginx ise config dosyasını düzenleyip reload etmeni bekler. Seçimin büyük kısmını bu tek fark belirliyor. Servislerin kendi takvimine göre gelip giden container’larsa, o kenara Traefik koy; topolojinin sabit olduğu yerde nginx’te kal.
Takas şu: operasyonel kolaylığa karşılık daha ince bir veri yolu. Traefik düzenle-test-et-reload döngüsünü ortadan kaldırıyor, bedelini de daha büyük bir runtime ayak izi ve daha az olgun bir rewrite/caching motoruyla ödüyor. Sabit bir upstream listesi statik dosya sunuyorsa bu kötü bir takas. Günde birkaç kez yeniden deploy edilen bir container filosu içinse kolay bir takas.
Traefik Nedir?#
Traefik cloud-native bir edge router. Başlangıçta statik bir konfigürasyon dosyası okumak yerine bir provider’a (Docker, Kubernetes, Consul) abone olur ve provider her değişiklik bildirdiğinde routing tablosunu yeniden kurar. Konfigürasyon ortadan kalkmıyor; servisin yanına taşınıyor, container label’ı veya Ingress annotation’ı olarak.
Traefik, servislerin sık sık gelip gittiği ortamlarda parlıyor: microservice deployment’ları, development ortamları veya developer’ların kendi servislerini deploy ettiği platformlar. Hedeflediği sorun dar kapsamlı: dinamik konfigürasyon yönetimi.
Traefik’in Çözdüğü Temel Problem#
Sık karşılaşılan bir senaryo: Docker Swarm veya Kubernetes cluster’ına yeni bir microservice deploy ediyorsun. nginx ile yapman gerekenler:
- nginx konfigürasyon dosyasını editlemek
- Konfigürasyonu test etmek
- nginx’i reload etmek
- Bir şey bozulmadığını umut etmek
Traefik ile Docker container’ına label’lar ekliyorsun veya Kubernetes service’ine annotation’lar koyuyorsun, routing kuralları otomatik güncelleniyor. Sunuculara SSH yapman, konfigürasyon dosyası editlemen, servis reload’u gerekmiyor.
Temel Kavramlar#
1. Provider’lar#
Provider’lar Traefik’in servisleri keşfetme yöntemi. Yaygın provider’lar:
- Docker: Docker container’larını ve label’larını izler
- Kubernetes: Ingress/IngressRoute resource’larını okur
- File: Geleneksel konfigürasyon dosyaları (evet, hala statik config kullanabilirsin)
- Consul, Etcd: Service discovery backend’leri
Provider abstraction güçlü bir kavram: development’ta Docker label’ları ile başlayıp production’da Kubernetes annotation’larına geçebilirsin, aynı mental modeli kullanarak.
2. Entrypoint’ler#
Entrypoint’ler Traefik’in hangi portları dinlediğini tanımlar. Tipik kurulum:
# Port 80'de HTTP entrypoint
--entrypoints.web.address=:80
# Port 443'te HTTPS entrypoint
--entrypoints.websecure.address=:443
3. Router’lar#
Router’lar entrypoint’leri kurallara göre servislerle bağlar. Kurallar şunlara göre eşleşebilir:
- Host header’ları:
Host(`api.example.com`) - Path prefix’leri:
PathPrefix(`/api`) - Header’lar:
Headers(`X-Custom-Header`, `value`) - Birden fazla koşul:
Host(`api.example.com`) && PathPrefix(`/v1`)
4. Middleware’ler#
Middleware’ler request/response’ları dönüştürür. Traefik’in gücünün ortaya çıktığı yer burası:
- HTTP’yi HTTPS’e redirect et
- Header ekle/çıkar
- Rate limiting
- Basic authentication
- Circuit breaker’lar
- Compression
Pratik Kurulum Örneği#
İki servisin önünde Traefik duran bir Docker Compose kurulumu:
version: '3.8'
services:
traefik:
image: traefik:v2.10
command:
# Docker provider'ı etkinleştir
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
# Entrypoint'leri tanımla
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
# Dashboard'u etkinleştir (production'da kaldır)
- "--api.dashboard=true"
# Access log'ları etkinleştir
- "--accesslog=true"
ports:
- "80:80"
- "443:443"
- "8080:8080" # Dashboard
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
labels:
# Dashboard için Traefik'i etkinleştir
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.localhost`)"
- "traefik.http.routers.dashboard.service=api@internal"
whoami:
image: traefik/whoami
labels:
# Bu container için Traefik'i etkinleştir
- "traefik.enable=true"
# Routing kuralını tanımla
- "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"
# Entrypoint'i belirt
- "traefik.http.routers.whoami.entrypoints=web"
api:
image: nginx:alpine
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.localhost`)"
- "traefik.http.routers.api.entrypoints=web"
# Path stripping için middleware ekle
- "traefik.http.routers.api.middlewares=api-stripprefix"
- "traefik.http.middlewares.api-stripprefix.stripprefix.prefixes=/api"
Bunu docker-compose up -d ile başlat ve şunlara erişebilirsin:
http://whoami.localhost- whoami servisihttp://api.localhost- nginx servisihttp://traefik.localhost- Traefik dashboard
Eşdeğer nginx Konfigürasyonu#
Karşılaştırma için, aynı kurulum için nginx’te ihtiyacın olanlar:
# /etc/nginx/conf.d/services.conf
# Upstream tanımları
upstream whoami_backend {
server whoami:80;
}
upstream api_backend {
server api:80;
}
# whoami servisi
server {
listen 80;
server_name whoami.localhost;
location / {
proxy_pass http://whoami_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# API servisi
server {
listen 80;
server_name api.localhost;
location /api {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://api_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
nginx config’i olduğu gibi gayet iyi. Maliyet bir sonraki serviste ortaya çıkıyor: dosyayı düzenle, test et, reload et.
Middleware Kullanımı#
İşte HTTPS redirect ve rate limiting kullanan middleware’ler ile pratik bir örnek:
services:
traefik:
image: traefik:v2.10
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
# Global HTTP to HTTPS redirect
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
api:
image: your-api:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.example.com`)"
- "traefik.http.routers.api.entrypoints=websecure"
# Rate limiting middleware'i uygula
- "traefik.http.routers.api.middlewares=api-ratelimit,api-auth"
# Rate limit: saniyede ortalama 100 request, 50 burst
- "traefik.http.middlewares.api-ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.api-ratelimit.ratelimit.burst=50"
# Basic authentication
- "traefik.http.middlewares.api-auth.basicauth.users=admin:$$apr1$$hash..."
Aynı rate limiting’i nginx’te uygulamak ngx_http_limit_req_module (iyi çalışır) veya harici araçlar gerektirir. Her iki yaklaşım da işe yarar; Traefik versiyonu sadece farklı konfigure edilir.
İstek Akışı Mimarisi#
Request’lerin Traefik’ten nasıl geçtiğine geleneksel kurulumla karşılaştırmalı bakalım:
nginx Yerine Traefik Ne Zaman Seçilmeli#
Burada mesele hangisinin daha iyi olduğu değil, hangisinin kuruluma oturduğu.
Traefik’i Şu Durumlarda Seç#
- Dinamik altyapı: Servisler sık deploy edilip kaldırılıyor
- Container-native: Docker, Kubernetes veya benzeri orchestrator’lar kullanıyorsun
- Developer self-service: Takımlar kendi servislerini label/annotation’larla deploy ediyor
- Otomatik HTTPS: Let’s Encrypt entegrasyonu built-in ve çok kolay
- Microservice’ler: Bağımsız değişen bir sürü küçük servis
Kazanç proxy’nin dışında görünür. Routing değişikliği ortak bir dosyanın düzenlenmesi olmaktan çıkıp servisin kendi deploy manifest’inin parçası olur; böylece kodla aynı review ve rollback yolunu izler.
nginx’i Şu Durumlarda Seç#
- Statik altyapı: Servisler nadiren değişiyor
- Kompleks URL rewriting: nginx’in rewrite engine’i daha olgun
- Maksimum performans: nginx’in latency’si daha düşük (fark küçük olsa da)
- Gelişmiş caching: nginx’in caching yetenekleri daha sofistike
- Statik dosya sunma: nginx bu işte üstün
nginx’in olgunluğunun somutlaştığı yer burası: response caching için proxy_cache, statik asset’ler için sendfile ve open_file_cache, arkasında yılların uç durumları biriken bir rewrite motoru. Traefik’te yerleşik bir response cache veya statik dosya sunucusu yok; path rewrite middleware’leri de daha dar bir alanı kapsıyor.
Yaygın Pattern’ler ve Gotcha’lar#
Pattern 1: Servis Başına Birden Fazla Router#
Aynı servise farklı path’leri farklı middleware’lerle yönlendirebilirsin:
labels:
- "traefik.enable=true"
# Public API - rate limited
- "traefik.http.routers.api-public.rule=Host(`api.example.com`) && PathPrefix(`/public`)"
- "traefik.http.routers.api-public.middlewares=rate-limit"
# Internal API - rate limit yok, authentication gerekli
- "traefik.http.routers.api-internal.rule=Host(`api.example.com`) && PathPrefix(`/internal`)"
- "traefik.http.routers.api-internal.middlewares=auth"
Pattern 2: Weighted Load Balancing#
# Servis A - trafiğin %80'i
labels:
- "traefik.http.services.myapp.loadbalancer.server.port=8080"
- "traefik.http.services.myapp.loadbalancer.sticky.cookie=true"
# Servis B - trafiğin %20'si (canary deployment)
labels:
- "traefik.http.services.myapp-canary.loadbalancer.server.port=8080"
# Weighted load balancing'li router
labels:
- "traefik.http.routers.myapp.service=myapp-weighted"
- "traefik.http.services.myapp-weighted.weighted.services[0].name=myapp"
- "traefik.http.services.myapp-weighted.weighted.services[0].weight=80"
- "traefik.http.services.myapp-weighted.weighted.services[1].name=myapp-canary"
- "traefik.http.services.myapp-weighted.weighted.services[1].weight=20"
Gotcha 1: Docker Socket Erişimi#
Traefik’in Docker socket’ine read erişimi lazım. Production’da, maruz kalma riskini sınırlamak için tecnativa/docker-socket-proxy gibi bir Docker socket proxy kullanmayı düşün.
Gotcha 2: Label Syntax#
Label’lar string olduğu için kompleks değerler düzgün escape edilmeli:
# Yanlış - bozulur
- "traefik.http.routers.api.rule=Host(`api.example.com`) && PathPrefix(`/v1`)"
# Doğru - compose versiyonuna göre backtick'leri escape et
- 'traefik.http.routers.api.rule=Host(`api.example.com`) && PathPrefix(`/v1`)'
Gotcha 3: Default Ayarlar#
Varsayılan olarak Traefik TÜM container’ları expose eder. exposedbydefault=false yap ve servisleri açıkça etkinleştir:
command:
- "--providers.docker.exposedbydefault=false"
Kullanım Senaryoları#
Senaryo 1: Development Ortamı#
Tek bir hostname arkasında çok servisli bir local kurulum:
version: '3.8'
services:
traefik:
image: traefik:v2.10
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
frontend:
image: node:18
working_dir: /app
command: npm run dev
volumes:
- ./frontend:/app
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`app.local`)"
- "traefik.http.services.frontend.loadbalancer.server.port=3000"
backend:
image: node:18
working_dir: /app
command: npm start
volumes:
- ./backend:/app
labels:
- "traefik.enable=true"
- "traefik.http.routers.backend.rule=Host(`app.local`) && PathPrefix(`/api`)"
- "traefik.http.services.backend.loadbalancer.server.port=4000"
/etc/hosts’a 127.0.0.1 app.local ekle, birleşik bir local development URL’ine sahip olursun.
Senaryo 2: Let’s Encrypt ile Otomatik HTTPS#
services:
traefik:
image: traefik:v2.10
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
# Let's Encrypt konfigürasyonu
- "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
# HTTP'den HTTPS'e redirect
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
app:
image: your-app:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`example.com`)"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.tls.certresolver=letsencrypt"
Traefik sertifika alımını, yenilemeyi ve sunmayı otomatik halleder. nginx ile genelde certbot’u cron job’larla ve nginx’i reload eden hook’larla kullanırsın.
Performans Farkı#
Her iki proxy de çoğu yükte darboğaz olmayacak kadar hızlı. Ayrışma daha çok yapısal tarafta:
- Latency: nginx istek başına daha az ek yük getirir; fark tek bir veritabanı çağrısının arkasında kaybolur.
- Throughput: Sentetik benchmark’larda nginx önde; kendi payload boyutlarınla ölçmeden bunu karar sayma.
- Resource kullanımı: Traefik Go runtime’ında çalışır ve orchestrator’ün canlı görüntüsünü tutar; boştaki memory ayak izi ikisinin yüksek olanı.
- CPU: Normal yükte benzer; nginx ekstrem trafikte öne geçer.
Çoğu uygulamada otomatik keşfin operasyonel kazancı bu farktan ağır basar. Ultra yüksek trafikli statik content delivery içinse belirleyici olan nginx’in avantajı.
Geçiş Stratejisi#
nginx’ten Traefik’e geçiyorsan, riski düşük bir sıra:
- Yan yana başla: nginx ve Traefik’i birlikte çalıştır
- Aşama aşama taşı: Servisleri teker teker geçir
- File provider kullan: Traefik statik config dosyalarını okuyabilir (nginx’e benzer)
- İyice test et: Özellikle middleware chain’leri ve routing kurallarını
- Metrikleri izle: Latency, hata oranları, resource kullanımını karşılaştır
Her şeyi migrate etmen gerekmiyor. Bazı takımlar statik content ve API’ler için nginx kullanırken Traefik dinamik microservice’leri hallediyor.
Sonuç#
Varsayılan seçim, topoloji hareket ettiği sürece geçerli: kendi takvimine göre yeniden deploy edilen container’lar, proxy ticket’ı açmadan yayına çıkan takımlar, elle yenilemek istemediğin sertifikalar. Upstream listesi sabitse ve yük statik dosya ya da yoğun caching ise tersini seç; nginx’in rewrite motorunun, response cache’inin ve dosya sunumunun Traefik’te yerleşik karşılığı yok. İkisini birlikte çalıştırmak olağan bir sonuç: statik kenarda nginx, container’ların önünde Traefik.
Önce yukarıdaki temel Compose dosyasıyla başla; routing oturduktan sonra middleware’leri ve Let’s Encrypt’i ekle.
Kaynaklar#
- Traefik Proxy Belgeleri (yeni sekmede açılır) - Traefik v3 için giriş noktaları, yönlendiriciler, servisler ve middleware’leri kapsayan resmi belgeleme.
- Traefik Middleware Referansı (yeni sekmede açılır) - Hız sınırlama, kimlik doğrulama ve başlıklar dahil istek dönüşüm middleware’leri için tam referans.
- Traefik Docker Provider Belgeleri (yeni sekmede açılır) - Docker etiketleri aracılığıyla konteyner otomatik keşfi ve beklenen etiket söz dizimi için resmi kılavuz.
- Traefik ACME / Let’s Encrypt Yapılandırması (yeni sekmede açılır) - ACME protokolü kullanılarak otomatik TLS sertifikası sağlama için resmi referans.
- Traefik Hızlı Başlangıç Kılavuzu (yeni sekmede açılır) - Docker Compose ile Traefik kurulumu için yeni başlayanlara yönelik adım adım rehber.
- Dokploy Belgeleri (yeni sekmede açılır) - Konteyner yönlendirme ve SSL sonlandırma için dahili olarak Traefik kullanan self-hosted PaaS belgeleri.
İlgili yazılar
Geliştiriciler için pratik bir ağ kavramları sözlüğü - protokollerden DNS'e, debugging araçlarından güvenlik temellerine.
networking · http · debugging +3
VPS, Dokploy deployment platformu ve Cloudflared tunnel kullanarak güvenli, uygun maliyetli private sunucu kurulumu için pratik bir rehber
docker · deployment · cloudflare +2
AWS Fargate'e pratik bir rehber: task definition, awsvpc network modu, maliyet dengesi ve serverless container'ların ne zaman mantıklı olduğu.
aws · fargate · ecs +3
Ölçekte karşılaşacağınız IAM boyut, ekleme ve kota limitleri; ve hepsinden uzak tutan dar kapsamlı politika, izin sınırı ve SCP yapısı.
aws · iam · security +2
Her git olayı farklı bir işi hak eder: push, pull_request, merge kuyruğu ve tag/release'de ne çalışmalı? Lead time'ı koruyan bir GitHub Actions yönlendirme rehberi.
ci-cd · github-actions · devops +1