TL;DR — Résumé Rapide

Guide complet sur Caddy en reverse proxy avec HTTPS automatique. Configurez SSL, équilibrage de charge, contrôles de santé et hébergement multi-site.

Caddy est un serveur web en Go qui fait du HTTPS automatique le comportement par défaut — pas une tâche supplémentaire. Contrairement à Nginx ou Apache où TLS signifie installer certbot, écrire des scripts de renouvellement et déboguer des cron jobs, Caddy négocie les certificats avec Let’s Encrypt ou ZeroSSL dès que vous ajoutez un domaine à votre configuration.

Prérequis

  • Un serveur Linux (Ubuntu 22.04/24.04, Debian, RHEL ou Docker).
  • Un domaine avec des enregistrements DNS A pointant vers l’IP publique de votre serveur.
  • Les ports 80 et 443 ouverts dans le pare-feu — Caddy en a besoin pour le défi ACME HTTP-01.
  • Des services backend tournant sur des ports localhost (Node.js, Python, PHP, etc.).

Architecture de Caddy

Caddy est un binaire statique unique écrit en Go sans dépendances d’exécution.

HTTPS automatique via ACME. Quand vous configurez un domaine, Caddy :

  1. Détecte que le domaine nécessite un certificat.
  2. Exécute un défi ACME HTTP-01 ou TLS-ALPN-01.
  3. Stocke le certificat dans ~/.local/share/caddy/ (ou /var/lib/caddy/ pour les installations système).
  4. Programme le renouvellement 30 jours avant expiration — automatiquement.
  5. Ajoute des réponses OCSP aux handshakes TLS pour des vérifications de révocation plus rapides.

API d’administration. Caddy expose une API REST sur localhost:2019 pour des changements de configuration en direct — sans redémarrage nécessaire.


Installation

apt (Ubuntu/Debian — recommandé)

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 caddy

Docker

docker run -d \
  --name caddy \
  -p 80:80 -p 443:443 -p 443:443/udp \
  -v $PWD/Caddyfile:/etc/caddy/Caddyfile \
  -v caddy_data:/data \
  caddy:latest

xcaddy — Compilations Personnalisées avec Plugins

xcaddy build \
  --with github.com/caddy-dns/cloudflare \
  --with github.com/mholt/caddy-ratelimit

Syntaxe du Caddyfile

Blocs de site :

example.com {
    reverse_proxy localhost:3000
}

Options globales :

{
    email admin@example.com
}

Snippets réutilisables :

(en_tetes_communs) {
    header {
        X-Content-Type-Options nosniff
        X-Frame-Options DENY
        -Server
    }
}

example.com {
    import en_tetes_communs
    reverse_proxy localhost:3000
}

Configuration du Reverse Proxy

Reverse Proxy Basique

example.com {
    reverse_proxy localhost:3000
}

Caddy gère automatiquement la redirection HTTP→HTTPS, l’émission du certificat, le renouvellement et l’agrafage OCSP.

Équilibrage de Charge

example.com {
    reverse_proxy app1:3000 app2:3000 app3:3000 {
        lb_policy round_robin
    }
}
PolitiqueDescription
round_robinDistribue les requêtes uniformément entre les backends
least_connDirige vers le backend avec le moins de connexions actives
ip_hashHash de l’IP client pour des sessions persistantes
cookieUtilise un cookie pour la persistance de session
uri_hashHash de l’URI de la requête

Contrôles de Santé Actifs et Passifs

example.com {
    reverse_proxy app1:3000 app2:3000 {
        lb_policy least_conn
        health_uri /health
        health_interval 10s
        health_timeout 5s
        fail_duration 30s
        max_fails 3
    }
}

Manipulation des En-têtes

example.com {
    reverse_proxy localhost:3000 {
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-Proto {scheme}
        header_down -Server
        header_down -X-Powered-By
    }
}

HTTPS Automatique en Profondeur

Comment Caddy Obtient les Certificats

  1. Une requête arrive pour example.com.
  2. Caddy vérifie son magasin de certificats — aucun trouvé.
  3. Caddy exécute un défi ACME HTTP-01.
  4. Le serveur ACME (Let’s Encrypt) vérifie le token.
  5. Caddy reçoit le certificat signé et le stocke.
  6. HTTP redirige automatiquement vers HTTPS.
  7. Caddy renouvelle le certificat 30 jours avant expiration.

TLS à la Demande

Pour les plateformes SaaS où les utilisateurs ajoutent des domaines personnalisés :

{
    on_demand_tls {
        ask http://localhost:8080/verifier-domaine
        interval 2m
        burst 5
    }
}

CA Interne pour le Développement Local

localhost {
    tls internal
    reverse_proxy localhost:3000
}

Exécutez caddy trust pour installer la CA locale de Caddy dans le magasin de confiance du système.


Patterns Courants du Caddyfile

SPA avec Routage Côté Client

app.example.com {
    root * /var/www/app
    try_files {path} /index.html
    file_server
}

PHP avec PHP-FPM

php.example.com {
    root * /var/www/php-app
    php_fastcgi unix//run/php/php8.3-fpm.sock
    file_server
}

Caddy vs Nginx vs Traefik vs HAProxy

FonctionnalitéCaddyNginxTraefikHAProxy
HTTPS automatiqueIntégré, par défautManuel (certbot)IntégréManuel
Syntaxe de configurationCaddyfile simplenginx.conf complexeYAML/TOMLComplexe
Rechargement en directOui (API + signal)Oui (signal)OuiOui
Équilibrage de charge8 politiquesRound-robin, IP hashMultiplesExtensif
API d’administrationREST JSONNonREST JSONSocket
HTTP/3 (QUIC)OuiOui (v1.25+)OuiNon
Meilleur pourHTTPS automatique, simplicitéFichiers statiques haute perfDocker/K8sÉquilibrage TCP

Caddyfile de Production : Hébergement Multi-Site

{
    email ops@example.com
    admin localhost:2019
}

(en_tetes_securite) {
    header {
        X-Content-Type-Options nosniff
        X-Frame-Options SAMEORIGIN
        Referrer-Policy strict-origin-when-cross-origin
        -Server
    }
}

app.example.com {
    import en_tetes_securite
    encode gzip zstd

    reverse_proxy app1:3000 app2:3000 {
        lb_policy least_conn
        health_uri /health
        health_interval 15s
        fail_duration 30s
    }
}

api.example.com {
    import en_tetes_securite
    reverse_proxy localhost:8080 {
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }
}

www.example.com {
    import en_tetes_securite
    encode gzip zstd
    root * /var/www/marketing
    try_files {path} /index.html
    file_server
}

Pièges et Cas Particuliers

  • Le port 80 doit être accessible. Caddy utilise le défi ACME HTTP-01. Si le port 80 est bloqué, utilisez le défi DNS-01 avec un plugin DNS via xcaddy.
  • Limites de débit sur Let’s Encrypt. Maximum 50 certificats par domaine par semaine. Utilisez la CA de staging pendant les tests.
  • header_up Host peut casser certains backends. Testez d’abord sans cette directive.
  • L’API d’administration est localhost uniquement par défaut. N’exposez jamais le port 2019 publiquement.
  • Rechargement vs redémarrage. Utilisez toujours systemctl reload caddy en production.

Résumé

  • HTTPS automatique — Caddy obtient et renouvelle les certificats Let’s Encrypt/ZeroSSL sans configuration.
  • Syntaxe simple — Cinq lignes dans le Caddyfile remplacent des centaines de lignes de configuration Nginx.
  • 8 politiques d’équilibrage de charge — incluant les sessions persistantes via cookie et IP hash.
  • Contrôles de santé actifs et passifs — supprime et réintègre automatiquement les backends défaillants.
  • TLS à la demande — émet des certificats dynamiquement pour les domaines des utilisateurs.
  • API REST d’administration — changements de configuration en direct sur localhost:2019 sans redémarrages.

Articles Connexes