Wolkra

Guides

Configurer Caddy comme reverse proxy

Configurez Caddy comme reverse proxy sur Ubuntu ou Debian : HTTPS automatique, plusieurs applications sur un serveur, authentification basique, répartition de charge et vrais exemples de Caddyfile.

Mis à jour le 5 min de lecture

Un reverse proxy reçoit tout le trafic web sur les ports 80 et 443 et transmet chaque requête à la bonne application du serveur. Caddy est un bon choix, car il obtient et renouvelle lui-même les certificats HTTPS : une ligne comme reverse_proxy localhost:3000 par site suffit.

Ce guide installe Caddy sur Ubuntu 24.04 ou Debian 12 et construit la configuration étape par étape.

Pourquoi placer un proxy en frontal

  • Un point d'entrée unique. Plusieurs applications sur un même serveur, chacune sur son propre domaine ou chemin.
  • HTTPS au même endroit. Les applications parlent HTTP simple sur localhost ; Caddy gère le TLS.
  • Sécurité. Les applications n'écoutent jamais sur des ports publics. Vous pouvez ajouter en-têtes, limites de débit ou mot de passe au niveau du proxy.
  • Souplesse. Déplacez une application vers un autre port ou un autre serveur en changeant une seule ligne.

1. Prérequis

  • Un serveur sur lequel les premiers pas ont été effectués.
  • Des enregistrements DNS pour chaque domaine pointant vers le serveur (A pour l'IPv4, AAAA pour l'IPv6).
  • Les ports 80 et 443 ouverts :
bash
sudo ufw allow 80,443/tcp
sudo ufw allow 443/udp     # HTTP/3

Ouvrez les mêmes ports dans votre pare-feu cloud si vous en utilisez un.

2. Installer Caddy

bash
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
systemctl status caddy

Le paquet fait tourner Caddy comme service systemd, avec la configuration dans /etc/caddy/Caddyfile.

3. Le plus petit Caddyfile utile

Supposons qu'une application écoute sur localhost:3000. Remplacez le contenu du fichier par :

text
app.example.com {
    reverse_proxy localhost:3000
}

Validez et rechargez :

bash
sudo caddy fmt --overwrite /etc/caddy/Caddyfile
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy

À la première requête, Caddy obtient un certificat, redirige HTTP vers HTTPS et sert l'application. C'est tout.

4. Plusieurs applications sur un même serveur

Ajoutez un bloc par site :

text
app.example.com {
    reverse_proxy localhost:3000
}

api.example.com {
    reverse_proxy localhost:8080
}

status.example.com {
    reverse_proxy localhost:3001
}

Ou répartissez un même domaine par chemin :

text
example.com {
    handle_path /api/* {
        reverse_proxy localhost:8080
    }
    handle {
        root * /var/www/site
        file_server
    }
}

handle_path retire /api avant de transmettre la requête ; utilisez handle si le backend attend le préfixe.

5. Des réglages par défaut utiles grâce à un snippet

Les snippets regroupent en un seul endroit les réglages répétés :

text
(common) {
    encode zstd gzip
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Content-Type-Options "nosniff"
        Referrer-Policy "strict-origin-when-cross-origin"
        -Server
    }
    log {
        output file /var/log/caddy/access.log {
            roll_size 50MiB
            roll_keep 5
        }
    }
}

app.example.com {
    import common
    reverse_proxy localhost:3000
}

Créez une fois le répertoire des journaux : sudo mkdir -p /var/log/caddy && sudo chown caddy:caddy /var/log/caddy.

6. Protéger un outil d'administration par mot de passe

Générez une empreinte de mot de passe :

bash
caddy hash-password

Utilisez-la dans le bloc du site :

text
admin.example.com {
    basic_auth {
        alice <paste-hash-here>
    }
    reverse_proxy localhost:9000
}

Les anciennes versions de Caddy écrivent la directive basicauth. Pour tout ce qui est sensible, restreignez aussi par adresse :

text
admin.example.com {
    @outside not remote_ip 198.51.100.0/24
    respond @outside 403
    reverse_proxy localhost:9000
}

La plage est un exemple. Indiquez celle de votre bureau ou de votre VPN ; avec le guide WireGuard, il peut s'agir du sous-réseau de votre VPN.

7. Proxy vers des conteneurs Docker

Si Caddy tourne sur l'hôte, liez les conteneurs à localhost pour qu'ils ne soient pas publics :

yaml
services:
  app:
    image: ghcr.io/example/app:1.0
    ports:
      - "127.0.0.1:3000:3000"

Si Caddy tourne dans Docker, placez-le dans le même projet Compose et faites pointer le proxy vers les noms de services (reverse_proxy app:3000). Le guide Docker Compose présente une stack complète.

8. Répartir la charge entre plusieurs backends

Caddy peut répartir les requêtes entre plusieurs instances d'une application, sur le même serveur ou sur d'autres serveurs via un réseau privé :

text
app.example.com {
    reverse_proxy 10.0.0.11:3000 10.0.0.12:3000 {
        lb_policy least_conn
        health_uri /healthz
        health_interval 10s
    }
}

Les adresses sont des exemples sur une plage privée. Si vous préférez que la répartition se fasse en dehors de vos serveurs, un répartiteur de charge géré fait le même travail avec des contrôles de santé et peut atteindre des serveurs sans IP publique.

9. WebSockets et vraies IP des clients

Les WebSockets passent par reverse_proxy sans réglage supplémentaire. Caddy envoie X-Forwarded-For, X-Forwarded-Proto et X-Forwarded-Host au backend ; configurez votre application pour ne leur faire confiance que depuis 127.0.0.1.

Si Caddy se trouve lui-même derrière un autre proxy ou un répartiteur de charge, indiquez-lui les adresses de confiance :

text
{
    servers {
        trusted_proxies static 10.0.0.0/24
    }
}

Ce bloc global se place tout en haut du Caddyfile.

10. Journaux et dépannage

bash
journalctl -u caddy --since "10 min ago"
sudo tail -f /var/log/caddy/access.log
curl -I https://app.example.com

Problèmes fréquents :

Problème Solution
Certificat non émis Le DNS doit pointer vers ce serveur ; ports 80/443 ouverts dans UFW et dans le pare-feu cloud
502 Bad Gateway Le backend ne tourne pas ou écoute sur un autre port : ss -tlnp
Boucle de redirection L'application redirige aussi vers HTTPS ; laissez Caddy s'en charger et faites confiance à X-Forwarded-Proto
Modifications ignorées Lancez systemctl reload caddy et vérifiez la sortie de caddy validate

Les autorités de certification limitent les échecs répétés : corrigez le DNS avant de réessayer de nombreuses fois.

Redirections et domaine canonique

La plupart des sites devraient répondre sur un seul nom et rediriger les autres. Envoyez www vers le domaine nu :

text
www.example.com {
    redir https://example.com{uri} permanent
}

example.com {
    reverse_proxy localhost:3000
}

Caddy obtient des certificats pour les deux noms. Inversez-les si vous préférez www comme adresse principale.

Limitation de débit et taille des requêtes

Caddy garde un cœur léger, la limitation de débit nécessite donc un plugin. Pour la plupart des petits sites, Fail2ban sur le journal d'accès ou une limite dans l'application suffit. La limitation de la taille du corps des requêtes, elle, est intégrée :

text
app.example.com {
    request_body {
        max_size 20MB
    }
    reverse_proxy localhost:3000
}

Les envois trop volumineux sont ainsi arrêtés avant d'atteindre votre application.

Fichiers statiques à côté d'une application

Servir les ressources directement depuis le disque est plus rapide que de les faire passer par l'application :

text
app.example.com {
    handle /static/* {
        root * /var/www/app
        file_server
        header Cache-Control "public, max-age=604800"
    }
    handle {
        reverse_proxy localhost:3000
    }
}

11. Où sont stockés les certificats

Caddy stocke certificats et clés sous /var/lib/caddy/.local/share/caddy. Incluez ce chemin dans vos sauvegardes pour éviter de tout réémettre après une restauration, même si Caddy obtiendra simplement de nouveaux certificats si ce dossier manque.

Prochaines étapes

Avec Caddy en frontal, vous pouvez héberger de nombreuses applications sur un seul serveur. Les étapes suivantes typiques : WordPress, une stack Docker, ou un outil auto-hébergé issu de la page auto-hébergement. N'oubliez pas les bases de la sécurité ni les sauvegardes.

Questions fréquentes

Caddy obtient-il vraiment les certificats HTTPS automatiquement ?

Oui. Lorsqu'une adresse de site dans le Caddyfile est un domaine public qui pointe vers le serveur, et que les ports 80 et 443 sont joignables, Caddy obtient et renouvelle seul les certificats auprès d'une autorité ACME publique.

Caddy est-il assez rapide pour la production ?

Oui. Pour des applications web classiques, le reverse proxy est rarement le goulot d'étranglement, et Caddy prend en charge HTTP/2 et HTTP/3 d'emblée.

Caddy peut-il servir de proxy vers des applications dans Docker ?

Oui. Faites tourner Caddy dans le même réseau Compose et utilisez les noms de services, ou liez les conteneurs à 127.0.0.1 et faites pointer le proxy vers les ports locaux.

Caddy ou Nginx ?

Caddy demande moins de configuration et gère lui-même les certificats. Nginx dispose d'un écosystème d'exemples et de modules plus vaste. Les deux sont des choix solides.

Pourquoi Caddy n'arrive-t-il pas à obtenir un certificat ?

Le plus souvent, le DNS ne pointe pas encore vers le serveur, ou le port 80 ou 443 est bloqué par un pare-feu. Vérifiez les deux, puis consultez journalctl -u caddy.

Lancer un serveur à Francfort

Créez un compte, rechargez votre solde et lancez un serveur dès €3.49 par mois, en ne payant que les heures utilisées. Bande passante non mesurée sur toutes les offres.