# Caddy otomatik HTTPS'li reverse proxy olarak nasıl kurulur

> Caddy'yi resmi apt deposundan Ubuntu veya Debian'a kurun; birden fazla uygulamayı güvenlik başlıkları, parola koruması ve loglarla otomatik HTTPS arkasına alın.

Zorluk: Başlangıç\
Denendiği sistemler: Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12, Debian 13

Caddy, HTTPS sertifikalarını kendi başına alan ve yenileyen bir web sunucusu ve reverse proxy'dir. Bir alan adı yazar, onu bir uygulamaya yönlendirirsiniz; Let's Encrypt'i, HTTP'den HTTPS'e yönlendirmeyi ve yenilemeleri Caddy halleder. Bu yüzden Caddy, bu kütüphanedeki self-hosted uygulamaların varsayılan HTTPS ön yüzüdür: her uygulama `127.0.0.1:8080` gibi yerel bir portta dinler, Caddy de onu 80 ve 443 numaralı portlarda yayınlar. Bu rehber Caddy'yi resmi apt deposundan Ubuntu veya Debian'a kurar, güvenlik duvarını açar, birden fazla uygulamaya proxy yapar, güvenlik başlıkları, parola koruması ve erişim logları ekler; sertifikaları güvenle test etmeyi, yedeklemeyi, güncellemeyi ve sorun gidermeyi gösterir.

> **Not**
>
> Başka bir proxy mi tercih edersiniz? [Nginx ve Certbot](/guides/nginx-reverse-proxy-certbot) Nginx'i zaten bilen ekiplere uygundur; [Traefik](/guides/traefik-reverse-proxy) ve [Nginx Proxy Manager](/guides/nginx-proxy-manager) ise konteyner olarak çalışır. Hepsi 80 ve 443 numaralı portlara ihtiyaç duyduğu için bir sunucuda yalnızca birini kullanın.

## Ön koşullar

- **Ubuntu 24.04 LTS**, **Ubuntu 26.04 LTS**, **Debian 12** veya **Debian 13** çalıştıran bir sunucu. Caddy'nin apt deposu tek bir sürüme bağlı değildir.
- `sudo` yetkisi ve SSH anahtarıyla girişi olan, root olmayan bir kullanıcı: [Yeni bir Linux sunucusunu güvenli hale getirin](/guides/secure-a-new-linux-server) ve [SSH anahtarlarını ayarlayın](/guides/ssh-keys).
- Sunmak istediğiniz her ana makine adı için, örneğin `app.example.com`, sunucunun genel IP adresini gösteren bir **A kaydı** (sunucuda çalışan IPv6 varsa bir **AAAA kaydı** da) olan bir alan adı.
- Sunucuda boş 80 ve 443 numaralı portlar: orada dinleyen Apache, Nginx veya konteynerde çalışan bir proxy olmamalı.
- Yerel bir portta dinleyen en az bir uygulama. Docker uygulamalarını [Docker Compose temelleri](/guides/docker-compose-basics) rehberinde anlatıldığı gibi yalnızca `127.0.0.1` üzerinde yayınlayın.

Caddy projesi en düşük donanım gereksinimi yayınlamaz; Caddy'nin kendisi küçük ayak izli tek bir ikili dosyadır. Aşağıdaki değerler yalnızca Caddy için temkinli bir başlangıç noktasıdır; sunucuyu arkasındaki uygulamalara göre boyutlandırın.

| Kaynak | En düşük (resmi) | Önerilen başlangıç |
|---|---|---|
| CPU | Yayınlanmamış | Uygulamalarınızla paylaşılan 1 vCPU |
| RAM | Yayınlanmamış | Caddy için 256 MB boş bellek |
| Disk | Yayınlanmamış | Sertifikalar ve loglar için 1 GB boş alan |

## Adım 1 — DNS'i sunucuya yönlendirin ve güvenlik duvarını açın

Caddy ancak Let's Encrypt sunucunuza alan adı üzerinden ulaşabildiğinde sertifika alabilir. Caddy'yi başlatmadan önce DNS kayıtlarını oluşturun ve sunucuya çözümlendiklerini kontrol edin:

```bash
dig +short A app.example.com
dig +short AAAA app.example.com
```

İlk komut sunucunuzun IPv4 adresini, örneğin `203.0.113.10`, yazmalıdır. İkinci komut bir adres yazıyorsa sunucuda IPv6'nın da çalışması gerekir; çünkü bir AAAA kaydı varsa Let's Encrypt IPv6'yı tercih eder. Sunucuda çalışan IPv6 yoksa AAAA kaydını kaldırın.

ufw'de SSH, HTTP ve HTTPS'e izin verin. Caddy varsayılan olarak UDP üzerinden çalışan HTTP/3 sunar; bu yüzden `443/udp` portunu da açın. Debian'da önce ufw'yi `sudo apt install ufw` ile kurun.

```bash
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 443/udp
sudo ufw enable
sudo ufw status verbose
```

Tüm trafik sonunda HTTPS'e gitse de 80 numaralı port açık kalmalıdır: Caddy onu HTTP doğrulaması ve ziyaretçileri HTTPS'e yönlendirmek için kullanır.

## Adım 2 — Caddy'yi resmi depodan kurun

Caddy, Debian ve Ubuntu paketlerini Cloudsmith deposu üzerinden yayınlar. Gerekli paketleri kurun, imza anahtarını ve depoyu ekleyin, ardından paketi kurun:

```bash
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
```

Aynı komutlar Ubuntu'da ve Debian'da çalışır. Paket sizin için birkaç şey yapar:

- ana klasörü `/var/lib/caddy` olan ve sertifikalarla diğer durum bilgilerini tutan `caddy` adlı bir sistem kullanıcısı oluşturur,
- sahibi bu kullanıcı olan `/var/log/caddy` klasörünü oluşturur,
- `/etc/caddy/Caddyfile` yapılandırma dosyasını kurar,
- `caddy run --config /etc/caddy/Caddyfile` komutunu `caddy` kullanıcısıyla çalıştıran `caddy` systemd servisini kurar ve başlatır.

Servisin çalıştığını kontrol edin:

```bash
caddy version
systemctl status caddy --no-pager
curl -I http://localhost
```

Varsayılan Caddyfile 80 numaralı portta bir karşılama sayfası sunar; bu yüzden `curl` çıktısında `HTTP/1.1 200 OK` görünür.

## Adım 3 — İlk uygulamanıza proxy yapın

Caddyfile'ı açın:

```bash
sudo nano /etc/caddy/Caddyfile
```

İçeriğini bir global seçenekler bloğu ve bir site bloğuyla değiştirin. E-posta adresi, sertifika otoritesindeki ACME hesabınız için kullanılır:

```caddyfile
{
    email admin@example.com
}

app.example.com {
    reverse_proxy 127.0.0.1:8080
}
```

Tek bir HTTPS sitesi için yapılandırmanın tamamı budur. `app.example.com` herkese açık bir alan adı olduğu için Caddy kendiliğinden:

- Let's Encrypt'ten sertifika alır, Let's Encrypt başarısız olursa ZeroSSL'i dener,
- `http://app.example.com` adresini HTTPS'e yönlendirir,
- sertifikayı süresi dolmadan çok önce arka planda yeniler,
- özgün `Host` başlığını uygulamaya iletir ve `X-Forwarded-For`, `X-Forwarded-Proto` ile `X-Forwarded-Host` başlıklarını ayarlar,
- ek bir yönerge olmadan WebSocket bağlantılarına proxy yapar ve server-sent events gibi akış yanıtlarını iletir.

> **İpucu**
>
> Denemeler sırasında global seçenekler bloğuna `acme_ca https://acme-staging-v02.api.letsencrypt.org/directory` satırını ekleyin. Let's Encrypt'in staging CA'sının sınırları çok daha yüksektir, ancak sertifikalarına tarayıcılar güvenmez. Her şey çalıştığında satırı silip yeniden yükleyin; Caddy güvenilir sertifikaları alır.

## Adım 4 — Doğrulayın, yeniden yükleyin ve kontrol edin

Yapılandırmayı `caddy` kullanıcısıyla kontrol edin; böylece kontrolün oluşturduğu dosyalar, örneğin yeni bir log dosyası, doğru sahibe ait olur:

```bash
sudo -H -u caddy caddy validate --config /etc/caddy/Caddyfile
```

`Valid configuration` görmelisiniz. Girdinin biçimlendirilmediğini söyleyen bir uyarı zararsızdır; `sudo caddy fmt --overwrite /etc/caddy/Caddyfile` ile düzeltin. Ardından yapılandırmayı kesinti olmadan uygulayın:

```bash
sudo systemctl reload caddy
```

Yeni yapılandırma yüklenemezse Caddy eskisini çalıştırmaya devam eder; yani bir yazım hatası sitelerinizi kapatmaz. Sertifikanın alınmasını izleyin:

```bash
journalctl -u caddy --no-pager -n 50
```

`app.example.com` için sertifikanın başarıyla alındığını söyleyen bir satır arayın. Ardından sunucudan veya kendi bilgisayarınızdan test edin:

```bash
curl -I http://app.example.com
curl -I https://app.example.com
```

İlk istek `Location: https://app.example.com/` başlığıyla `308 Permanent Redirect` döndürür; ikincisi uygulamanızın yanıtını, genellikle `HTTP/2 200` döndürür. Sertifikalar ve ACME hesap anahtarları `/var/lib/caddy/.local/share/caddy` altında saklanır.

## Adım 5 — Başka siteler ve ortak güvenlik başlıkları ekleyin

Her ek uygulama, kendi yerel portunu gösteren kendi site bloğunu alır. Tekrarlanan ayarlar bir **snippet**'e, yani `import` ile eklediğiniz parantez içinde adlandırılmış bir bloğa konur. Aşağıdaki Caddyfile iki uygulama sunar, yanıtları sıkıştırır ve temkinli güvenlik başlıkları ekler:

```caddyfile
{
    email admin@example.com
}

(common) {
    encode zstd gzip
    header {
        ?Strict-Transport-Security "max-age=31536000;"
        ?X-Content-Type-Options "nosniff"
        ?X-Frame-Options "SAMEORIGIN"
        ?Referrer-Policy "strict-origin-when-cross-origin"
        -Server
    }
}

app.example.com {
    import common
    reverse_proxy 127.0.0.1:8080
}

status.example.com {
    import common
    reverse_proxy 127.0.0.1:3001
}
```

`?` öneki bir başlığı yalnızca uygulama onu zaten göndermediyse ayarlar; böylece kendi, daha sıkı başlıkları olan bir uygulama onları korur. `-Server`, `Server: Caddy` başlığını kaldırır. Her değişiklikten sonra Adım 4'teki gibi doğrulayıp yeniden yükleyin; Caddy her yeni ana makine adı için sertifikayı kendisi ister.

> **Uyarı**
>
> `Strict-Transport-Security` (HSTS), tarayıcılara bu ana makine adı için belirtilen süre boyunca, burada bir yıl, düz HTTP'yi reddetmelerini söyler. Caddy her zaman HTTPS sunduğu için bu normalde güvenlidir; ancak alan adının her alt alan adı geçerli HTTPS sunmuyorsa `includeSubDomains` veya `preload` eklemeyin.

Uygulamalarınız bir CDN'in veya başka bir proxy'nin arkasındaysa, Caddy'nin CDN'in ilettiği ziyaretçi adresini kabul etmesi için onun adres aralıklarını `trusted_proxies` sunucu seçeneğine ekleyin. Varsayılan olarak Caddy hiçbir proxy'ye güvenmez ve gelen `X-Forwarded-*` başlıklarını yok sayar.

## Adım 6 — Bir yönetim arayüzünü parolayla koruyun

Bazı araçların kendi girişi yoktur ya da ek bir katman olmadan erişilebilir olmamalıdır. Caddy'nin `basic_auth` yönergesi, istek uygulamaya ulaşmadan önce kullanıcı adı ve parola sorar. Parolalar hash olarak saklanır; bir hash şöyle üretilir:

```bash
caddy hash-password
```

İstendiğinde parolayı iki kez yazın (ekranda görünmez) ve `$2a$` ile başlayan hash'i kopyalayın. Varsayılan algoritma bcrypt'tir; `caddy hash-password --algorithm argon2id` ise Caddy belgelerinin önerdiği argon2id hash'ini üretir. Kullanıcıyı site bloğuna ekleyin:

```caddyfile
tools.example.com {
    import common
    basic_auth {
        # caddy hash-password çıktısındaki hash'i buraya yapıştırın
        alice HASH_FROM_CADDY_HASH_PASSWORD
    }
    reverse_proxy 127.0.0.1:9000
}
```

argon2id kullandıysanız `basic_auth {` yerine `basic_auth argon2id {` yazın. Doğrulayıp yeniden yükleyin; ardından `curl -I https://tools.example.com` komutunun `401 Unauthorized` döndürdüğünü, tarayıcının ise kimlik bilgilerini sorduğunu kontrol edin. Basic auth parolayı her istekle gönderir; bu yalnızca buradaki gibi HTTPS üzerinden kabul edilebilir. Arkadaki uygulama da HTTP basic auth kullanıyorsa iki giriş çakışır; böyle uygulamaları kendi girişleriyle koruyun.

## Adım 7 — Erişim loglarını yazın

Siz istemedikçe Caddy erişim logu yazmaz. Her isteği JSON biçiminde kaydetmek için bir siteye `log` bloğu ekleyin:

```caddyfile
app.example.com {
    import common
    log {
        output file /var/log/caddy/app.example.com.log
    }
    reverse_proxy 127.0.0.1:8080
}
```

Varsayılan olarak dosya 100 MiB'de döndürülür, Caddy 10 eski dosya saklar ve 90 günden eski dosyaları siler; böylece loglar diski dolduramaz. `Authorization` ve `Cookie` başlıkları `REDACTED` olarak loglanır. Adım 4'teki komutla doğrulayın, yeniden yükleyin ve logu izleyin:

```bash
sudo tail -f /var/log/caddy/app.example.com.log
```

Sertifika olayları ve hatalar dahil Caddy'nin kendi mesajları systemd journal'a gider: `journalctl -u caddy -f`.

## Yedekleme ve geri yükleme

Caddy'nin durumu küçüktür:

- `/etc/caddy/` — Caddyfile'ınız ve ondan içe aktardığınız her şey,
- `/var/lib/caddy/.local/share/caddy/` — sertifikalar, özel anahtarlar ve ACME hesabı.

Sertifikalar her zaman yeniden istenebilir; ancak onları geri yüklemek, çok sayıda ana makine adı olan bir sunucuyu yeniden kurarken sınırlara takılmanızı önler. Yedeği oluşturun:

```bash
sudo mkdir -p /opt/backups
sudo tar czf /opt/backups/caddy-$(date +%F).tar.gz /etc/caddy /var/lib/caddy/.local/share/caddy
```

Yeni bir sunucuda geri yüklemek için Caddy'yi Adım 2'deki gibi kurun, ardından arşivi açın, sahipliği düzeltin ve yeniden yükleyin:

```bash
sudo tar xzf /opt/backups/caddy-2026-10-09.tar.gz -C /
sudo chown -R caddy:caddy /var/lib/caddy/.local
sudo systemctl reload caddy
```

Arşiv özel anahtarlar içerir; kısıtlı izinlerle saklayın ve sunucunun dışında güvenli bir yere kopyalayın.

## Caddy güncelleme

Caddy güncellemeleri eklediğiniz apt deposu üzerinden gelir:

```bash
sudo apt update
sudo apt install --only-upgrade caddy
caddy version
systemctl status caddy --no-pager
```

Bir ara sürüm yükseltmesinden önce Caddy'nin GitHub sürümler sayfasındaki sürüm notlarını okuyun ve `/etc/caddy` klasörünün yedeğini tutun. Paketle kurulmuş bir sistemde `caddy upgrade` kullanmayın; bu komut ikili dosyayı apt'nin haberi olmadan değiştirir.

## Sorun giderme

### Sertifika alınamıyor: Timeout during connect (likely firewall problem)

Let's Encrypt sunucuya 80 veya 443 numaralı porttan ulaşamadı. `sudo ufw status` çıktısını, sunucunun önündeki güvenlik duvarlarını ve bu portları başka bir şeyin dinlemediğini kontrol edin. Alan adının AAAA kaydı varsa IPv6'yı başka bir makineden `curl -6 -I http://app.example.com` ile test edin; eski bir AAAA kaydı sık görülen bir nedendir. Caddy artan aralıklarla kendisi yeniden dener; nedeni düzelttikten sonra yeniden yükleyin ve `journalctl -u caddy -f` ile izleyin.

### DNS problem: NXDOMAIN looking up A for app.example.com

DNS kaydı henüz yok, yazım hatası içeriyor veya başka bir yeri gösteriyor. `dig +short A app.example.com` ile kendi bilgisayarınızdan da kontrol edin; yeni kayıtların yayılması birkaç dakika sürebilir.

### urn:ietf:params:acme:error:rateLimited

Bir Let's Encrypt sınırına takıldınız. Let's Encrypt diğer sınırların yanı sıra tam olarak aynı ana makine adı kümesi için 7 günde 5 sertifikaya ve ana makine adı başına saatte 5 başarısız doğrulamaya izin verir. Asıl sorunu düzeltin, staging CA ile test edin (Adım 3'teki ipucu) ve sınırın dolmasını bekleyin. Yeniden kurulumdan sonra `/var/lib/caddy/.local/share/caddy` klasörünü yedekten geri yüklemek yeni sertifika alımlarını önler.

### listen tcp :443: bind: address already in use

Portu başka bir program kullanıyor. `sudo ss -tlpn 'sport = :443'` ile bulun. Tipik nedenler Apache, Nginx veya 80 ya da 443 numaralı portu yayınlayan bir konteynerdir. Onu durdurup devre dışı bırakın, örneğin `sudo systemctl disable --now apache2`, ardından `sudo systemctl restart caddy` çalıştırın.

### 502 Bad Gateway

Caddy çalışıyor, ancak arkadaki uygulama yanıt vermiyor. Upstream'i sunucudan `curl -I http://127.0.0.1:8080` ile test edin. Bu başarısız olursa uygulama kapalıdır veya başka bir portta dinliyordur; Docker uygulamalarında `docker compose ps` çıktısını ve port eşlemesini kontrol edin.

### open /var/log/caddy/app.example.com.log: permission denied

Log dosyası root tarafından oluşturulmuş; örneğin `caddy validate` düz `sudo` ile çalıştırıldığında. Dosyayı `sudo chown caddy:caddy /var/log/caddy/*.log` ile servis kullanıcısına geri verin ve yeniden yükleyin. Bunu önlemek için Adım 4'te gösterildiği gibi doğrulayın.

## Sonraki adımlar

- Uygulama rehberlerinin konteynerlerini nasıl düzenlediğini [Docker Compose temelleri](/guides/docker-compose-basics) rehberinde öğrenin.
- [Nginx ve Certbot](/guides/nginx-reverse-proxy-certbot) veya konteyner tabanlı [Traefik](/guides/traefik-reverse-proxy) ile karşılaştırın.
- Sunucunun geri kalanını [Yeni bir Linux sunucusunu güvenli hale getirin](/guides/secure-a-new-linux-server) rehberiyle sağlamlaştırın.
- Konteynerleriniz için bir sunucuyu [Docker hosting](/docker-hosting) sayfasında bulun.
- Eşleyiciler, snippet'ler ve diğer yönergeler için resmi [Caddyfile belgelerini](https://caddyserver.com/docs/caddyfile/concepts) okuyun.

## Sık sorulan sorular

### Caddy için Let’s Encrypt'i kendim yapılandırmam gerekir mi?

Hayır. Bir site bloğunda herkese açık bir alan adı geçtiği anda Caddy Let’s Encrypt'ten (yedek olarak ZeroSSL'den) sertifika alır, HTTP'yi HTTPS'e yönlendirir ve sertifikayı arka planda yeniler. Yalnızca sunucuyu gösteren DNS kayıtlarına ve erişilebilir 80 ile 443 numaralı portlara ihtiyacınız vardır.

### Caddy WebSocket ve server-sent events destekler mi?

Evet, ek yapılandırma olmadan. reverse_proxy WebSocket yükseltmelerini geçirir ve event stream gibi akış yanıtlarını hemen iletir. Uzun süreli WebSocket bağlantıları yapılandırmayı yeniden yüklediğinizde kapanır ve istemciler yeniden bağlanır.

### Caddy'yi aynı sunucuda Nginx veya Apache ile birlikte çalıştırabilir miyim?

Aynı portlarda hayır. 80 ve 443 numaralı portları yalnızca tek bir program dinleyebilir. Diğer web sunucusunu durdurup devre dışı bırakın ya da Caddy'nin ona 127.0.0.1:8081 gibi yerel bir port üzerinden proxy yapmasını sağlayın.

### Uygulamalarım neden ziyaretçinin değil Caddy'nin IP adresini görüyor?

Caddy ziyaretçinin adresini X-Forwarded-For başlığında gönderir. Uygulamayı 127.0.0.1 adresindeki proxy'ye güvenecek ve bu başlığı okuyacak şekilde ayarlayın; çoğu uygulamada bunun için bir güvenilir proxy (trusted proxies) ayarı bulunur.

### Caddy'yi güncellemek için caddy upgrade kullanmalı mıyım?

Caddy apt deposundan kurulduysa hayır. Paket yöneticisinin ikili dosyayı ve systemd servisini yönetmeye devam etmesi için Caddy'yi diğer paketler gibi apt ile güncelleyin.

---

Kaynak: <https://hyperdc.com/tr/guides/tutorials/caddy-reverse-proxy>\
Son güncelleme: 2026-10-09
