Docker Compose Leitfaden: Verwaltung von Multi-Container-Anwendungen
Multi-Container-Anwendungen mit Docker Compose definieren: Service-Abhängigkeiten, Umgebungsvariablen, Health Checks, Skalierung und Production-Deployment.
Caddy-Webserver installieren: Caddyfile-Konfiguration, automatisches Let's Encrypt SSL, Reverse Proxy, statische Websites, PHP-FPM-Integration und Tuning.
Caddy ist ein moderner Webserver, der sich durch automatisches HTTPS-Zertifikatmanagement auszeichnet. Dank der Let's Encrypt-Integration erhält, erneuert und konfiguriert er SSL-Zertifikate automatisch.
Herausragende Merkmale von Caddy:
Caddy benötigt Root-Rechte für die Ports 80 und 443. Dies wird automatisch verwaltet, wenn es als systemd-Dienst ausgeführt wird.
# Caddy GPG-Schlüssel und Repository hinzufügen
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 installieren
sudo apt update
sudo apt install caddy -y
# Dienststatus prüfen
sudo systemctl status caddy
# Neueste Version herunterladen
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
# Entpacken und installieren
tar -xzf caddy.tar.gz
sudo mv caddy /usr/local/bin/
sudo chmod +x /usr/local/bin/caddy
# Version prüfen
caddy version
# xcaddy installieren
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
# Mit zusätzlichen Modulen kompilieren
xcaddy build \
--with github.com/caddy-dns/cloudflare \
--with github.com/greenpau/caddy-security
# Einzelne Website
example.com {
root * /var/www/html
file_server
}
# Mehrere Websites
example.com {
respond "Hallo example.com!"
}
api.example.com {
reverse_proxy localhost:3000
}
# Globale Einstellungen am Anfang der Caddyfile
{
# Admin API Port
admin localhost:2019
# E-Mail (für Let's Encrypt)
email admin@example.com
# ACME-Server (Staging zum Testen)
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
# HTTP-Port
http_port 80
# HTTPS-Port
https_port 443
# Log-Format
log {
output file /var/log/caddy/access.log
format json
}
}
Caddy erhält automatisch ein Let's Encrypt-Zertifikat für Ihre Domain:
# Schreiben Sie einfach den Domainnamen - HTTPS ist automatisch!
example.com {
root * /var/www/html
file_server
encode gzip
}
# www-Weiterleitung
www.example.com {
redir https://example.com{uri} permanent
}
# Wildcard-Zertifikat (erfordert DNS-Challenge)
*.example.com {
tls {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
@api host api.example.com
handle @api {
reverse_proxy localhost:3000
}
}
Caddy erneuert Zertifikate automatisch. Kein manueller Eingriff erforderlich. Zertifikate werden in ~/.local/share/caddy/ oder /var/lib/caddy/ gespeichert.
app.example.com {
reverse_proxy localhost:3000
}
# Mehrere Upstreams (Load Balancing)
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 weiterleiten
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}
# Timeouts
transport http {
dial_timeout 5s
response_header_timeout 30s
}
# Wiederholung
lb_retries 3
lb_try_duration 5s
}
# Sicherheits-Header
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 {
# Verzeichnisliste
browse
# Versteckte Dateien ausblenden
hide .git .env
}
encode gzip zstd
# Cache-Header
header /assets/* Cache-Control "public, max-age=31536000, immutable"
header /*.html Cache-Control "no-cache"
# Fehlerseiten
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-Dateien an PHP-FPM weiterleiten
php_fastcgi unix//run/php/php8.2-fpm.sock
# Oder über TCP
# php_fastcgi localhost:9000
file_server
# Für WordPress
@notStatic {
not path /wp-content/* /wp-includes/*
not file
}
rewrite @notStatic /index.php
}
# Vollständige WordPress-Konfiguration
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:
Caddy unterstützt dynamische Konfiguration über REST API:
# Aktuelle Konfiguration anzeigen
curl http://localhost:2019/config/
# Konfiguration aktualisieren
curl -X POST http://localhost:2019/load \
-H "Content-Type: application/json" \
-d @caddy.json
# Caddy neu laden (Zero Downtime)
caddy reload --config /etc/caddy/Caddyfile
# Konfiguration validieren
caddy validate --config /etc/caddy/Caddyfile
# Caddyfile formatieren
caddy fmt --overwrite /etc/caddy/Caddyfile
{
servers {
max_header_size 1MB
timeouts {
read_body 10s
read_header 10s
write 30s
idle 2m
}
}
}
example.com {
# Komprimierung
encode {
gzip 6
zstd
minimum_length 1024
}
reverse_proxy localhost:3000
}
Caddy erfüllt moderne Webserver-Anforderungen mit automatischem HTTPS-Management und einfacher Konfiguration. Es erfordert viel weniger Konfiguration als Nginx oder Apache und bietet dabei alle für Produktionsumgebungen notwendigen Funktionen. Es ist besonders ideal für alle, die das Let's Encrypt-Zertifikatmanagement automatisieren möchten.
Caddy speichert Zertifikate standardmäßig unter Linux in '/var/lib/caddy/.local/share/caddy/'. Dieses Verzeichnis wird automatisch erstellt, wenn es als systemd-Dienst ausgeführt wird. Bei Docker müssen Sie das 'caddy_data'-Volume dauerhaft einbinden, sonst wird bei jedem Neustart ein neues Zertifikat angefordert.
Let's Encrypt begrenzt auf 5 Zertifikate pro Woche für dieselbe Domain. Verwenden Sie während des Tests die Staging-Umgebung mit 'acme_ca https://acme-staging-v02.api.letsencrypt.org/directory'. Staging-Zertifikate werden von Browsern als nicht vertrauenswürdig markiert, haben aber kein Rate-Limit. Entfernen Sie die Staging-Zeile beim Wechsel zur Production.
Caddy bietet automatisches HTTPS-Management und viel einfachere Konfiguration. Nginx hat mehr Anpassungsoptionen und breiteren Community-Support. Caddy ist in Go geschrieben und kommt standardmäßig mit HTTP/3-Unterstützung. Nginx ist in C geschrieben und kann bei sehr hohem Traffic besser performen.
Sie können mit 'sudo systemctl reload caddy' oder 'caddy reload --config /etc/caddy/Caddyfile' ohne Downtime neu laden. Es wird empfohlen, die Konfiguration zuerst mit 'caddy validate' zu validieren. Wenn eine ungültige Konfiguration geladen wird, kehrt Caddy zur vorherigen Konfiguration zurück.
Wildcard-Zertifikate erfordern eine DNS-Challenge. Bei Cloudflare fügen Sie das Modul 'caddy-dns/cloudflare' hinzu und setzen Ihren API-Token. Verwenden Sie die Direktive 'tls { dns cloudflare {env.CF_API_TOKEN} }' in der Caddyfile. Möglicherweise müssen Sie mit xcaddy einen benutzerdefinierten Build mit dem DNS-Provider-Modul erstellen.
Standardmäßig lauscht die Admin API nur auf localhost:2019. Öffnen Sie diesen Port in der Production nicht nach außen. Wenn Remote-Verwaltung benötigt wird, verwenden Sie einen SSH-Tunnel statt 'admin 0.0.0.0:2019'. Alternativ können Sie die API mit 'admin off' vollständig deaktivieren.
Multi-Container-Anwendungen mit Docker Compose definieren: Service-Abhängigkeiten, Umgebungsvariablen, Health Checks, Skalierung und Production-Deployment.
CI/CD-Pipelines mit GitHub Actions erstellen: Docker Build und Push, SSH-Server-Deployment, Test-Automatisierung, Secrets-Verwaltung und Workflow-Optimierung.
Ansible Schritt für Schritt: Installation, Inventory, Playbooks, Rollen, Variablen, verschlüsselter Vault, Ad-hoc-Befehle und Serverautomatisierung.