Modern web altyapısında Nginx ve Apache’nin yanına güçlü bir rakip çıktı: Caddy. Go diliyle yazılmış bu web sunucusu, otomatik HTTPS, sıfır bağımlılık ve son derece sade yapılandırma dosyasıyla sistem yöneticilerinin hayatını ciddi ölçüde kolaylaştırıyor. Özellikle Let’s Encrypt sertifikalarını elle uğraşmadan otomatik alan adı doğrulamasıyla yönetmesi, Caddy’yi production ortamlarında bile tercih edilen bir çözüm haline getiriyor. Bu yazıda Caddy’yi sıfırdan kuracak, Caddyfile sözdizimini öğrenecek ve gerçek dünya senaryolarıyla yapılandırmayı kavrayacağız.
Caddy Nedir ve Neden Kullanılır?
Caddy, 2015 yılında Matt Holt tarafından geliştirilen, Go ile yazılmış modern bir web sunucusudur. Klasik web sunucularından en temel farkı otomatik TLS özelliğidir. Nginx veya Apache’de HTTPS kurmak için certbot kurmanız, cron job yazmanız, sertifika yenileme süreçlerini takip etmeniz gerekir. Caddy’de ise alan adınızı Caddyfile’a yazmanız yeterli; gerisini Caddy halleder.
Caddy’nin öne çıkan özellikleri şunlardır:
- Otomatik HTTPS: Let’s Encrypt ve ZeroSSL üzerinden sertifika alır, yeniler, yönetir
- HTTP/2 ve HTTP/3 desteği: Kutudan çıkar çıkmaz aktif gelir
- Sade yapılandırma dili: Caddyfile, Nginx config’e kıyasla çok daha okunabilir
- API tabanlı yönetim: JSON API üzerinden dinamik yapılandırma değiştirme imkanı
- Tek binary: Hiçbir bağımlılık yok, tek dosya kurulum
- Reverse proxy, yük dengeleme, dosya sunumu: Hepsi dahili modüller olarak geliyor
Küçük projelerde, hobi sunucularında veya hızlı prototip ortamlarında Caddy neredeyse rakipsiz. Büyük ölçekli yapılarda da özellikle HTTPS yönetimi açısından ciddi avantaj sağlıyor.
Kurulum
Ubuntu/Debian Üzerine Kurulum
Caddy’nin resmi APT deposunu sisteme ekleyerek kurulum yapabilirsiniz. Bu yöntemle hem kurulum hem de gelecekteki güncellemeler sorunsuz yönetilir.
# Gerekli paketleri kur
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
# Caddy GPG anahtarını ekle
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key'
| sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
# APT deposunu ekle
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt'
| sudo tee /etc/apt/sources.list.d/caddy-stable.list
# Caddy'yi kur
sudo apt update && sudo apt install caddy
Kurulumun ardından Caddy servisi otomatik olarak başlar ve /etc/caddy/Caddyfile dosyası oluşturulur.
RHEL/CentOS/Rocky Linux Üzerine Kurulum
# COPR deposunu etkinleştir
dnf copr enable @caddy/caddy
# Caddy'yi kur
dnf install caddy
# Servisi başlat ve sistem açılışında otomatik başlasın
systemctl enable --now caddy
Binary ile Manuel Kurulum
Daha fazla kontrol isteyenler veya özel bir Caddy sürümü kullananlar için manuel kurulum seçeneği de var:
# GitHub releases sayfasından en son sürümü indir
curl -L "https://github.com/caddyserver/caddy/releases/latest/download/caddy_linux_amd64.tar.gz"
-o caddy.tar.gz
# Arşivi aç
tar -xzf caddy.tar.gz
# Binary'yi sistem dizinine taşı
sudo mv caddy /usr/local/bin/
sudo chmod +x /usr/local/bin/caddy
# Caddy kullanıcısını oluştur
sudo useradd --system --home /var/lib/caddy --shell /usr/sbin/nologin caddy
# Gerekli dizinleri oluştur
sudo mkdir -p /etc/caddy /var/lib/caddy /var/log/caddy
sudo chown -R caddy:caddy /var/lib/caddy /var/log/caddy
Kurulum Doğrulama
# Caddy sürümünü kontrol et
caddy version
# Servis durumunu kontrol et
sudo systemctl status caddy
# Portu dinleyip dinlemediğini kontrol et
ss -tlnp | grep caddy
Caddyfile Sözdizimi
Caddy’nin yapılandırma dosyası olan Caddyfile, minimal ve anlaşılır bir sözdizime sahip. Temel yapı şu şekilde:
alan_adi {
direktif parametreler
}
Temel Statik Dosya Sunumu
En basit kullanım senaryosu: bir dizini web üzerinden sunmak.
# /etc/caddy/Caddyfile
example.com {
root * /var/www/html
file_server
}
Bu kadar. Caddy bu yapılandırmayı gördüğünde otomatik olarak Let’s Encrypt’ten SSL sertifikası alır, HTTP’yi HTTPS’e yönlendirir ve /var/www/html dizinini sunar.
Localhost üzerinde geliştirme yaparken ise Caddy kendi kendine imzalı sertifika üretir:
localhost:8080 {
root * /home/kullanici/proje/public
file_server
}
Reverse Proxy Yapılandırması
En sık kullanılan senaryo budur. Arkada çalışan bir Node.js, Python veya başka bir uygulama için Caddy’yi önüne proxy olarak koyuyorsunuz:
api.example.com {
reverse_proxy localhost:3000
}
Birden fazla backend instance’ı varsa yük dengeleme de dahili olarak çalışır:
api.example.com {
reverse_proxy localhost:3000 localhost:3001 localhost:3002
}
Caddy varsayılan olarak round-robin algoritmasıyla dağıtım yapar. İsterseniz bunu değiştirebilirsiniz:
api.example.com {
reverse_proxy {
to localhost:3000 localhost:3001
lb_policy least_conn
health_uri /health
health_interval 10s
}
}
lb_policy için kullanılabilir değerler:
- round_robin: Sıralı dağıtım (varsayılan)
- least_conn: En az bağlantıya sahip sunucuya yönlendir
- ip_hash: İstemci IP’ye göre sabit yönlendirme
- random: Rastgele seçim
Gerçek Dünya Senaryoları
Senaryo 1: WordPress Sitesi + PHP-FPM
Bir müşteri için shared hosting yerine VPS üzerinde WordPress kuracaksınız. PHP-FPM zaten çalışıyor, MySQL hazır. Sadece Caddy yapılandırması lazım:
wordpress.musteri.com {
root * /var/www/wordpress
# PHP dosyalarını PHP-FPM'e gönder
php_fastcgi unix//run/php/php8.1-fpm.sock
# Statik dosyaları doğrudan sun
file_server
# WordPress için gerekli yönlendirmeler
@notFound {
not file
not path /wp-admin/*
}
rewrite @notFound /index.php
# Hassas dosyalara erişimi engelle
@sensitive {
path /.git/* /wp-config.php /.env
}
respond @sensitive 403
# Gzip sıkıştırma
encode gzip
# Erişim logları
log {
output file /var/log/caddy/wordpress.log
format json
}
}
Bu yapılandırma ile:
- Otomatik HTTPS aktif
- PHP sayfaları PHP-FPM’e yönlendiriliyor
- Hassas dosyalar korunuyor
- Yanıtlar sıkıştırılıyor
- JSON formatında erişim logu tutuluyor
Senaryo 2: Mikro Servis Mimarisi
Farklı portlarda çalışan birkaç servisi tek alan adı altında toplamak istiyorsunuz:
app.example.com {
# /api/* isteklerini backend servise gönder
handle /api/* {
reverse_proxy localhost:8080
}
# /auth/* isteklerini kimlik doğrulama servisine gönder
handle /auth/* {
reverse_proxy localhost:8081
}
# /uploads/* için doğrudan dosya servisi
handle /uploads/* {
root * /var/www
file_server
}
# Gerisi React uygulaması
handle {
root * /var/www/frontend/build
file_server
try_files {path} /index.html
}
encode gzip zstd
}
try_files direktifi burada kritik: React gibi SPA uygulamalarında client-side routing için her 404’ü index.html’e yönlendirmek gerekir.
Senaryo 3: Temel HTTP Kimlik Doğrulama
Bir iç araç veya staging ortamı için basit parola koruması eklemek:
# Önce bcrypt ile parola hash'i oluştur
caddy hash-password --plaintext "gizliparola123"
Çıktı olarak bir hash string alacaksınız. Bunu Caddyfile’a ekleyin:
staging.example.com {
reverse_proxy localhost:4000
basicauth /* {
admin $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNmpkT/5qqR7hx4IjWJPDhjvC
developer $2a$14$abc123...
}
}
Senaryo 4: Subdomain Wildcard ve Çoklu Site
Aynı sunucuda onlarca siteniz varsa wildcard eşleştirme işinizi kolaylaştırır. Bunun için DNS sağlayıcınızın API desteği gerekir (Cloudflare, Route53 vb.):
# Cloudflare DNS modülüyle Caddy'yi derle
xcaddy build --with github.com/caddy-dns/cloudflare
*.example.com {
tls {
dns cloudflare {env.CF_API_TOKEN}
}
@site1 host site1.example.com
handle @site1 {
root * /var/www/site1
file_server
}
@site2 host site2.example.com
handle @site2 {
reverse_proxy localhost:5000
}
}
{env.CF_API_TOKEN} ifadesi ortam değişkeninden token okur. Bunu /etc/caddy/caddy.env dosyasında saklayın ve systemd servis dosyasına EnvironmentFile direktifiyle dahil edin.
Yapılandırma Yönetimi
Caddyfile Doğrulama ve Yeniden Yükleme
Yapılandırma dosyanızı kaydetmeden önce mutlaka doğrulayın:
# Caddyfile sözdizimini kontrol et
caddy validate --config /etc/caddy/Caddyfile
# Servisi durdurmadan yapılandırmayı yeniden yükle
sudo systemctl reload caddy
# Veya Caddy'nin kendi komutuyla
caddy reload --config /etc/caddy/Caddyfile
systemctl reload ile Caddy zero-downtime reload yapar. Yani aktif bağlantılar kesilmez, sadece yeni yapılandırma geçerli olur.
Ortam Değişkenleri Kullanımı
API anahtarlarını veya hassas bilgileri Caddyfile’a yazmak yerine ortam değişkenlerinden okuyabilirsiniz:
# /etc/caddy/caddy.env dosyası oluştur
cat > /etc/caddy/caddy.env << EOF
CF_API_TOKEN=buraya_cloudflare_token
DB_HOST=localhost
DOMAIN=example.com
EOF
chmod 600 /etc/caddy/caddy.env
Systemd servis dosyasını düzenleyin:
sudo systemctl edit caddy
Açılan editöre şunu yazın:
[Service]
EnvironmentFile=/etc/caddy/caddy.env
Artık Caddyfile içinde {env.CF_API_TOKEN} veya {env.DOMAIN} şeklinde kullanabilirsiniz:
{env.DOMAIN} {
reverse_proxy localhost:3000
}
Caddy JSON API
Caddy’nin güçlü yönlerinden biri REST API üzerinden dinamik yapılandırma yapabilmektir. Servis yeniden başlatmaya gerek kalmaz:
# Mevcut yapılandırmayı görüntüle
curl localhost:2019/config/
# Yeni bir route ekle (dinamik olarak)
curl localhost:2019/config/apps/http/servers/srv0/routes
-X POST
-H "Content-Type: application/json"
-d '{
"match": [{"host": ["yeni-site.example.com"]}],
"handle": [{"handler": "reverse_proxy", "upstreams": [{"dial": "localhost:7000"}]}]
}'
# Yapılandırmayı Caddyfile formatından JSON'a çevir
caddy adapt --config /etc/caddy/Caddyfile
Log Yönetimi ve İzleme
Caddy’nin log sistemi oldukça esnek. JSON formatında loglama yapılandırması:
{
log {
output file /var/log/caddy/caddy.log {
roll_size 100mb
roll_keep 5
roll_keep_for 720h
}
level INFO
}
}
example.com {
log {
output file /var/log/caddy/access.log
format json {
time_format "2006-01-02T15:04:05Z07:00"
}
}
reverse_proxy localhost:3000
}
Üstteki {} bloğu global ayarlar bölümüdür, alan adı bloklarının dışına yazılır.
Logları gerçek zamanlı izlemek için:
# Systemd journal üzerinden
sudo journalctl -u caddy -f
# Log dosyasını takip et
sudo tail -f /var/log/caddy/access.log | jq .
# Sadece hata loglarını gör
sudo journalctl -u caddy -p err
Güvenlik Yapılandırması
Rate Limiting
Caddy’de rate limiting için caddy-ratelimit modülü gereklidir. Ama temel koruma için header ve respond direktifleriyle bazı senaryoları ele alabilirsiniz:
api.example.com {
# Güvenlik header'ları ekle
header {
X-Content-Type-Options nosniff
X-Frame-Options DENY
X-XSS-Protection "1; mode=block"
Referrer-Policy strict-origin-when-cross-origin
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
-Server
}
# Belirli IP'leri engelle
@blocked {
remote_ip 192.168.100.50 10.0.0.100
}
abort @blocked
reverse_proxy localhost:8080
}
TLS Yapılandırması
Varsayılan TLS ayarları genellikle yeterli olsa da ince ayar yapabilirsiniz:
example.com {
tls {
protocols tls1.2 tls1.3
ciphers TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
curves x25519 secp384r1
}
reverse_proxy localhost:3000
}
Kendi Sertifikanızı Kullanmak
Let’s Encrypt yerine kendi sertifikanızı kullanmak isterseniz:
example.com {
tls /etc/ssl/certs/example.com.crt /etc/ssl/private/example.com.key
reverse_proxy localhost:3000
}
Sık Karşılaşılan Sorunlar ve Çözümleri
Port 80/443 zaten kullanımda hatası:
# Hangi servis portu kullanıyor?
sudo ss -tlnp | grep ':80|:443'
# Nginx veya Apache varsa durdur
sudo systemctl stop nginx
sudo systemctl disable nginx
Let’s Encrypt sertifika alamıyor:
Genellikle DNS henüz propagate olmamıştır veya port 80 kapalıdır. Kontrol adımları:
# Port 80'in dışarıdan erişilebilir olduğunu kontrol et
curl -v http://example.com
# DNS'in doğru IP'ye işaret ettiğini kontrol et
dig example.com +short
# Caddy loglarında detaya bak
sudo journalctl -u caddy --since "10 minutes ago"
Staging ortamı için Let’s Encrypt rate limit sorunları:
Test aşamasında gerçek sertifika almak yerine Let’s Encrypt staging ortamını kullanın:
{
acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}
example.com {
reverse_proxy localhost:3000
}
Sonuç
Caddy, özellikle HTTPS yönetimini otomatik hale getirmesiyle sistem yöneticilerinin tekrarlayan ve hata prone işlerini ortadan kaldırıyor. Nginx ile karşılaştırdığınızda yapılandırma dosyaları çok daha okunabilir, sertifika yenileme cron job’larıyla uğraşmak zorunda kalmıyorsunuz ve HTTP/2, HTTP/3 gibi modern protokoller kutudan çıkar çıkmaz çalışıyor.
Küçük bir VPS üzerinde birkaç site yönetiyorsanız, mikro servis mimarisinde reverse proxy ihtiyacınız varsa ya da hızlıca güvenli bir web sunucusu ayağa kaldırmak istiyorsanız Caddy mükemmel bir seçim. Büyük ölçekli yapılarda Nginx’in daha fazla özelleştirme imkanı sunduğu doğru, ancak Caddy’nin geliştirme hızı ve modül ekosistemi giderek büyüyor.
En iyi öğrenme yöntemi olduğu gibi: bir test sunucusu alın, bu yazıdaki örnekleri uygulayın ve kendi senaryolarınıza göre genişletin. Caddy’nin resmi dokümantasyonu da (caddyserver.com/docs) oldukça kapsamlı ve güncel, takıldığınız noktalarda ilk başvuru kaynağınız olsun.