Caddy : reverse proxy HTTPS automatique

Caddy : reverse proxy HTTPS automatique

Caddy fait du reverse proxy HTTPS sans aucune config manuelle de certificats. ACME, HTTP/2, HTTP/3, gzip, brotli, OCSP, automatique. Le serveur web "qui juste marche".

Caddy : reverse proxy HTTPS automatique

Caddy fait du reverse proxy HTTPS sans aucune config manuelle de certificats. ACME, HTTP/2, HTTP/3, gzip, brotli, OCSP, automatique. Le serveur web "qui juste marche".

Introduction

Caddy est un serveur web moderne ecrit en Go avec une obsession : zero config pour HTTPS. Concretement :

  • Obtient automatiquement des certificats Let's Encrypt / ZeroSSL
  • Renouvelle automatiquement avant expiration
  • HTTPS active par defaut
  • HTTP/2 et HTTP/3 (QUIC) actives par defaut
  • Reverse proxy simple a configurer
  • Syntaxe Caddyfile ultra-lisible
  • Hot-reload sans downtime

Idеal pour : sites perso, dev, prod simple, prototypage rapide. Pour les configs complexes, Nginx reste la reference.

Prerequis

  • VPS Linux
  • Ports 80 et 443 ouverts (necessaire pour ACME)
  • Nom de domaine pointant vers le VPS
  • Acces root

Etape 1 : Installation

Sur Debian / Ubuntu

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 apt update
sudo apt install -y caddy

Verifier

caddy version
sudo systemctl status caddy

Etape 2 : Le Caddyfile

Toute la config tient dans /etc/caddy/Caddyfile :

votre-domaine.fr {
    respond "Hello, World!"
}

Reload :

sudo systemctl reload caddy

Visitez https://votre-domaine.fr : Caddy a obtenu un certificat Let's Encrypt automatiquement et sert "Hello, World!" en HTTPS.

⚠️ Aucune config SSL ! Caddy s'occupe de tout.

Etape 3 : Servir des fichiers statiques

votre-domaine.fr {
    root * /var/www/html
    file_server
}

Avec listing du dossier :

votre-domaine.fr {
    root * /var/www/html
    file_server browse
}

Etape 4 : Reverse proxy vers une app

Imaginons une app Node.js sur le port 3000 :

api.votre-domaine.fr {
    reverse_proxy localhost:3000
}

Et c'est tout. HTTPS, HTTP/2, HTTP/3, redirection 80 -> 443. Tout est gere.

Multiple backends (load balancing) :

api.votre-domaine.fr {
    reverse_proxy backend1:3000 backend2:3000 backend3:3000 {
        lb_policy round_robin
        health_uri /healthz
        health_interval 10s
    }
}

Etape 5 : Multi-sites

site1.fr {
    root * /var/www/site1
    file_server
}

site2.fr {
    reverse_proxy localhost:8000
}

api.site2.fr {
    reverse_proxy backend:3000
}

Chaque site a son propre certificat automatique.

Etape 6 : Configurations avancees

PHP avec PHP-FPM

votre-domaine.fr {
    root * /var/www/html
    php_fastcgi unix//run/php/php8.2-fpm.sock
    file_server
}

Caddy gere le routing index.php automatiquement.

Compression

Activee par defaut (gzip + zstd). Pour ajouter brotli :

votre-domaine.fr {
    encode gzip zstd
    reverse_proxy localhost:3000
}

Headers de securite

votre-domaine.fr {
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "SAMEORIGIN"
        Referrer-Policy "strict-origin-when-cross-origin"
        Permissions-Policy "geolocation=()"
    }
    reverse_proxy localhost:3000
}

Rate limiting

Caddy ne supporte pas le rate limiting nativement (sans plugin). Pour ca, utilisez le plugin officiel caddy-ratelimit :

sudo caddy add-package github.com/mholt/caddy-ratelimit

Puis :

votre-domaine.fr {
    rate_limit {
        zone main {
            key {client_ip}
            events 100
            window 1m
        }
    }
    reverse_proxy localhost:3000
}

Etape 7 : Wildcard certificate

Pour *.votre-domaine.fr, vous avez besoin de DNS-01 challenge. Caddy supporte de nombreux providers via plugins :

sudo caddy add-package github.com/caddy-dns/cloudflare
*.votre-domaine.fr {
    tls {
        dns cloudflare votre_token_cloudflare
    }
    
    @app1 host app1.votre-domaine.fr
    handle @app1 {
        reverse_proxy localhost:3001
    }
    
    @app2 host app2.votre-domaine.fr
    handle @app2 {
        reverse_proxy localhost:3002
    }
}

Etape 8 : Logging

votre-domaine.fr {
    log {
        output file /var/log/caddy/access.log {
            roll_size 100mb
            roll_keep 10
        }
        format json
    }
    reverse_proxy localhost:3000
}

Parser :

sudo tail -f /var/log/caddy/access.log | jq

Etape 9 : Basic auth

admin.votre-domaine.fr {
    basicauth /* {
        admin $2a$14$Zkx19XLiW6VYouLHR5NmfO...
    }
    reverse_proxy localhost:8080
}

Generer le hash :

caddy hash-password

Etape 10 : WebSockets

Aucune config supplementaire :

ws.votre-domaine.fr {
    reverse_proxy localhost:3000
}

WebSockets transitent transparent.

Etape 11 : API admin

Caddy expose une API REST sur :2019 (localhost only par defaut) pour piloter dynamiquement :

# Voir la config courante
curl localhost:2019/config/ | jq

# Update une route sans reload
curl -X POST localhost:2019/config/apps/http/servers/srv0/routes \
    -H "Content-Type: application/json" \
    -d '{"match": [{"host": ["new.example.com"]}], "handle": [{"handler": "reverse_proxy", "upstreams": [{"dial": "localhost:9000"}]}]}'

Etape 12 : Migration depuis Nginx

Caddy lit la conf Nginx via :

caddy adapt --config /etc/nginx/sites-available/mon-site --adapter nginxconf

Vous obtenez un Caddyfile equivalent. Verifiez manuellement avant deploiement.

Depannage

Certificat ne se genere pas

Verifiez :

  • Le port 80 est ouvert (HTTP-01)
  • Le DNS du domaine pointe bien vers le VPS
  • Pas d'autre service sur 80 (sinon Caddy ne peut pas faire HTTP-01)

Logs :

sudo journalctl -u caddy -f

502 Bad Gateway sur reverse_proxy

Le backend est down ou non joignable. Verifiez :

curl http://localhost:3000

"address already in use"

Un autre service utilise le 80/443 (Nginx, Apache). Stoppez-le ou utilisez d'autres ports.

Rate limit depasse par Let's Encrypt

Trop de tests. Passez en staging temporairement :

votre-domaine.fr {
    tls {
        ca https://acme-staging-v02.api.letsencrypt.org/directory
    }
}

Commandes utiles

# Status
sudo systemctl status caddy

# Reload sans downtime
sudo systemctl reload caddy

# Tester le Caddyfile
caddy validate --config /etc/caddy/Caddyfile

# Format / normaliser le Caddyfile
caddy fmt /etc/caddy/Caddyfile --overwrite

# Logs
sudo journalctl -u caddy -f

# Lister les certs
ls /var/lib/caddy/.local/share/caddy/certificates/

# Forcer le renouvellement
sudo caddy reload --config /etc/caddy/Caddyfile

# Voir la config courante via API
curl localhost:2019/config/

Conclusion

Caddy est :

  • Le serveur web "qui juste marche" (no SSL config needed)
  • Adapte aux sites simples a moyens
  • Tres rapide pour prototyper
  • Plugins riches (DNS providers, rate limit, WAF, etc.)

Limites : pour des configs Nginx complexes (regex, locations imbriquees, OpenResty, scripting Lua), Nginx reste plus adapte.

Pour aller plus loin :

Ressources

Join our Discord community server

For any questions, suggestions, or just to chat with the community, join us on Discord!

900+Members