Tek sunucuda beş farklı konteyner çalıştırdığınız anda aynı soruyla karşılaşırsınız: 80 ve 443 portunu hangisi alacak? Her uygulamayı farklı porta bağlayıp firmaniz.com:8081 gibi adresler dağıtmak kısa vadede işe yarar ama ne SSL'i düzgün çözer ne de kimseye gönül rahatlığıyla verebileceğiniz bir adres üretir. Bu noktada devreye ters proxy (reverse proxy) girer ve Docker dünyasında bu işin en pratik çözümlerinden biri Traefik'tir. Traefik'in klasik Nginx yapılandırmasından ayrıldığı yer şu: yeni bir uygulama eklediğinizde hiçbir yapılandırma dosyasına dokunmazsınız, uygulamanın kendi docker-compose.yml dosyasına birkaç etiket yazarsınız ve Traefik bunu Docker soketinden okuyup yönlendirmeyi kendi kurar.
Bu rehberde sıfırdan bir Traefik kurulumunu adım adım kuracağız: paylaşılan bir Docker ağı oluşturmak, Traefik'i docker-compose ile ayağa kaldırmak, Let's Encrypt'ten otomatik sertifika almak, bir örnek uygulamayı etiketlerle bağlamak, dashboard'u şifreyle korumak ve HTTP'den HTTPS'e zorunlu yönlendirme kurmak. Sonunda da benim yıllardır aynı sırayla gördüğüm hataları — yanlış ağ, eksik dosya izni, acme.json tuzağı, rate limit yemek — tek tek ele alacağız.
Traefik Neden Diğer Ters Proxy'lerden Farklı#
Nginx veya Apache ile ters proxy kurduğunuzda akış şudur: bir server bloğu yazarsınız, proxy_pass ile hedefi belirtirsiniz, sertifikayı elle ya da certbot ile alırsınız, sonra servisi yeniden yüklersiniz. Her yeni uygulama bu döngüyü tekrarlar. Traefik ise "servis keşfi" (service discovery) mantığıyla çalışır: arka planda Docker'ın soketini dinler, yeni bir konteyner ayağa kalktığında etiketlerine bakar ve yönlendirme kuralını anında belleğine ekler. Yani yapılandırma, proxy'nin dosyasında değil uygulamanın kendi tanımında yaşar.
Bu yaklaşımın pratik sonucu şudur: on farklı projeyi tek sunucuda barındırıyorsanız, on ayrı nginx.conf bloğu ve on ayrı certbot yenileme kancası yönetmek yerine tek bir Traefik konteyneri ve her projede üç dört satır etiket yönetirsiniz. Aşağıdaki tablo üç popüler seçeneği pratik açıdan karşılaştırıyor:
| Özellik | Traefik | Nginx (elle) | Caddy |
|---|---|---|---|
| Yapılandırma yeri | Konteyner etiketleri | Merkezi conf dosyaları | Caddyfile |
| Docker keşfi | Yerleşik | Yok (elle) | Eklenti ile |
| Otomatik sertifika | Yerleşik ACME | certbot ile ayrı | Yerleşik |
| Yeniden başlatma gerekir mi | Hayır | Genelde evet | Hayır |
| Öğrenme eğrisi | Orta | Düşük-orta | Düşük |
Traefik'in bedeli, kavramlarının başta yabancı gelmesidir: entrypoint (dinlenen port), router (hangi isteğin nereye gideceği), service (arka uç), middleware (araya giren dönüşüm). Bu dördünü bir kez oturttuğunuzda gerisi mekanik hale gelir. Daha görsel bir panel üzerinden aynı işi yapmak isterseniz Nginx Proxy Manager, tek satırlık yapılandırma tercih ediyorsanız Caddy ile otomatik HTTPS yazılarına da göz atın.
Kurulum Öncesi Hazırlık: Ağ, Dizin ve DNS#
Traefik'in bir uygulamaya trafik yönlendirebilmesi için ikisinin aynı Docker ağında bulunması şart. Bu yüzden en başta harici (external) bir ağ oluşturup her projeye bunu tanıtmak, sonradan çıkacak "gateway timeout" hatalarının yarısını baştan siler.
# Proxy'nin ve tüm uygulamaların paylaşacağı ortak ağ
docker network create proxy
# Traefik'in çalışacağı dizin ve sertifika deposu
mkdir -p /opt/traefik/letsencrypt
cd /opt/traefik
# acme.json sertifikaları tutar; izinleri 600 DEĞİLSE Traefik başlamayı reddeder
touch letsencrypt/acme.json
chmod 600 letsencrypt/acme.json
DNS tarafında yapmanız gereken tek şey, kullanacağınız alan adlarının A kaydını sunucunuzun genel IP adresine yöneltmektir. Let's Encrypt sertifikayı verirken HTTP-01 doğrulaması yapar; yani http://uygulama.firmaniz.com/.well-known/acme-challenge/... adresine bağlanıp gerçekten o alan adının sizin sunucunuza baktığını doğrular. DNS henüz yayılmadan Traefik'i başlatırsanız sertifika alma denemesi başarısız olur.
Kontrol listesi olarak şu üç maddeyi geçmeden devam etmeyin:
dig uygulama.firmaniz.com +shortkomutu sunucunuzun IP'sini dönmeli.- Sunucunun güvenlik duvarında 80 ve 443 portları dışarıya açık olmalı (
ufw allow 80,443/tcp). - 80 ve 443'te başka bir servis (sistem Nginx'i, Apache) dinlemiyor olmalı:
ss -ltnp | grep -E ':80|:443'.
Docker ağlarının nasıl çalıştığı, bridge ve host ağları arasındaki fark konusunda kafanız karışıksa Docker ağ yapılandırma rehberi bu bölümün altını doldurur.
docker-compose ile Traefik'i Ayağa Kaldırmak#
Traefik'i statik yapılandırmayı komut satırı bayraklarıyla vererek çalıştırmak, ayrı bir traefik.yml dosyası tutmaktan daha okunaklıdır; her şey tek dosyada durur. /opt/traefik/docker-compose.yml dosyasını şöyle oluşturun:
services:
traefik:
image: traefik:v3.1
container_name: traefik
restart: unless-stopped
command:
# Docker sağlayıcısını aç, ama HER konteyneri otomatik yayımlama
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=proxy
# Giriş noktaları
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
# 80'e geleni kalıcı olarak 443'e taşı
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
# Let's Encrypt HTTP-01 çözümleyicisi
- [email protected]
- --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.le.acme.httpchallenge=true
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
# Dashboard (aşağıda parola ile korunacak)
- --api.dashboard=true
- --log.level=INFO
- --accesslog=true
ports:
- "80:80"
- "443:443"
volumes:
# Salt okunur soket: Traefik yalnızca konteyner listesini okur
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
networks:
- proxy
networks:
proxy:
external: true
Dikkat edilecek iki satır var. exposedbydefault=false olmadan Traefik sunucudaki her konteyneri internete açmaya çalışır; veritabanınız da dahil. İkincisi, Docker soketini :ro (salt okunur) bağlamak zorunludur — yine de bu soket sunucu üzerinde root eşdeğeri yetki anlamına gelir, bu yüzden Traefik'i güvendiğiniz bir imajdan çalıştırın. Şimdi başlatın ve logu izleyin:
docker compose up -d
docker compose logs -f traefik
# Beklenen: "Configuration loaded from flags" ve entrypoint bilgileri
Bir Uygulamayı Etiketlerle Traefik'e Bağlamak#
Traefik ayakta, ama henüz hiçbir şeye yönlendirmiyor. Örnek olarak basit bir web uygulamasını bağlayalım. Ayrı bir dizinde şu compose dosyasını oluşturun:
services:
web:
image: nginx:alpine
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
# Router: hangi isteği yakalayacak
- "traefik.http.routers.web.rule=Host(`uygulama.firmaniz.com`)"
- "traefik.http.routers.web.entrypoints=websecure"
- "traefik.http.routers.web.tls.certresolver=le"
# Service: konteynerin İÇ portu (yayımlanan port değil)
- "traefik.http.services.web.loadbalancer.server.port=80"
networks:
proxy:
external: true
Burada web ismi routerın kimliğidir; her uygulamaya benzersiz bir isim verin, yoksa kurallar birbirini ezer. server.port değeri konteynerin içindeki porttur; uygulamanız 3000'de dinliyorsa buraya 3000 yazarsınız ve ports: bölümünü hiç kullanmazsınız — dışarıya port açmanıza gerek yoktur, çünkü trafik Traefik üzerinden iç ağdan akar. Bu, yanlışlıkla açık bırakılmış portların yol açtığı sızıntıları da kökten önler.
docker compose up -d
# Sertifikanın gelmesi 10-30 saniye sürebilir
curl -I https://uygulama.firmaniz.com
# HTTP/2 200 ve "server: nginx" görüyorsanız zincir tamamdır
Birden fazla kural birleştirebilirsiniz. Örneğin hem kök hem www için:
- "traefik.http.routers.web.rule=Host(`firmaniz.com`) || Host(`www.firmaniz.com`)"
Yol tabanlı yönlendirme de mümkündür: Host(firmaniz.com) && PathPrefix(/api) kuralı yalnızca /api ile başlayan istekleri API konteynerine gönderir. Bu sayede tek alan adı altında birden çok servisi bölüştürebilirsiniz.
Dashboard'u Güvene Almak ve Middleware Kullanımı#
Traefik'in dashboard'u hangi router'ın hangi servise baktığını, sertifikaların durumunu ve hataları gösterir; sorun giderirken çok işe yarar. Ancak parolasız bırakılmış bir dashboard, altyapınızın tüm haritasını internete açmak demektir. Doğru yöntem, temel kimlik doğrulama (basic auth) middleware'i eklemektir. Önce parola özetini üretin:
# htpasswd yoksa: apt install apache2-utils
htpasswd -nb yonetici GucluBirParola
# Çıktı: yonetici:$apr1$xxxxxxxx$yyyyyyyyyyyyyyyyyyyyy
Ardından Traefik servisinin kendi labels bölümüne şunları ekleyin. Compose dosyasında $ işaretinin iki kez yazılması ($$) zorunludur, aksi halde compose onu değişken sanıp siler:
labels:
- "traefik.enable=true"
- "traefik.http.routers.dash.rule=Host(`traefik.firmaniz.com`)"
- "traefik.http.routers.dash.entrypoints=websecure"
- "traefik.http.routers.dash.tls.certresolver=le"
- "traefik.http.routers.dash.service=api@internal"
- "traefik.http.routers.dash.middlewares=dashauth"
- "traefik.http.middlewares.dashauth.basicauth.users=yonetici:$$apr1$$xxxxxxxx$$yyyyyyy"
Middleware kavramı yalnızca kimlik doğrulama için değildir. Sık kullanılan birkaç örnek:
| Middleware | İşlevi | Tipik kullanım |
|---|---|---|
basicauth | Kullanıcı adı/parola sorar | Panel, staging ortamı |
redirectscheme | HTTP'yi HTTPS'e taşır | Genel zorunlu SSL |
ipwhitelist | Yalnız belirli IP'lere izin | Yönetim arayüzleri |
ratelimit | İstek sayısını sınırlar | API kötüye kullanımı |
headers | Güvenlik başlıkları ekler | HSTS, nosniff |
compress | Yanıtı gzip'ler | Statik içerik |
Güvenlik başlıklarını eklemek tek satır meselesidir ve bunu tüm projelerde varsayılan yapmanızı tavsiye ederim:
- "traefik.http.middlewares.sec.headers.stsSeconds=31536000"
- "traefik.http.middlewares.sec.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.sec.headers.frameDeny=true"
- "traefik.http.routers.web.middlewares=sec"
Sık Yapılan Hatalar ve Sorun Giderme#
404 page not found — Traefik ayakta ama isteği eşleştirecek kural bulamıyor demektir. Sırasıyla şunlara bakın: uygulamada traefik.enable=true etiketi var mı, Host() kuralındaki alan adı tarayıcıya yazdığınızla birebir aynı mı, ve konteyner gerçekten proxy ağında mı. Son maddeyi docker inspect -f '{{json .NetworkSettings.Networks}}' konteyner_adi ile doğrulayabilirsiniz.
Bad Gateway (502) — Kural eşleşiyor ama Traefik arka uca bağlanamıyor. Neredeyse her zaman loadbalancer.server.port yanlıştır: dışarıya yayımladığınız portu değil, uygulamanın konteyner içinde dinlediği portu yazmanız gerekir. İkinci ihtimal, uygulamanın 127.0.0.1 üzerinde dinlemesidir; konteyner içindeki bir servis yalnızca localhost'a bağlanırsa dışarıdan erişilemez, 0.0.0.0 dinlemelidir.
Sertifika gelmiyor, tarayıcı "TRAEFIK DEFAULT CERT" gösteriyor — Bu, ACME sürecinin başarısız olduğunun işaretidir. En sık üç sebep: acme.json izinleri 600 değil, DNS kaydı henüz yayılmamış, veya 80 portu dışarıdan erişilemiyor. Logu filtreleyerek gerçek nedeni görün:
docker compose logs traefik | grep -i acme
# "unable to generate a certificate ... 403" → doğrulama sunucuya ulaşamıyor
# "acme: error presenting token" → 80 portu kapalı ya da başka servis dinliyor
Let's Encrypt limitine takılmak — Aynı alan adı için haftalık deneme hakkı sınırlıdır ve yapılandırmayı deneme yanılma ile düzeltmeye çalışırken bu limit çabuk tükenir. Denemeler sırasında staging sunucusunu kullanın, çalıştığından emin olunca satırı silin:
- --certificatesresolvers.le.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
Sertifikayı kaybetmek — letsencrypt klasörünü hacim olarak bağlamayı unutursanız her docker compose down sonrası tüm sertifikalar silinir ve yeniden alınır; bu da limite giden en hızlı yoldur. Bu dizini yedek planınıza dahil edin; konteyner verilerini yedeklemeyi Docker uygulama yedekleme ve geri yükleme yazısında topluca ele aldık.
Sıkça Sorulan Sorular#
Traefik ücretsiz mi#
Traefik Proxy açık kaynaklıdır ve bu rehberde anlatılan her şey — yönlendirme, middleware, Let's Encrypt ile otomatik sertifika, dashboard — ücretsiz sürümde bulunur. Ücretli olan ayrı bir kurumsal ürün vardır; merkezi yönetim, çoklu küme ve gelişmiş erişim kontrolü gibi büyük ölçek özellikleri sunar. Tek sunucuda birkaç düzine konteyner çalıştıran bir kurulum için ücretsiz sürüm fazlasıyla yeterlidir.
Traefik mi Nginx mi kullanmalıyım#
Yapılandırmanız nadiren değişiyorsa ve zaten Nginx'e hakimseniz Nginx gayet iyi bir tercihtir. Ancak konteynerler sık sık gelip gidiyorsa, her yeni proje için proxy dosyası düzenlemek ve servisi yeniden yüklemek zamanla yorucu olur. Traefik'in avantajı yapılandırmanın uygulamanın yanında durması ve yeni servisin saniyeler içinde otomatik yayına girmesidir. Statik siteler için Nginx, sürekli değişen mikroservisler için Traefik daha rahat eder.
Sertifika yenilemeyi elle yapmam gerekir mi#
Hayır. Traefik sertifikaların süresini kendi takip eder ve bitiş tarihine yaklaşınca arka planda yeniler; ayrı bir cron görevi ya da certbot kurmanıza gerek yoktur. Sizin tek sorumluluğunuz acme.json dosyasının kalıcı bir hacimde durması ve 80 portunun dışarıya açık kalmasıdır. Bu ikisi sağlandığı sürece yenileme sessizce gerçekleşir.
Traefik dashboard'unu internete açmak güvenli mi#
Kimlik doğrulaması olmadan kesinlikle güvenli değildir; dashboard tüm servislerinizin adlarını, alan adlarını ve arka uç portlarını listeler. En azından basic auth middleware'i ekleyin, mümkünse buna IP kısıtlaması da katın. Alternatif olarak dashboard'u hiç yayımlamayıp yalnızca SSH tüneli üzerinden erişebilirsiniz; bu, üretim sunucuları için en temiz yaklaşımdır.
Aynı sunucuda hem Traefik hem Apache çalıştırabilir miyim#
İkisi aynı anda 80 ve 443 portunu dinleyemez. Apache'yi 8080 gibi bir iç porta alıp Traefik'i onun önüne koyabilirsiniz; bu durumda Apache'yi bir arka uç servisi gibi tanımlarsınız. Ancak pratikte iki katmanlı proxy fazladan karmaşıklık getirir. Sunucuda hâlihazırda çalışan bir web sunucusu varsa önce onu durdurup portları boşaltmak, sonra Traefik'i kurmak daha sağlıklıdır.
Wildcard sertifika almak için ne yapmalıyım#
HTTP-01 doğrulaması wildcard sertifika veremez; bunun için DNS-01 doğrulaması gerekir. DNS-01'de Traefik, alan adı sağlayıcınızın API'sini kullanarak geçici bir TXT kaydı oluşturur ve doğrulamayı DNS üzerinden tamamlar. Bu yüzden sağlayıcınıza ait API anahtarını ortam değişkeni olarak Traefik konteynerine vermeniz ve çözümleyiciyi dnschallenge olarak yapılandırmanız gerekir. Onlarca alt alan adınız varsa bu yöntem tek tek sertifika almaktan çok daha rahattır.
Kapanış#
Traefik'i doğru kurmanın özü aslında dört alışkanlıkta toplanıyor: proxy ve uygulamaların paylaştığı tek bir harici ağ oluşturmak, exposedbydefault=false ile hiçbir konteyneri kazara yayımlamamak, acme.json dosyasını 600 izniyle kalıcı bir hacimde tutmak ve loadbalancer.server.port değerine her zaman konteynerin iç portunu yazmak. Bu dördünü otomatikleştirdiğinizde yeni bir proje eklemek gerçekten üç satır etiket yazmaktan ibaret hale gelir. Sorun çıktığında da ilk bakacağınız yer bellidir: docker compose logs traefik ve ardından konteynerin hangi ağda olduğu.
Traefik'i çalıştıracağınız yer tam root erişimi ve kendi güvenlik duvarı kuralları isteyen bir ortamdır; bu iş için VDS veya bulut sunucu paketlerimiz doğrudan uygundur. Kurulumu ve sonrasındaki bakımı kendiniz üstlenmek istemiyorsanız sunucu yönetimi hizmetimiz proxy katmanını, sertifika yenilemelerini ve güncellemeleri sizin yerinize takip eder. Let's Encrypt yerine kurumsal doğrulamalı bir sertifika kullanmayı düşünüyorsanız SSL sayfamızdaki seçenekler işinizi görecektir.