Docker & DevOps

    Caddy ile Otomatik HTTPS

    Caddy'yi kurup tek satırlık Caddyfile ile otomatik sertifikalı bir web sunucusu elde etmenin rehberi.

    10 dk okuma Güncellendi: 25 Ağustos 2026

    Bir web sunucusunu HTTPS ile yayına almak uzun yıllar şu adımların toplamıydı: sertifika iste, doğrulama dosyasını yerleştir, sertifikayı indir, sunucu yapılandırmasına yolunu yaz, yönlendirmeyi kur, cron ile yenilemeyi ayarla ve yenilemenin çalıştığını üç ayda bir kontrol et. Caddy'nin varlık sebebi tam olarak bu listeyi silmektir: Caddy'de otomatik HTTPS varsayılan davranıştır, kapatmak için özel çaba gerekir. Yapılandırma dosyanıza bir alan adı yazarsınız, Caddy sertifikayı kendisi alır, kendisi kurar, süresi dolmadan kendisi yeniler ve HTTP'den HTTPS'e yönlendirmeyi kendiliğinden ekler.

    Bu rehberde Caddy'yi hem doğrudan sisteme hem Docker ile kurmayı, Caddyfile'ın dilbilgisini, ters proxy ve PHP-FPM senaryolarını, iç ağ ve wildcard sertifika durumlarını ele alacağız. Ayrıca "otomatik" kelimesinin gizlediği birkaç şartı — 80 portunun açık olması, DNS'in doğru olması, sertifika deposunun kalıcı olması — ve bunlar sağlanmadığında karşılaşacağınız hataları da tek tek göreceğiz.

    Caddy'nin Otomatik HTTPS Mantığı#

    Caddy başlarken yapılandırmanızdaki alan adlarını toplar ve her biri için geçerli bir sertifikası olup olmadığına bakar. Yoksa ACME protokolüyle bir sertifika otoritesine başvurur; varsayılan olarak önce Let's Encrypt'i dener, başarısız olursa ZeroSSL'e geçer. Doğrulama için 80 portundan HTTP-01 ya da 443 portundan TLS-ALPN-01 kullanır. Sertifika alındıktan sonra bunu veri dizinine yazar ve süresinin üçte biri kaldığında arka planda sessizce yeniler.

    Bu davranışın pratik sonucu şudur: yapılandırmanızda alan adı yerine IP adresi ya da localhost yazarsanız Caddy HTTPS'i açmaz (çünkü ACME bir IP'ye herkese güvenilir sertifika vermez), fakat yerel geliştirme için kendi ürettiği bir kök sertifikayla iç HTTPS sağlar. Yani "neden sertifika almadı" sorusunun cevabı çoğu zaman yapılandırmadaki adresin biçimindedir.

    Adres yazımıSonuçKullanım
    firmaniz.comGenel güvenilir sertifika alınırÜretim
    :80HTTP, sertifika yokYük dengeleyici arkası
    localhostYerel kök ile HTTPSGeliştirme
    http://firmaniz.comHTTPS zorla kapatılırÖzel durumlar
    *.firmaniz.comDNS doğrulaması gerekirWildcard

    Caddy'yi Nginx ve Apache ile karşılaştırmak isterseniz, mimari farkların ne anlama geldiğini Apache ve Nginx karşılaştırması yazısında ele almıştık; Caddy bu iki geleneksel sunucunun yapılandırma yükünü azaltmayı hedefleyen daha yeni bir yaklaşımdır.

    Kurulum: Paket Deposu ve Docker Seçenekleri#

    Debian ve Ubuntu üzerinde resmi paket deposundan kurmak en temiz yoldur; bu yöntemde systemd servisi ve caddy kullanıcısı otomatik oluşur:

    # Gerekli araçlar
    apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
    
    # Depo anahtarını ekle
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
      | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
    
    # Depoyu tanımla ve kur
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
      | tee /etc/apt/sources.list.d/caddy-stable.list
    apt update && apt install caddy
    
    # Servis durumu
    systemctl status caddy
    

    Docker tarafında ise tek konteyner yeterlidir. Kritik nokta, /data dizinini kalıcı bir hacme bağlamaktır; sertifikalar orada saklanır ve bu hacim yoksa her yeniden oluşturmada sertifika yeniden istenir, bu da otoritenin haftalık limitine takılmanıza yol açar:

    services:
      caddy:
        image: caddy:2-alpine
        container_name: caddy
        restart: unless-stopped
        ports:
          - "80:80"
          - "443:443"
          - "443:443/udp"   # HTTP/3 için
        volumes:
          - ./Caddyfile:/etc/caddy/Caddyfile:ro
          - caddy_data:/data      # SERTİFİKALAR burada, kaybetmeyin
          - caddy_config:/config
          - ./site:/srv           # statik dosyalar
    volumes:
      caddy_data:
      caddy_config:
    

    Kurulumdan sonra yapılandırmayı her değiştirdiğinizde servisi yeniden başlatmanıza gerek yoktur; Caddy sıcak yeniden yükleme (graceful reload) yapar ve açık bağlantılar kopmaz:

    # Sözdizimi kontrolü ve biçimlendirme
    caddy fmt --overwrite /etc/caddy/Caddyfile
    caddy validate --config /etc/caddy/Caddyfile
    
    # Kesintisiz yeniden yükleme
    systemctl reload caddy
    # Docker kurulumunda:
    docker exec -w /etc/caddy caddy caddy reload
    

    Caddyfile Anatomisi: En Sade Yapılandırma#

    Caddyfile, blok başlığında adresi ve içinde direktifleri barındıran basit bir yapıya sahiptir. En küçük çalışan örnek iki satırdır ve bu iki satır size HTTPS'li, HTTP/2 ve HTTP/3 destekli, otomatik yenilenen bir siteyi getirir:

    firmaniz.com {
    	root * /srv
    	file_server
    }
    

    Birden fazla site tanımlamak için blokları alt alta yazarsınız. Ortak ayarlar için dosyanın en başına global blok konur:

    {
    	# Sertifika bildirimlerinin gideceği adres
    	email [email protected]
    	# Yerel testte staging otoritesi kullanmak için:
    	# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
    }
    
    firmaniz.com, www.firmaniz.com {
    	root * /srv/site
    	encode gzip zstd
    	file_server
    	# Güvenlik başlıkları
    	header {
    		Strict-Transport-Security "max-age=31536000"
    		X-Content-Type-Options "nosniff"
    		X-Frame-Options "DENY"
    		-Server
    	}
    }
    
    api.firmaniz.com {
    	reverse_proxy 127.0.0.1:3000
    }
    

    Dikkat edilecek üç ayrıntı var. Birincisi, Caddyfile girintilerde sekme kullanmayı sever; caddy fmt komutu dosyayı standart biçime çeker ve garip ayrıştırma hatalarının çoğunu ortadan kaldırır. İkincisi, -Server satırı yanıt başlığından sunucu bilgisini siler. Üçüncüsü, virgülle ayrılmış birden fazla alan adı yazdığınızda Caddy her biri için ayrı sertifika alır ve hepsini aynı blokla sunar.

    Ters Proxy, PHP-FPM ve Statik Site Örnekleri#

    Caddy'nin en sık kullanıldığı senaryo bir uygulamanın önünde durmaktır. reverse_proxy direktifi tek satırda bunu halleder ve gerekli başlıkları (X-Forwarded-For, X-Forwarded-Proto) kendiliğinden ekler — Nginx'te elle yazmanız gereken satırlar Caddy'de varsayılandır:

    uygulama.firmaniz.com {
    	# Docker ağındaki bir konteynere yönlendirme
    	reverse_proxy web-uygulamasi:3000 {
    		# Sağlık kontrolü ile ölü arka ucu devre dışı bırak
    		health_uri /health
    		health_interval 10s
    	}
    }
    
    # Birden fazla arka uç: basit yük dağıtımı
    yuk.firmaniz.com {
    	reverse_proxy app1:3000 app2:3000 app3:3000 {
    		lb_policy round_robin
    	}
    }
    

    PHP tabanlı bir uygulama için php_fastcgi direktifi, Nginx'te on beş satır tutan fastcgi_param bloğunu tek satıra indirir. WordPress, Laravel ve benzeri uygulamalarda ön denetleyici (front controller) yönlendirmesi de otomatik yapılır:

    firmaniz.com {
    	root * /var/www/firmaniz/public
    	# PHP-FPM soketi ya da TCP adresi
    	php_fastcgi unix//run/php/php-fpm.sock
    	file_server
    	# Yükleme boyutu ve zaman aşımı
    	request_body {
    		max_size 64MB
    	}
    }
    

    Docker ortamında PHP-FPM'i ayrı konteyner olarak çalıştırıyorsanız soket yerine ağ adresi verirsiniz: php_fastcgi php:9000. Bu mimarinin ayrıntılarını ve dosya paylaşımının nasıl kurulacağını Docker'da Nginx ve PHP-FPM yığını yazısında ele aldık; oradaki mantık Caddy için de aynen geçerlidir, yalnızca web sunucusu katmanı değişir.

    Tek sayfalık uygulamalar (React, Vue) için istemci tarafı yönlendirmeyi desteklemek gerekir; aksi halde /panel/ayarlar gibi bir adrese doğrudan girildiğinde 404 alırsınız:

    panel.firmaniz.com {
    	root * /srv/dist
    	encode gzip
    	try_files {path} /index.html
    	file_server
    }
    

    Sertifika Yönetimi: Wildcard, İç Ağ ve Kendi Sertifikanız#

    Wildcard sertifika (*.firmaniz.com) HTTP doğrulamasıyla alınamaz; DNS doğrulaması gerekir ve bunun için DNS sağlayıcınızın eklentisiyle derlenmiş bir Caddy binary'si kullanırsınız. xcaddy aracıyla eklentili sürüm derlenir ya da resmi imajın eklentili varyantı kullanılır. Yapılandırma tarafı ise şuna benzer:

    *.firmaniz.com {
    	tls {
    		dns saglayici_adi {env.DNS_API_TOKEN}
    	}
    	reverse_proxy 127.0.0.1:8080
    }
    

    İç ağda, internete açık olmayan bir servis için genel sertifika alınamaz. Bu durumda Caddy'nin kendi kök otoritesini kullanabilir ya da elinizdeki sertifikayı doğrudan gösterebilirsiniz:

    # Kendi sertifikanızı kullanmak
    guvenli.firmaniz.com {
    	tls /etc/ssl/certs/firmaniz.crt /etc/ssl/private/firmaniz.key
    	reverse_proxy 127.0.0.1:9000
    }
    
    # Sertifikayı tamamen kapatmak (yük dengeleyici arkası)
    http://ic-servis.firmaniz.com {
    	reverse_proxy 127.0.0.1:9000
    }
    

    Sertifika dosyalarının nerede tutulduğunu bilmek yedekleme açısından önemlidir. Paket kurulumunda genellikle /var/lib/caddy/.local/share/caddy, Docker'da ise /data/caddy altındadır. Bu dizini yedeklemek, sunucuyu taşırken yeni sertifika istememenizi sağlar. Ticari doğrulamalı bir sertifikaya ihtiyacınız varsa SSL sayfamızdaki kurumsal seçenekleri inceleyebilirsiniz; Caddy bu sertifikaları da tls direktifiyle sorunsuz kullanır.

    Loglama, Metrikler ve Günlük Bakım#

    Caddy varsayılan olarak erişim loglarını dosyaya yazmaz; yalnızca hata ve süreç loglarını standart çıktıya verir. Trafik analizi ya da saldırı incelemesi yapacaksanız erişim logunu açıkça etkinleştirmeniz gerekir. Log biçimi olarak JSON kullanmak, sonradan jq gibi araçlarla filtrelemeyi kolaylaştırır:

    firmaniz.com {
    	log {
    		output file /var/log/caddy/firmaniz.log {
    			roll_size 50MiB
    			roll_keep 10
    		}
    		format json
    		level INFO
    	}
    	reverse_proxy 127.0.0.1:3000
    }
    

    roll_size ve roll_keep değerleri log dosyasının diski doldurmasını engeller; Caddy dosya belirli boyuta ulaşınca kendisi döndürür, ayrıca logrotate kurmanıza gerek kalmaz. Logu okurken en çok işinize yarayacak iki alan status ve duration olacaktır:

    # Son 200 istekten 5xx dönenleri listele
    tail -n 200 /var/log/caddy/firmaniz.log | jq 'select(.status >= 500) | {ts, request: .request.uri, status}'
    
    # En yavaş 10 isteği bul
    jq -s 'sort_by(-.duration) | .[0:10] | .[] | {uri: .request.uri, duration}' /var/log/caddy/firmaniz.log
    

    Sürüm yükseltmesi de gündelik bakımın parçasıdır. Paket kurulumunda apt upgrade caddy yeterlidir ve servis yeniden başlatıldığında açık bağlantılar nazikçe kapatılır. Docker kurulumunda imaj etiketini sabitlemek (caddy:2-alpine yerine belirli bir sürüm) beklenmedik davranış değişikliklerinin önüne geçer; yükseltmeden önce yapılandırmayı caddy validate ile yeni sürümde doğrulamak iyi bir alışkanlıktır.

    Sık Yapılan Hatalar ve Sorun Giderme#

    "could not get certificate" hatası — Neredeyse her zaman doğrulama trafiğinin sunucuya ulaşamamasıdır. 80 portunun dışarıdan erişilebilir olduğunu (ss -ltnp | grep :80), alan adının A kaydının bu sunucuyu gösterdiğini ve güvenlik duvarında engel olmadığını doğrulayın. Ayrıntılı hata mesajı için logu okuyun:

    journalctl -u caddy --no-pager -n 100 | grep -i "certificate\|acme"
    # Docker: docker logs caddy 2>&1 | grep -i acme
    

    Sertifika limitine takılmak — Yapılandırmayı deneme yanılma ile düzeltirken aynı alan adı için tekrar tekrar sertifika istemek, otoritenin haftalık sınırını tüketir. Denemeler sırasında global bloktaki acme_ca satırıyla staging otoritesine geçin; tarayıcı uyarı verir ama akış aynen test edilir. Çalıştığından emin olduktan sonra satırı silip veri dizinini temizleyin.

    Docker'da her yeniden başlatmada yeni sertifika/data hacmi bağlanmamıştır. Konteyner silindiğinde sertifikalar da gider. Compose dosyasında adlandırılmış bir hacim tanımlayıp /data yolunu ona bağlayın; bu tek satır, limit sorununun da kökünü kazır.

    Yapılandırma değişikliği etkisizreload yerine dosyayı düzenleyip beklemek işe yaramaz. Ayrıca Caddy, JSON yapılandırmasını bir kez API üzerinden aldıysa Caddyfile'ı yok sayabilir. Hangi yapılandırmanın etkin olduğunu görmek için yönetim API'sini sorgulayın:

    curl -s localhost:2019/config/ | head -40
    

    Yönlendirme döngüsü — Arka uçtaki uygulama kendi başına HTTPS'e yönlendiriyorsa ve Caddy ona HTTP ile bağlanıyorsa döngü oluşur. Uygulamayı proxy arkasında çalıştığını bilecek şekilde ayarlayın; Caddy X-Forwarded-Proto başlığını zaten gönderir, uygulamanın bu başlığa güvenmesini etkinleştirmeniz yeterlidir.

    80 portunu kapatmak — Güvenlik gerekçesiyle 80'i kapatan kurulumlarda HTTP-01 doğrulaması çalışmaz. TLS-ALPN-01 doğrulaması 443 üzerinden çalışabilir, ama en sağlam çözüm DNS doğrulamasına geçmektir. 80'i tamamen kapatmadan önce sertifika yenilemesinin hangi yöntemi kullandığını bilin.

    Sıkça Sorulan Sorular#

    Caddy gerçekten hiçbir ayar yapmadan HTTPS açıyor mu#

    Neredeyse. Şartlar şunlardır: yapılandırmada IP değil alan adı yazmış olmanız, o alan adının DNS'inin sunucunuza bakması ve 80 ya da 443 portundan doğrulama trafiğinin geçebilmesi. Bu üçü sağlandığında Caddy başlar başlamaz sertifikayı alır ve HTTP'yi HTTPS'e yönlendirir; sizin ayrıca bir satır yazmanıza gerek kalmaz. Şartlardan biri eksikse sertifika alınmaz ve log dosyasında sebebini açıkça yazar.

    Caddy Nginx'ten yavaş mı#

    Gerçek dünya yüklerinde ikisi arasındaki fark, uygulamanızın kendi gecikmesinin yanında genellikle önemsiz kalır. Nginx çok yüksek eşzamanlı statik dosya servisinde biraz daha ekonomik davranabilir, Caddy ise varsayılan olarak HTTP/3 ve modern TLS ayarlarıyla gelir. Seçimi performans yerine yapılandırma rahatlığı ve ekibin aşinalığı üzerinden yapmak daha doğrudur.

    Caddy ücretsiz mi, ticari kullanımda lisans gerekir mi#

    Caddy açık kaynaklıdır ve ticari kullanım dahil ücretsizdir. Resmi binary'yi indirip müşteri projelerinde kullanmanızın önünde bir engel yoktur. Ticari destek satan bir şirket vardır ama yazılımın kendisini kullanmak için ödeme ya da lisans anahtarı gerekmez.

    Caddyfile'ı mı JSON yapılandırmasını mı kullanmalıyım#

    Elle yazacaksanız kesinlikle Caddyfile; okunması ve bakımı çok daha kolaydır. JSON biçimi, yapılandırmayı programatik olarak üreten sistemler ve yönetim API'si üzerinden anlık değişiklik yapan araçlar içindir. Caddy Caddyfile'ı zaten arka planda JSON'a çevirir, yani ikisi arasında yetenek farkı değil kullanım kolaylığı farkı vardır.

    Mevcut Nginx yapılandırmamı Caddy'ye nasıl taşırım#

    Otomatik bir dönüştürücüye güvenmek yerine site site elden geçirmek daha sağlıklıdır, çünkü Caddy'de çoğu satırın karşılığı yoktur — gerek kalmaz. Tipik bir Nginx server bloğu Caddy'de üç beş satıra iner: adres, root, file_server veya reverse_proxy. Geçişi yaparken eski sunucuyu farklı bir portta çalışır durumda tutup Caddy'yi test edin, doğruladıktan sonra portları değiştirin.

    Caddy ile yönlendirme kuralı nasıl yazılır#

    redir direktifi tek satırda kalıcı ya da geçici yönlendirme kurar; örneğin redir /eski-sayfa /yeni-sayfa permanent biçiminde. Alan adı düzeyinde yönlendirme için ayrı bir blok açıp içine tek satır redir https://firmaniz.com{uri} permanent yazmanız yeterlidir. Apache alışkanlığıyla kural üretmek isterseniz htaccess yönlendirme üretici aracımızla mantığı kurup Caddy karşılığına çevirebilirsiniz.

    Kapanış#

    Caddy'nin sunduğu kolaylıktan tam olarak yararlanmak için akılda tutulacaklar sade: yapılandırmaya IP değil alan adı yazın, sertifika deposunu (/data ya da /var/lib/caddy) kalıcı tutup yedekleyin, denemeleri staging otoritesiyle yapıp limit yakmayın ve her değişiklikten sonra caddy validate ile reload ikilisini alışkanlık haline getirin. Bu dördü yerindeyse Caddy gerçekten arka planda unutulan bir bileşene dönüşür.

    Kendi web sunucunuzu kurup yönetmek için tam root erişimi gerekir; VDS ve bulut sunucu paketlerimiz bu iş için doğrudan uygundur. Sertifikalar, güvenlik duvarı ve düzenli güncellemelerle uğraşmak istemiyorsanız sunucu yönetimi hizmetimiz bu bakımı üstlenir; mevcut sitenizi yeni bir sunucuya taşıyacaksanız site taşıma hizmetimiz DNS ve sertifika geçişini de kapsar.

    CaddyHTTPSWeb Sunucusu

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.