Let's Encrypt etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Let's Encrypt etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

18 Kasım 2025 Salı

Docker Compose ile Traefik v3, Cloudflare ve Let's Encrypt ile Otomatik Reverse Proxy Kurulumu

Giriş

Kendi sunucunuzda birden fazla web uygulamasını alan adlarıyla yönetmek, güvenli SSL sertifikalarını otomatik yenilemek ve trafik yönlendirmelerini zahmetsizce yapmak istiyorsanız, Traefik v3 sizin için biçilmiş kaftan. Bu yazıda, Docker Compose kullanarak Traefik v3 ile Cloudflare DNS ve Let’s Encrypt entegrasyonunu adım adım kuracağız. Hedefimiz: tek bir reverse proxy arkasında otomatik HTTPS, kolay yönlendirme ve minimum bakım maliyeti.

Neden Traefik v3?

Traefik, container tabanlı ortamlarda dinamik servis keşfi, otomatik TLS ve güçlü yönlendirme kurallarıyla öne çıkıyor. v3 sürümü, performans ve güvenlik iyileştirmeleri ile birlikte yapılandırma tutarlılığı sunuyor. Docker üzerinde çalışan mikro servisleriniz için exposedByDefault=false gibi güvenli varsayılanlarla ince ayar yapmak da oldukça kolay.

Önkoşullar

- Docker ve Docker Compose kurulu bir Linux sunucu (ör. Ubuntu 22.04).

- 80 ve 443 portlarının dış dünyaya açık olması.

- Alan adınız Cloudflare üzerinde yönetiliyor olmalı.

- Cloudflare üzerinde DNS düzenleme yetkisine sahip bir API Token (Zone.DNS.Edit, Zone.Read).

- Let’s Encrypt için bir e-posta adresi.

Adım 1: Cloudflare API Token oluşturun

Cloudflare hesabınızda User Profile > API Tokens > Create Token yolunu izleyin. “Edit zone DNS” şablonunu seçip alan adınızı kısıtlayın. Token’ı güvenle saklayın; birazdan docker-compose içinde kullanacağız.

Adım 2: Proje dizinini hazırlayın

Sunucuda boş bir klasör oluşturup içine docker-compose.yml ve isteğe bağlı .env dosyası yerleştireceğiz. Aşağıdaki örnek, Traefik v3’ü, Cloudflare DNS-01 challenge ile Let’s Encrypt sertifika yenilemesi yapacak şekilde hazırlar.

version: "3.8"

services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    command:
      - --api.dashboard=true
      - --providers.docker=true
      - --providers.docker.exposedByDefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - [email protected]
      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
      - --certificatesresolvers.letsencrypt.acme.dnschallenge=true
      - --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare
    ports:
      - "80:80"
      - "443:443"
    environment:
      - CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.entrypoints=web"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.routers.traefik.rule=Host(`proxy.example.com`)"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.middlewares.dashboard-auth.basicauth.users=${TRAEFIK_DASHBOARD_USER}:${TRAEFIK_DASHBOARD_HASH}"
      - "traefik.http.routers.traefik.middlewares=dashboard-auth"

  whoami:
    image: traefik/whoami:latest
    container_name: whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`demo.example.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=letsencrypt"

Yukarıdaki örnekte dashboard’ı proxy.example.com üzerinden Basic Auth ile koruyoruz. whoami servisi ise demo.example.com üzerinden otomatik TLS ile yayınlanacak. Cloudflare tarafında bu iki alt alan adını A/AAAA kaydıyla sunucunuza yönlendirin. Cloudflare “turuncu bulut” (proxy) açık olabilir; DNS-01 challenge, proxied modda da sorunsuz çalışır.

Adım 3: Ortam değişkenleri ve parola karması

.env dosyanıza aşağıdaki gibi değerleri ekleyin. Basic Auth için bir bcrypt karma gerekir. Linux’ta hızla üretmek için şu komutu kullanabilirsiniz: htpasswd -nbB admin 'Sifre123' çıktısındaki admin:$2y$... kısmını kopyalayın.

CF_DNS_API_TOKEN=cf_api_tokeniniz_buraya
TRAEFIK_DASHBOARD_USER=admin
TRAEFIK_DASHBOARD_HASH=$2y$05$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Adım 4: Servisleri başlatın

Klasörde docker compose up -d komutunu çalıştırın. İlk kurulumda Let’s Encrypt DNS-01 challenge ile TXT kaydı oluşturup doğrulama yapar ve acme.json içine sertifikaları yazar. Ardından https://demo.example.com adresini açtığınızda whoami çıktısını, https://proxy.example.com adresini açtığınızda ise kimlik doğrulama sonrası Traefik dashboard’ını görmelisiniz.

İpuçları ve iyi uygulamalar

- letsencrypt klasörünün izinlerini 600 veya 700 seviyesinde tutun; acme.json hassas bilgiler içerir.

- production ortamında traefik konteynerinin yalnızca ihtiyaç duyduğu ağlara eriştiğinden emin olun; Docker network’leri ile segmentasyon yapın.

- Rate limitlere takılmamak için Let’s Encrypt’in staging ortamını testlerde kullanabilirsiniz: --certificatesresolvers.letsencrypt.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory parametresini ekleyip denemeler tamamlanınca kaldırın.

- Cloudflare’de DNSSEC aktifse, zone yapılandırmanızın doğru olduğundan emin olun; yanlış DS kayıtları çözümleme sorunlarına neden olabilir.

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

- Giriş başarısız: CF_DNS_API_TOKEN yetkileri eksik olabilir. Token’a Zone.DNS.Edit ve Zone.Read sağlandığından ve doğru zone’da sınırlandığından emin olun.

- Sertifika alınamıyor: Alan adınız doğru IP’ye işaret ediyor mu? DNS yayılımı tamamlandı mı? Ayrıca Cloudflare’de CNAME flattening ayarları bazen beklenmedik davranışlar gösterebilir; A kaydıyla test etmek daha sağlıklıdır.

- 404 veya yönlendirme döngüsü: http-catchall ve redirect-to-https etiketlerinin çakışmadığından emin olun. Aynı ana bilgisayar için hem http hem https router tanımlarını kontrol edin.

Sonuç

Bu kurulumla Docker tabanlı servisleriniz için modern, güvenli ve otomatik bir reverse proxy katmanı elde ettiniz. Traefik v3, Cloudflare DNS-01 ve Let’s Encrypt birleşimi; mikro servislerinizi hızlıca yayına almanızı, sertifikaları otomatik yenilemeyi ve tek noktadan görünürlük sağlamayı mümkün kılıyor. Bundan sonra yeni bir servis eklemek yalnızca birkaç label yazmak kadar basit. Üstelik, aynı mimariyi staging ve production çevrelerinde tekrar kullanarak sürdürülebilir bir dağıtım modeli kurabilirsiniz.

20 Ekim 2025 Pazartesi

Traefik v3 ile Docker Compose Üzerinde Çoklu Alan Adı ve Otomatik SSL: Adım Adım Rehber

Bir sunucuda birden fazla web uygulamasını farklı alan adlarıyla güvenli (HTTPS) şekilde yayınlamak istiyorsanız, modern bir ters proxy çözümü olan Traefik v3 harika bir seçenek. Bu rehberde, Docker Compose kullanarak Traefik v3 ile otomatik Let’s Encrypt sertifika yönetimini, HTTP’den HTTPS’e yönlendirmeyi ve birden fazla alan adını tek yapılandırmada yönetmeyi adım adım göstereceğim.

Traefik v3 nedir ve neden tercih edilmeli?

Traefik v3, konteyner tabanlı mimariler için optimize edilmiş, otomatik keşif ve sade etiketleme (label) mantığıyla çalışan bir ters proxy ve yük dengeleyicidir. Docker, Kubernetes ve diğer sağlayıcılarla derin entegrasyon sunar. v3 sürümü, performans ve yapılandırma deneyiminde iyileştirmeler getirirken, Let’s Encrypt ile otomatik TLS/SSL sertifikalandırmayı pratik hale getirir.

Ön koşullar ve DNS

- Bir Linux sunucu (Ubuntu/Debian/CentOS vb.)

- Docker ve Docker Compose kurulu

- Alan adınızda, sunucunuzun IP adresine işaret eden A/AAAA kayıtları (örnek: app.example.com ve traefik.example.com)

İpucu: Cloudflare kullanıyorsanız ve HTTP-01 doğrulaması yapacaksanız, ilgili DNS kaydını “DNS only” (turuncu bulut kapalı) olarak ayarlayın; aksi halde Let’s Encrypt doğrulaması başarısız olabilir.

Adım 1: Docker ağı ve klasörler

Aşağıdaki ağ, farklı Compose dosyaları arasında servisleri paylaşmanızı sağlar. Oluşturun:

docker network create web
mkdir -p traefik/letsencrypt
touch traefik/letsencrypt/acme.json
chmod 600 traefik/letsencrypt/acme.json

Adım 2: Traefik v3 için docker-compose.yml

Aşağıdaki dosya, Traefik’i 80/443 portlarına bağlar, Let’s Encrypt’i HTTP-01 ile etkinleştirir, HTTP’yi otomatik olarak HTTPS’e yönlendirir ve güvenli bir kontrol paneli kurar. E-postayı ve alan adlarını kendinize göre düzenlemeyi unutmayın.

version: "3.8"

services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entrypoints.web.http.redirections.entrypoint.scheme=https
      - [email protected]
      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
      - --certificatesresolvers.letsencrypt.acme.httpchallenge=true
      - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
      - --api.dashboard=true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/letsencrypt:/letsencrypt
    networks:
      - web
    labels:
      - "traefik.enable=true"
      # Dashboard için güvenli router
      - "traefik.http.routers.api.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.api.service=api@internal"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"
      # Basit BasicAuth middleware (parolayı hashleyip $$ ile kaçırın)
      - "traefik.http.middlewares.basicauth.basicauth.users=admin:$$2y$$12$$REPLACE_WITH_YOUR_BCRYPT_HASH"
      - "traefik.http.routers.api.middlewares=basicauth@docker"

  # Örnek uygulama
  whoami:
    image: traefik/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`app.example.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
    networks:
      - web

networks:
  web:
    external: true

Bu dosyada iki önemli nokta var: “exposedbydefault=false” etiketsiz konteynerların dış dünyaya açılmasını engeller; “http redirections” ise tüm HTTP trafiğini otomatik olarak HTTPS’e taşır. Dashboard’ı traefik.example.com üzerinden basit bir BasicAuth ile koruyoruz. Parola hash’ini üretmek için şu komutlardan birini kullanabilirsiniz:

# OpenSSL ile bcrypt:
htpasswd -nbB admin SIFRENIZ

# Ya da Python:
python3 -c "import bcrypt; print(b'admin:' + bcrypt.hashpw(b'SIFRENIZ', bcrypt.gensalt()))"

Elde ettiğiniz hash’i compose dosyasına yapıştırırken $ karakterlerini $$ ile kaçırın; aksi halde Compose bunu çevresel değişken sanacaktır.

Adım 3: Servis ekleme ve çoklu alan adı

Yeni bir servis eklemek için ilgili konteynere “traefik.enable=true” etiketi ve “rule=Host(`sub.example.com`)" kuralı tanımlayın. Her servis için ayrı router, entrypoint ve TLS resolver atayabilirsiniz. Örneğin bir Node.js uygulaması için:

myapp:
  image: node:20-alpine
  working_dir: /app
  command: ["node", "server.js"]
  volumes:
    - ./myapp:/app
  labels:
    - "traefik.enable=true"
    - "traefik.http.routers.myapp.rule=Host(`api.example.com`)"
    - "traefik.http.routers.myapp.entrypoints=websecure"
    - "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
  networks:
    - web

Statik dosya sunucuları, PHP-FPM arkasındaki Nginx veya Go/Rust uygulamaları da benzer şekilde etiketlenir. Tüm servisler aynı “web” ağına bağlı oldukça Traefik onları otomatik keşfeder.

Güvenlik ve en iyi uygulamalar

- Dashboard’ı mutlaka alt alan adı ve BasicAuth (veya IP kısıtlaması) ile koruyun.

- “acme.json” dosyasını 600 izinleriyle saklayın; sertifika anahtarları bu dosyada tutulur.

- Gereksiz portları açmayın; yalnızca 80 ve 443 çoğu kurulum için yeterlidir.

- Üretimde otomatik yeniden başlatma politikası (“restart: unless-stopped”) kullanabilirsiniz.

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

- Sertifika alınamadı: DNS kayıtlarınız doğru mu? Cloudflare “proxied” açık mı? HTTP-01 için kapalı olmalı. Alternatif olarak DNS-01 challenge kullanarak wildcard (*.example.com) alabilirsiniz.

- 80/443 dinlenemiyor: Sunucuda bu portları kullanan farklı bir servis (ör. Nginx) çalışıyor olabilir. Kapatın veya taşıyın.

- Rate limit: Let’s Encrypt test sırasında üretim yerine staging sunucularını deneyin. Traefik için “acme.caserver” parametresiyle staging’e geçebilirsiniz.

- “acme.json permission denied”: Dosya izinlerini 600 yapın ve doğru mount yolunu kontrol edin.

Sonuç

Traefik v3 ve Docker Compose ile çok sayıda servisi tek bir sunucu üzerinde, otomatik SSL ve modern yönlendirme yetenekleriyle dakikalar içinde yayına alabilirsiniz. Etiket tabanlı mimari, CI/CD süreçlerine rahatça entegre olurken, yeniden başlatma ihtiyacı olmadan konfigürasyon değişikliklerini devreye almanızı sağlar. Üstelik ölçeklenebilir ve gözlemlenebilir bir altyapının temelini atmış olursunuz.