KurulumHTTPS'li kurulum (Caddy)

HTTPS'li kurulum (Caddy)

Boş bir sunucuya, kendi alan adınızla ve otomatik Let's Encrypt sertifikasıyla Bekci kurun. Hangi dosyanın nereye gideceği adım adım.

Bu sayfada

Bu rehberin sonunda Bekci, https://bekci.ornek.com gibi kendi alan adınızda, geçerli bir HTTPS sertifikasıyla çalışıyor olacak. Sertifikayı Caddy web sunucusu Let's Encrypt'ten kendisi alır ve süresi dolmadan yeniler; sizin bir şey yapmanız gerekmez. Toplam süre: yaklaşık 10 dakika (DNS kaydının yayılmasını beklemek hariç).

Neye ihtiyacınız var?#

  • Genel (public) bir IPv4 adresi olan bir Linux sunucu (gereksinimler).
  • Bir alan adı ya da alt alan adı, ör. bekci.ornek.com, ve bu alan adının DNS kayıtlarını düzenleyebileceğiniz panel (alan adını aldığınız firma ya da Cloudflare).
  • Sertifika bildirimleri için bir e-posta adresi.

Kurulumun sonunda dosyalar#

Sunucunuzda bir klasör ve içinde üç dosya olacak. Yalnızca birini (.env) düzenleyeceksiniz:

Klasör düzeni
/opt/bekci/
├── docker-compose.yml   ← Bekci + Caddy tanımı      (olduğu gibi kullanın)
├── Caddyfile            ← Caddy'nin ayarı            (olduğu gibi kullanın)
└── .env                 ← alan adınız ve e-postanız  (düzenleyeceğiniz tek dosya)

.env dosyasının adı noktayla başlar; bu yüzden ls komutu onu göstermez, ls -la gösterir.

1. DNS kaydını ekleyin#

Alan adınızın DNS panelinde yeni bir A kaydı oluşturun:

AlanDeğer
Tür (Type)A
Ad (Name / Host)bekci — bekci.ornek.com için. Alan adının kendisi (ornek.com) için @
Değer (Value / IPv4 address)Sunucunuzun genel IPv4 adresi, ör. 203.0.113.10
TTLOtomatik (Auto) ya da 300

Sunucunun genel IP adresini barındırma sağlayıcınızın panelinde görebilirsiniz; sunucuda hostname -I komutunun yazdığı ilk adres de genellikle budur. IPv6 kullanıyorsanız aynı adla bir AAAA kaydı da ekleyebilirsiniz; eklerseniz sunucunun IPv6 üzerinden de erişilebilir olduğundan emin olun.

2. Docker'ı kurun#

Docker kurulu değilse Docker rehberindeki ilk adımı izleyin (resmi betik Compose eklentisini de kurar).

3. 80 ve 443 portlarını kontrol edin#

Önce portların boş olduğundan emin olun:

terminal
ss -ltnp 'sport = :80'
ss -ltnp 'sport = :443'

Sonra portların dışarıdan erişilebilir olduğundan emin olun:

  • Barındırma sağlayıcınızın güvenlik duvarı (Hetzner, DigitalOcean, AWS “security group” vb.): gelen 80/TCP, 443/TCP ve isteğe bağlı olarak 443/UDP (HTTP/3) bağlantılarına izin verin.
  • ufw kullanıyorsanız (ufw status “Status: active” diyorsa) kuralları ekleyin; SSH kuralını unutmayın:
terminal
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 443/udp

4. Klasörü oluşturun#

terminal
mkdir -p /opt/bekci
cd /opt/bekci

Bundan sonraki tüm komutları bu klasörün içindeyken çalıştırın. Terminali kapatıp yeniden bağlanırsanız önce cd /opt/bekci yazın.

5. Üç dosyayı oluşturun#

Dosyaları iki yoldan biriyle oluşturabilirsiniz. İndirmek daha hızlıdır ve kopyala-yapıştır hatası riski yoktur.

İndirerek (önerilen)

terminal
cd /opt/bekci
curl -fsSL -o docker-compose.yml https://bekci.app/indir/caddy/docker-compose.yml
curl -fsSL -o Caddyfile https://bekci.app/indir/caddy/Caddyfile
curl -fsSL -o .env https://bekci.app/indir/caddy/env.example
ls -la

Üçüncü komut örnek ayar dosyasını .env adıyla kaydeder; adın başındaki nokta önemlidir.

Elle oluşturarak

Her dosya için nano ile boş bir dosya açın, aşağıdaki içeriği yapıştırın, Ctrl+O ve Enter ile kaydedip Ctrl+X ile çıkın.

docker-compose.yml — nano /opt/bekci/docker-compose.yml

/opt/bekci/docker-compose.ymlİndir
# Bekci + Caddy: otomatik HTTPS ile kurulum (Let's Encrypt).
# Adım adım rehber: https://bekci.app/docs/kurulum/caddy/
#
# Bu dosyayı değiştirmeniz gerekmez: alan adı, e-posta ve sürüm .env
# dosyasından okunur. Üç dosya aynı klasörde durur (ör. /opt/bekci):
#   docker-compose.yml   bu dosya
#   Caddyfile            Caddy ayarı
#   .env                 alan adınız ve e-postanız
#
# Başlatma:     docker compose up -d
# Günlükler:    docker compose logs -f bekci      (Caddy için: caddy)
# Güncelleme:   docker compose pull && docker compose up -d
# Yedek, sürüm sabitleme, geri dönüş: https://bekci.app/docs/guncelleme-yedek/

name: bekci

services:
  bekci:
    # UPTIME_TAG: latest (SQLite, önerilen) | postgres (gömülü PostgreSQL)
    # ya da sabit bir sürüm: 1.0.0 / 1.0.0-postgres. İki türün verisi
    # birbirine taşınmaz: baştan birini seçin.
    image: kadirsungurlu/bekci:${UPTIME_TAG:-latest}
    restart: unless-stopped
    # Kapanışta uygulama (ve gömülü PostgreSQL) düzgünce kapansın.
    stop_grace_period: 30s
    environment:
      BASE_URL: https://${UPTIME_DOMAIN:?UPTIME_DOMAIN .env dosyasında tanımlı olmalı}
      TZ: ${TZ:-Europe/Istanbul}
      LOG_LEVEL: ${LOG_LEVEL:-info}
      MAX_CONCURRENT_CHECKS: ${MAX_CONCURRENT_CHECKS:-50}
    volumes:
      - bekci-data:/data
    # Dışarıya doğrudan açılmaz; yalnızca Caddy üzerinden erişilir.
    expose:
      - "8080"
    logging:
      driver: json-file
      options:
        max-size: 10m
        max-file: "3"

  caddy:
    # caddy:2-alpine (digest ile sabit)
    image: caddy:2-alpine@sha256:6aeddd44c3078b0f9a35206472a11420648a79c184603ef95957d0a20044cb2b
    restart: unless-stopped
    depends_on:
      bekci:
        condition: service_healthy
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp" # HTTP/3
    environment:
      UPTIME_DOMAIN: ${UPTIME_DOMAIN}
      ACME_EMAIL: ${ACME_EMAIL:?ACME_EMAIL .env dosyasında tanımlı olmalı}
      STATUS_DOMAIN: ${STATUS_DOMAIN:-}
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    logging:
      driver: json-file
      options:
        max-size: 10m
        max-file: "3"

volumes:
  bekci-data:
  caddy-data:
  caddy-config:

Caddyfile — nano /opt/bekci/Caddyfile (dosyanın adı tam olarak Caddyfile; uzantısı yok, C büyük)

/opt/bekci/Caddyfileİndir
# Caddy: HTTPS sertifikasını otomatik alır ve Bekci'ye yönlendirir.
# Alan adları .env dosyasından gelir; bu dosyayı değiştirmeniz gerekmez.
# Rehber: https://bekci.app/docs/kurulum/caddy/

{
	email {$ACME_EMAIL}
}

{$UPTIME_DOMAIN} {
	encode zstd gzip
	# Tarayıcı bu alan adına 1 yıl boyunca yalnızca HTTPS ile bağlansın.
	# ">" işareti: uygulama da aynı başlığı gönderirse çift olmasın, bu geçerli olsun.
	header >Strict-Transport-Security "max-age=31536000"
	reverse_proxy bekci:8080 {
		# Canlı akış (Server-Sent Events) tamponlanmadan iletilsin.
		flush_interval -1
	}
}

# İsteğe bağlı: durum sayfası için ayrı alan adı (ör. durum.ornek.com).
# .env'de STATUS_DOMAIN tanımlayıp aşağıdaki bloğun başındaki # işaretlerini
# kaldırın; ardından panelde durum sayfasının "Özel alan adı" alanına aynı
# adı yazın. Bu adresten yalnızca durum sayfası açılır, yönetim paneli açılmaz.
#
# {$STATUS_DOMAIN} {
# 	encode zstd gzip
# 	header >Strict-Transport-Security "max-age=31536000"
# 	reverse_proxy bekci:8080
# }

.env — nano /opt/bekci/.env (içeriğini bir sonraki adımda düzenleyeceksiniz)

/opt/bekci/.envİndir
# Bekci + Caddy ayarları. Bu dosyanın adı sunucuda ".env" olmalı ve
# docker-compose.yml ile aynı klasörde durmalı (ör. /opt/bekci/.env).
# Rehber: https://bekci.app/docs/kurulum/caddy/

# Panelin alan adı (http:// ve / olmadan). DNS A kaydı bu sunucuyu göstermeli.
UPTIME_DOMAIN=bekci.ornek.com

# Let's Encrypt sertifika bildirimleri için e-posta adresiniz.
ACME_EMAIL=[email protected]

# latest: SQLite (önerilen) | postgres: gömülü PostgreSQL
# Sürümü sabitlemek için: 1.0.0 (SQLite) ya da 1.0.0-postgres.
UPTIME_TAG=latest

TZ=Europe/Istanbul
LOG_LEVEL=info

# Aynı anda en fazla kontrol sayısı (yüzlerce monitörde artırılabilir).
MAX_CONCURRENT_CHECKS=50

# İsteğe bağlı: durum sayfası için ayrı alan adı (Caddyfile'daki bloğu da açın).
# STATUS_DOMAIN=durum.ornek.com

6. .env dosyasına alan adınızı yazın#

terminal
nano /opt/bekci/.env

Yalnızca iki satırı değiştirin; geri kalanlar olduğu gibi kalabilir:

/opt/bekci/.env (değişen satırlar)
UPTIME_DOMAIN=bekci.ornek.com
ACME_EMAIL=[email protected]
  • UPTIME_DOMAIN: 1. adımda DNS kaydını eklediğiniz alan adı. Başına https:// koymayın, sonuna / eklemeyin.
  • ACME_EMAIL: Let's Encrypt'in sertifikayla ilgili bildirimleri göndereceği e-posta adresiniz.

Diğer satırların anlamı: UPTIME_TAG hangi Bekci sürümünün kullanılacağı (sürüm sabitleme), TZ saat dilimi, MAX_CONCURRENT_CHECKS aynı anda yapılacak en fazla kontrol sayısı (tüm değişkenler).

Kaydedip çıkın (Ctrl+O, Enter, Ctrl+X).

7. Başlatın#

terminal
cd /opt/bekci
docker compose up -d

İlk seferde imajlar indirilir. Caddy, Bekci sağlıklı olana kadar bekler, sonra başlar ve sertifikayı almaya çalışır.

8. Sertifikayı doğrulayın#

Caddy'nin sertifikayı aldığını günlüğünden görebilirsiniz:

terminal
docker compose logs caddy | grep -i "certificate obtained"

Satır yoksa bir dakika bekleyip tekrar bakın. Hâlâ yoksa docker compose logs caddy çıktısındaki "level":"error" satırları nedeni söyler; sık karşılaşılan sorunlara bakın.

9. Yönetici hesabını oluşturun#

https://bekci.ornek.com adresini açın. Hoş geldiniz ekranında kullanıcı adı ve en az 8 karakterlik şifrenizi girip Hesabı oluştur'a basın.

BASE_URL bu kurulumda .env'deki alan adından otomatik oluşur (https:// + UPTIME_DOMAIN); ayrıca ayarlamanız gerekmez.

Sık karşılaşılan sorunlar#

Port 80 ya da 443 kullanımda#

docker compose up -d şu hatalardan biriyle durur:

Bind for 0.0.0.0:80 failed: port is already allocated
failed to bind host port 0.0.0.0:80/tcp: address already in use

İlki portu başka bir konteynerin kullandığını söyler; hangisi olduğunu docker ps --filter publish=80 gösterir (Coolify kurulu sunucularda bu coolify-proxy olur). İkincisi portu sunucuda doğrudan çalışan bir programın (çoğunlukla Nginx ya da Apache) kullandığını söyler; ss -ltnp 'sport = :80' hangisi olduğunu gösterir.

  • O web sunucusunu kullanıyorsanız Caddy'li kurulum yerine Bekci'yi onun arkasına yerleştirin: ters vekil arkasında. Coolify varsa: Coolify.
  • Kullanmıyorsanız durdurup kapatabilirsiniz, ör. systemctl disable --now nginx (Apache için apache2), sonra docker compose up -d komutunu tekrarlayın.

DNS henüz yayılmadı ya da yanlış#

Caddy günlüğünde sertifika alınamadığını söyleyen hatalar görürsünüz ve tarayıcı güvenlik uyarısı verir. 1. adımdaki getent komutu sunucunuzun IP'sini göstermiyorsa DNS henüz hazır değildir. Caddy aralıklarla kendisi yeniden dener; DNS doğru adresi gösterdikten sonra hızlandırmak için:

terminal
docker compose restart caddy

Cloudflare kullanıyorum#

  • İlk kurulumda kayıt DNS only (gri bulut) olmalı; aksi halde Let's Encrypt doğrulaması Cloudflare'e takılabilir.
  • Sertifika alındıktan sonra proxy'yi (turuncu bulut) açarsanız Cloudflare'in SSL/TLS ayarını Full (strict) yapın. Flexible modu sonsuz yönlendirme döngüsüne (ERR_TOO_MANY_REDIRECTS) yol açar.
  • Canlı güncellemeler Cloudflare arkasında da çalışır: Bekci bağlantıyı açık tutmak için 25 saniyede bir sinyal gönderir.
  • Sertifika yenilemesi ileride sorun çıkarırsa kaydı geçici olarak yeniden DNS only yapın.

Tarayıcı “güvenli değil” uyarısı veriyor#

Sertifika henüz alınmamıştır. 8. adımdaki kontrolü yapın. Let's Encrypt, çok sayıda başarısız denemeden sonra bir süre yeni istek kabul etmez; bu yüzden DNS'i ve portları düzelttikten sonra docker compose up -d komutunu art arda çok kez çalıştırmak yerine günlüğü izleyin: docker compose logs -f caddy.

.env'deki değişiklik uygulanmadı#

.env dosyasını değiştirdikten sonra docker compose up -d çalıştırın; Compose değişen konteynerleri yeniden oluşturur. Caddyfile dosyasını değiştirdiyseniz ayrıca docker compose restart caddy gerekir.

Durum sayfası için ayrı alan adı (isteğe bağlı)#

Müşterilerinize açık durum sayfasını durum.ornek.com gibi ayrı bir adresten yayınlayabilirsiniz. Bu adreste yalnızca durum sayfası açılır, yönetim paneli açılmaz.

  1. durum adıyla, aynı sunucuyu gösteren bir A kaydı ekleyin (1. adım gibi).

  2. .env dosyasında son satırın başındaki # işaretini kaldırıp alan adını yazın: STATUS_DOMAIN=durum.ornek.com

  3. Caddyfile dosyasının sonundaki bloğun satır başlarındaki # işaretlerini kaldırın. Blok şöyle görünmeli:

    /opt/bekci/Caddyfile (dosyanın sonu)
    {$STATUS_DOMAIN} {
        encode zstd gzip
        header >Strict-Transport-Security "max-age=31536000"
        reverse_proxy bekci:8080
    }
  4. Uygulayın:

    terminal
    cd /opt/bekci
    docker compose up -d --force-recreate caddy
  5. Panelde Durum sayfaları bölümünden sayfanızı açın ve Özel alan adı alanına durum.ornek.com yazıp kaydedin.

Sonraki adımlar#