Docker Compose Rehberi: Çok Konteynerli Uygulama Yönetimi
Docker Compose ile çok konteynerli uygulama tanımlama, servis bağımlılıkları, environment variables, health check, scaling ve production deployment. Kapsamlı rehber.
Caddy web server kurulumu, Caddyfile yapılandırması, otomatik Let's Encrypt SSL, reverse proxy, static site hosting, PHP-FPM entegrasyonu ve performans ayarları.
Caddy, otomatik HTTPS sertifikası yönetimi ile öne çıkan modern bir web sunucusudur. Let's Encrypt entegrasyonu sayesinde SSL sertifikalarını otomatik olarak alır, yeniler ve yapılandırır.
Caddy'nin öne çıkan özellikleri:
Caddy, 80 ve 443 portlarını kullanmak için root yetkisi gerektirir. Systemd servisi olarak çalıştırıldığında bu otomatik olarak yönetilir.
# Caddy GPG anahtarını ve deposunu ekle
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
# Caddy'yi kur
sudo apt update
sudo apt install caddy -y
# Servis durumunu kontrol et
sudo systemctl status caddy
# En son sürümü indir
VERSION=$(curl -s https://api.github.com/repos/caddyserver/caddy/releases/latest | grep tag_name | cut -d '"' -f 4)
curl -L "https://github.com/caddyserver/caddy/releases/download/${VERSION}/caddy_${VERSION#v}_linux_amd64.tar.gz" -o caddy.tar.gz
# Çıkart ve kur
tar -xzf caddy.tar.gz
sudo mv caddy /usr/local/bin/
sudo chmod +x /usr/local/bin/caddy
# Sürümü kontrol et
caddy version
# Systemd servisi oluştur
sudo caddy add-package github.com/caddyserver/caddy/v2
# xcaddy kur
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
# Ek modüllerle derle
xcaddy build \
--with github.com/caddy-dns/cloudflare \
--with github.com/greenpau/caddy-security
# Tek site
example.com {
root * /var/www/html
file_server
}
# Birden fazla site
example.com {
respond "Merhaba example.com!"
}
api.example.com {
reverse_proxy localhost:3000
}
# Caddyfile başında global ayarlar
{
# Admin API portu
admin localhost:2019
# Email (Let's Encrypt için)
email admin@example.com
# ACME sunucusu (test için staging)
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
# HTTP portu
http_port 80
# HTTPS portu
https_port 443
# Log formatı
log {
output file /var/log/caddy/access.log
format json
}
}
Caddy, alan adı için otomatik olarak Let's Encrypt sertifikası alır:
# Sadece alan adını yazın - HTTPS otomatik!
example.com {
root * /var/www/html
file_server
encode gzip
}
# www yönlendirmesi
www.example.com {
redir https://example.com{uri} permanent
}
# Wildcard sertifika (DNS challenge gerektirir)
*.example.com {
tls {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
@api host api.example.com
handle @api {
reverse_proxy localhost:3000
}
}
Caddy, sertifikaları otomatik olarak yeniler. Manuel müdahale gerekmez. Sertifikalar ~/.local/share/caddy/ veya /var/lib/caddy/ dizininde saklanır.
app.example.com {
reverse_proxy localhost:3000
}
# Birden fazla upstream (yük dengeleme)
api.example.com {
reverse_proxy {
to localhost:3001 localhost:3002 localhost:3003
lb_policy round_robin
health_uri /health
health_interval 30s
health_timeout 5s
}
}
app.example.com {
reverse_proxy localhost:3000 {
# Header'ları ilet
header_up Host {upstream_hostport}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
# Zaman aşımı
transport http {
dial_timeout 5s
response_header_timeout 30s
}
# Yeniden deneme
lb_retries 3
lb_try_duration 5s
}
# Güvenlik başlıkları
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options nosniff
X-Frame-Options DENY
Referrer-Policy strict-origin-when-cross-origin
-Server
}
}
static.example.com {
root * /var/www/static
file_server {
# Dizin listesi
browse
# Gizli dosyaları gizle
hide .git .env
}
encode gzip zstd
# Cache başlıkları
header /assets/* Cache-Control "public, max-age=31536000, immutable"
header /*.html Cache-Control "no-cache"
# Hata sayfaları
handle_errors {
rewrite * /errors/{err.status_code}.html
file_server
}
}
# SPA (Single Page Application)
app.example.com {
root * /var/www/app
encode gzip
try_files {path} /index.html
file_server
}
php.example.com {
root * /var/www/php
encode gzip
# PHP dosyalarını PHP-FPM'e yönlendir
php_fastcgi unix//run/php/php8.2-fpm.sock
# Veya TCP ile
# php_fastcgi localhost:9000
file_server
# WordPress için
@notStatic {
not path /wp-content/* /wp-includes/*
not file
}
rewrite @notStatic /index.php
}
# WordPress tam yapılandırma
wordpress.example.com {
root * /var/www/wordpress
encode gzip
php_fastcgi unix//run/php/php8.2-fpm.sock
@disallowed path /xmlrpc.php /wp-admin/install.php
respond @disallowed 403
@static path /wp-content/* /wp-includes/*
handle @static {
file_server
}
handle {
try_files {path} /index.php
php_fastcgi unix//run/php/php8.2-fpm.sock
}
}
# docker-compose.yml
services:
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp" # HTTP/3
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
- ./html:/var/www/html:ro
environment:
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
app:
build: ./app
expose:
- "3000"
volumes:
caddy_data:
caddy_config:
# Docker Caddyfile
example.com {
reverse_proxy app:3000
}
Caddy, REST API üzerinden dinamik yapılandırma destekler:
# Mevcut yapılandırmayı görüntüle
curl http://localhost:2019/config/
# Yapılandırmayı güncelle
curl -X POST http://localhost:2019/load \
-H "Content-Type: application/json" \
-d @caddy.json
# Belirli bir route ekle
curl -X POST http://localhost:2019/config/apps/http/servers/srv0/routes \
-H "Content-Type: application/json" \
-d '{"handle":[{"handler":"static_response","body":"Merhaba!"}]}'
# Caddy'yi yeniden yükle (sıfır downtime)
caddy reload --config /etc/caddy/Caddyfile
# Yapılandırmayı doğrula
caddy validate --config /etc/caddy/Caddyfile
# Formatla
caddy fmt --overwrite /etc/caddy/Caddyfile
{
# Maksimum eşzamanlı bağlantı
servers {
max_header_size 1MB
timeouts {
read_body 10s
read_header 10s
write 30s
idle 2m
}
}
}
example.com {
# Sıkıştırma
encode {
gzip 6
zstd
minimum_length 1024
}
# Rate limiting (caddy-ratelimit modülü gerektirir)
rate_limit {
zone dynamic {
key {remote_host}
events 100
window 1m
}
}
reverse_proxy localhost:3000
}
Caddy, otomatik HTTPS yönetimi ve basit yapılandırması ile modern web sunucusu ihtiyaçlarını karşılar. Nginx veya Apache'ye kıyasla çok daha az yapılandırma gerektirirken, production ortamları için gerekli tüm özellikleri sunar. Özellikle Let's Encrypt sertifikası yönetimini otomatikleştirmek isteyenler için ideal bir seçimdir.
Caddy sertifikaları varsayılan olarak Linux'ta '/var/lib/caddy/.local/share/caddy/' dizininde saklar. Systemd servisi olarak çalışırken bu dizin otomatik oluşturulur. Docker kullanırken 'caddy_data' volume'unu kalıcı olarak bağlamanız gerekir, aksi takdirde her yeniden başlatmada yeni sertifika alınır.
Let's Encrypt, aynı domain için haftada 5 sertifika sınırı uygular. Test aşamasında 'acme_ca https://acme-staging-v02.api.letsencrypt.org/directory' ile staging ortamını kullanın. Staging sertifikaları tarayıcılar tarafından güvenilmez olarak işaretlenir ama rate limit yoktur. Production'a geçerken staging satırını kaldırın.
Caddy otomatik HTTPS yönetimi sunar ve yapılandırması çok daha basittir. Nginx daha fazla özelleştirme seçeneği ve daha geniş topluluk desteğine sahiptir. Caddy Go ile yazılmıştır ve HTTP/3 desteği varsayılan olarak gelir. Nginx C ile yazılmıştır ve çok yüksek trafikte daha iyi performans gösterebilir.
'sudo systemctl reload caddy' veya 'caddy reload --config /etc/caddy/Caddyfile' komutu ile sıfır downtime ile yeniden yükleyebilirsiniz. 'caddy validate' ile önce yapılandırmayı doğrulamanız önerilir. Hatalı yapılandırma yüklenirse Caddy eski yapılandırmaya geri döner.
Wildcard sertifika için DNS challenge gereklidir. Cloudflare kullanıyorsanız 'caddy-dns/cloudflare' modülünü ekleyin ve API token'ınızı ayarlayın. Caddyfile'da 'tls { dns cloudflare {env.CF_API_TOKEN} }' direktifini kullanın. xcaddy ile DNS provider modülünü dahil ederek özel build oluşturmanız gerekebilir.
Varsayılan olarak Admin API yalnızca localhost:2019'da dinler. Production'da bu portu dışarıya açmayın. Uzaktan yönetim gerekiyorsa 'admin 0.0.0.0:2019' yerine SSH tüneli kullanın. Alternatif olarak 'admin off' ile API'yi tamamen devre dışı bırakabilirsiniz.
Docker Compose ile çok konteynerli uygulama tanımlama, servis bağımlılıkları, environment variables, health check, scaling ve production deployment. Kapsamlı rehber.
GitHub Actions ile CI/CD pipeline oluşturma, Docker build ve push, SSH ile sunucuya deployment, test otomasyonu, secrets yönetimi ve workflow optimizasyonu.
Ansible kurulumu, inventory dosyası, playbook yazımı, rol yapısı, değişkenler, şifreli vault, ad-hoc komutlar ve sunucu yapılandırma otomasyonu. Adım adım rehber.