Caddy est un serveur web moderne et open source ecrit en Go qui se distingue par une fonctionnalite majeure : le HTTPS automatique. Alors que les serveurs web traditionnels comme Nginx et Apache necessitent une configuration manuelle des certificats avec Certbot ou des outils similaires, Caddy obtient et renouvelle les certificats TLS aupres de Let’s Encrypt des que vous pointez un domaine vers lui. Combine avec sa syntaxe de configuration minimale, son reverse proxy integre et son support HTTP/3, Caddy est devenu le choix privilegie des developpeurs qui souhaitent un service web securise et pret pour la production avec le minimum d’effort.
Qu’est-ce que Caddy ?
Caddy est une plateforme de serveur web extensible qui privilegie la facilite d’utilisation et les parametres de securite par defaut. Il a ete cree par Matt Holt en 2015 et est distribue sous la forme d’un binaire unique compile statiquement, sans aucune dependance externe.
Caracteristiques principales de Caddy :
- HTTPS automatique — Provisionne et renouvelle les certificats TLS de Let’s Encrypt ou ZeroSSL sans aucune configuration
- HTTP/2 et HTTP/3 — Actives par defaut pour tous les sites HTTPS
- Reverse proxy — Reverse proxy integre avec equilibrage de charge, verifications de sante et manipulation des en-tetes
- Mode sans configuration — Un Caddyfile simple de deux lignes peut servir un site entier en HTTPS
- Multiplateforme — Fonctionne sous Linux, macOS, Windows et BSD
- Ecosysteme de plugins — Etendez les fonctionnalites avec des modules pour les fournisseurs DNS, l’authentification, la limitation de debit et plus encore
Caddy est distribue sous la licence Apache 2.0 et est gratuit pour un usage personnel comme commercial.
Caddy vs Nginx
Si vous utilisez actuellement Nginx et que vous vous demandez si Caddy convient a votre projet, voici une comparaison directe :
| Caracteristique | Caddy | Nginx |
|---|---|---|
| HTTPS | Automatique (client ACME integre) | Manuel (necessite Certbot ou similaire) |
| Syntaxe de configuration | Caddyfile (minimale, lisible) | nginx.conf (puissant mais verbeux) |
| HTTP/2 | Active par defaut | Necessite une configuration explicite |
| HTTP/3 (QUIC) | Integre, active par defaut | Experimental (necessite un build separe) |
| Reverse proxy | Directive integree | Module integre |
| Equilibrage de charge | Integre avec plusieurs politiques | Integre (round-robin, least_conn, etc.) |
| Rechargement de config | Sans interruption via API ou SIGHUP | Sans interruption via nginx -s reload |
| Langage | Go (sur en memoire) | C (haute performance) |
| Utilisation memoire | Faible (~20-50 Mo) | Tres faible (~5-15 Mo) |
| Debit brut | Tres bon | Excellent (gere des millions de RPS) |
| Communaute et ecosysteme | En croissance rapide | Massif, des decennies de documentation |
Quand choisir Caddy : Vous voulez le HTTPS automatique, une configuration minimale et un ensemble de fonctionnalites modernes sans gestion manuelle des certificats. Ideal pour les applications auto-hebergees, les projets personnels et les deploiements de petite a moyenne envergure.
Quand choisir Nginx : Vous avez besoin d’un controle extremement granulaire, d’un debit brut maximal pour des millions de connexions simultanees, ou d’une compatibilite etendue avec les modules issus de decennies de developpement de l’ecosysteme.
Prerequis
Avant d’installer Caddy, assurez-vous de disposer de :
- Un serveur Linux sous Ubuntu 22.04+ ou Debian 12+ (d’autres distributions sont egalement supportees)
- Un nom de domaine avec des enregistrements DNS A/AAAA pointant vers l’adresse IP publique de votre serveur
- Les ports 80 et 443 ouverts dans votre pare-feu (necessaires pour le defi ACME HTTP et le HTTPS)
- Un acces root ou sudo au serveur
- Aucun autre serveur web (Nginx, Apache) n’ecoutant sur les ports 80/443
Verifiez que votre pare-feu autorise les ports requis :
# Si vous utilisez UFW
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status
Installer Caddy sur Ubuntu
La methode d’installation recommandee utilise le depot APT officiel de Caddy, qui fournit des mises a jour automatiques :
# Installer les dependances requises
sudo apt update
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
# Ajouter la cle GPG de Caddy
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
# Ajouter le depot Caddy
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
# Installer Caddy
sudo apt update
sudo apt install -y caddy
Verifiez l’installation :
caddy version
Vous devriez voir une sortie du type v2.8.4 h1:... confirmant que Caddy est installe. L’installation du paquet cree egalement un service systemd, un Caddyfile par defaut dans /etc/caddy/Caddyfile, et un utilisateur caddy pour executer le processus.
Alternative : Installation depuis le Binaire
Si vous preferez une installation manuelle ou avez besoin d’une version specifique :
# Telecharger la derniere version
curl -Lo caddy.tar.gz "https://github.com/caddyserver/caddy/releases/latest/download/caddy_2.8.4_linux_amd64.tar.gz"
# Extraire et deplacer dans le PATH
tar xzf caddy.tar.gz
sudo mv caddy /usr/bin/caddy
sudo chmod +x /usr/bin/caddy
# Verifier
caddy version
Comprendre le Caddyfile
Le Caddyfile est le fichier de configuration de Caddy. Sa syntaxe est volontairement minimale — vous decrivez ce que vous voulez, pas comment y parvenir. Caddy se charge de remplir les valeurs par defaut raisonnables.
Le Caddyfile se trouve dans /etc/caddy/Caddyfile lorsqu’il est installe via le gestionnaire de paquets. Voici la structure de base :
# Options globales (facultatif)
{
email admin@example.com
}
# Bloc du site
example.com {
root * /var/www/html
file_server
}
Concepts cles :
- Adresse du site — Le domaine ou l’IP avant l’accolade ouvrante. L’utilisation d’un nom de domaine declenche automatiquement le HTTPS.
- Directives — Les commandes a l’interieur du bloc du site comme
root,file_server,reverse_proxy. - Options globales — Les parametres a l’interieur d’un bloc
{}de niveau superieur sans adresse. Utilises pour l’email (pour l’enregistrement ACME), les parametres de journalisation, etc. - Matchers — Les motifs comme
*ou/api/*qui controlent a quelles requetes une directive s’applique.
Apres avoir modifie le Caddyfile, validez et rechargez :
# Valider la syntaxe
caddy validate --config /etc/caddy/Caddyfile
# Recharger sans temps d'arret
sudo systemctl reload caddy
Servir des Fichiers Statiques
Servir un site web statique avec Caddy ne necessite que quelques lignes :
example.com {
root * /var/www/mysite
file_server
}
C’est tout. Caddy va :
- Obtenir un certificat TLS pour
example.comautomatiquement - Servir les fichiers depuis
/var/www/mysite - Activer HTTP/2 et HTTP/3
- Rediriger HTTP vers HTTPS
Pour une configuration de site statique plus complete avec compression et mise en cache :
example.com {
root * /var/www/mysite
# Activer la compression gzip et zstd
encode gzip zstd
# Servir les fichiers statiques avec la navigation de repertoire desactivee
file_server {
hide .git .env
}
# Pages d'erreur personnalisees
handle_errors {
rewrite * /{err.status_code}.html
file_server
}
# Cache pour les ressources statiques
@static path *.css *.js *.png *.jpg *.gif *.svg *.woff2
header @static Cache-Control "public, max-age=2592000, immutable"
# En-tetes de securite
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}
}
Creez le repertoire racine web et une page de test :
sudo mkdir -p /var/www/mysite
echo '<h1>Hello from Caddy</h1>' | sudo tee /var/www/mysite/index.html
sudo chown -R caddy:caddy /var/www/mysite
HTTPS Automatique
Le HTTPS automatique est la fonctionnalite phare de Caddy. Comprendre son fonctionnement vous aide a diagnostiquer les problemes et a personnaliser le comportement.
Comment ca Fonctionne
Lorsque Caddy rencontre un bloc de site avec un nom de domaine public (ni localhost ni une IP), il effectue automatiquement :
- Verification DNS — Verifie que le domaine pointe vers l’IP publique du serveur
- Demande de certificat — Contacte Let’s Encrypt (ou ZeroSSL en secours) via le protocole ACME
- Completion du defi HTTP-01 — Prouve la propriete du domaine en servant un jeton sur le port 80
- Installation du certificat — Configure TLS avec le certificat et la cle obtenus
- Redirection HTTP vers HTTPS — Cree une redirection automatique sur le port 80
- Planification du renouvellement — Renouvelle le certificat avant son expiration (generalement 30 jours a l’avance)
Le Protocole ACME
ACME (Automatic Certificate Management Environment) est le protocole utilise par Let’s Encrypt pour verifier la propriete d’un domaine. Caddy inclut un client ACME complet qui supporte :
- Defi HTTP-01 — Sert un fichier de jeton via HTTP sur le port 80 (par defaut)
- Defi TLS-ALPN-01 — Utilise la negociation TLS sur le port 443
- Defi DNS-01 — Cree un enregistrement TXT DNS (necessite un plugin de fournisseur DNS)
Configurer l’Email ACME
Definissez une adresse email pour les notifications d’expiration des certificats et l’enregistrement du compte :
{
email admin@example.com
}
example.com {
reverse_proxy localhost:3000
}
Utiliser une CA de Staging pour les Tests
Pendant le developpement, utilisez l’environnement de staging de Let’s Encrypt pour eviter les limites de debit :
{
acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}
example.com {
reverse_proxy localhost:3000
}
Important : Les certificats de staging ne sont pas approuves par les navigateurs. Supprimez la directive
acme_calors du passage en production.
Certificats Internes (Auto-signes)
Pour le developpement local ou les services internes qui n’ont pas besoin de certificats publics :
{
local_certs
}
localhost {
reverse_proxy localhost:3000
}
Caddy generera un certificat auto-signe et installera son autorite de certification racine dans le magasin de confiance du systeme pour que les navigateurs l’acceptent localement.
Configuration du Reverse Proxy
La directive reverse_proxy de Caddy fournit un reverse proxy complet avec une configuration minimale.
Reverse Proxy Basique
app.example.com {
reverse_proxy localhost:3000
}
Cette unique ligne redirige tout le trafic de app.example.com vers un backend sur le port 3000, avec HTTPS automatique, HTTP/2 et un transfert correct des en-tetes.
Plusieurs Backends sur un Domaine
Utilisez le routage par chemin pour rediriger differents chemins vers differents backends :
example.com {
reverse_proxy /api/* localhost:8000
reverse_proxy /admin/* localhost:9000
# Tout le reste sert des fichiers statiques
root * /var/www/frontend
file_server
}
Plusieurs Domaines (Hotes Virtuels)
app.example.com {
reverse_proxy localhost:3000
}
api.example.com {
reverse_proxy localhost:8000
}
admin.example.com {
reverse_proxy localhost:9000 {
header_up X-Custom-Header "admin-panel"
}
}
Chaque domaine obtient automatiquement son propre certificat TLS.
Preserver les Informations du Client
Caddy definit automatiquement les en-tetes X-Forwarded-For, X-Forwarded-Proto et X-Forwarded-Host. Vous pouvez ajouter ou remplacer des en-tetes :
app.example.com {
reverse_proxy localhost:3000 {
header_up Host {upstream_hostport}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-Port {server_port}
}
}
Support WebSocket
Caddy redirige les connexions WebSocket de maniere transparente — aucune configuration supplementaire n’est necessaire :
ws.example.com {
reverse_proxy localhost:4000
}
Les en-tetes Upgrade et Connection sont geres automatiquement par le reverse proxy de Caddy.
Equilibrage de Charge
Caddy supporte l’equilibrage de charge entre plusieurs instances backend avec differentes politiques.
Round-Robin (Par Defaut)
app.example.com {
reverse_proxy localhost:3001 localhost:3002 localhost:3003
}
Politiques d’Equilibrage de Charge
app.example.com {
reverse_proxy localhost:3001 localhost:3002 localhost:3003 {
lb_policy least_conn
}
}
Politiques disponibles :
| Politique | Description |
|---|---|
random | Choisit un backend au hasard |
least_conn | Envoie vers le backend avec le moins de connexions actives |
round_robin | Parcourt les backends de maniere sequentielle (par defaut) |
first | Utilise toujours le premier backend disponible |
ip_hash | Route selon l’IP du client pour l’affinite de session |
uri_hash | Route selon l’URI de la requete |
header | Route selon la valeur d’un en-tete de requete |
cookie | Route selon la valeur d’un cookie pour la persistance de session |
Verifications de Sante
Activez les verifications de sante actives pour detecter et retirer les backends defaillants :
app.example.com {
reverse_proxy localhost:3001 localhost:3002 localhost:3003 {
lb_policy least_conn
health_uri /health
health_interval 10s
health_timeout 5s
health_status 200
# Verifications de sante passives
fail_duration 30s
max_fails 3
unhealthy_latency 500ms
}
}
En-tetes, Compression et Mise en Cache
En-tetes de Reponse Personnalises
example.com {
header {
# En-tetes de securite
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
Permissions-Policy "camera=(), microphone=(), geolocation=()"
# Supprimer l'identification du serveur
-Server
# Controle de cache pour le contenu dynamique
Cache-Control "no-store, no-cache, must-revalidate"
}
reverse_proxy localhost:3000
}
Compression
Activez la compression transparente avec encode :
example.com {
encode zstd gzip
reverse_proxy localhost:3000
}
Caddy negocie automatiquement le meilleur algorithme de compression en fonction de l’en-tete Accept-Encoding du client. Zstandard (zstd) est prefere lorsqu’il est supporte, car il offre de meilleurs taux de compression et une decompression plus rapide que gzip.
Mise en Cache des Ressources Statiques
example.com {
@static path *.css *.js *.png *.jpg *.gif *.svg *.woff2 *.ico
header @static Cache-Control "public, max-age=31536000, immutable"
@dynamic not path *.css *.js *.png *.jpg *.gif *.svg *.woff2 *.ico
header @dynamic Cache-Control "no-cache, must-revalidate"
reverse_proxy localhost:3000
}
Executer Caddy en tant que Service systemd
L’installation du paquet APT cree automatiquement un service systemd. Voici les commandes essentielles :
# Demarrer Caddy
sudo systemctl start caddy
# Arreter Caddy
sudo systemctl stop caddy
# Redemarrer Caddy (breve interruption)
sudo systemctl restart caddy
# Recharger la configuration sans interruption
sudo systemctl reload caddy
# Activer Caddy au demarrage
sudo systemctl enable caddy
# Verifier l'etat du service
sudo systemctl status caddy
# Consulter les logs
sudo journalctl -u caddy --no-pager -f
Le Fichier de Service Caddy
Le fichier d’unite systemd par defaut se trouve dans /lib/systemd/system/caddy.service. Il execute Caddy en tant qu’utilisateur caddy et charge /etc/caddy/Caddyfile :
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
Remarque : Si vous avez installe Caddy manuellement (pas depuis le paquet), vous devez creer ce fichier de service vous-meme et ajouter l’utilisateur
caddyavecsudo useradd --system --home /var/lib/caddy --shell /usr/sbin/nologin caddy.
Verifier l’Installation
Apres avoir demarre Caddy, verifiez qu’il sert bien votre site :
# Verifier que Caddy ecoute
sudo ss -tlnp | grep caddy
# Tester le HTTPS (remplacez par votre domaine)
curl -I https://example.com
# Verifier les details du certificat
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -subject -dates
Reference des Directives du Caddyfile
Voici une reference des directives du Caddyfile les plus couramment utilisees :
| Directive | Fonction | Exemple |
|---|---|---|
reverse_proxy | Rediriger les requetes vers les serveurs backend | reverse_proxy localhost:3000 |
file_server | Servir des fichiers statiques depuis le disque | file_server |
root | Definir le repertoire racine des documents | root * /var/www/html |
encode | Activer la compression des reponses | encode gzip zstd |
header | Definir, ajouter ou supprimer des en-tetes de reponse | header X-Frame-Options "DENY" |
redir | Rediriger les requetes vers une nouvelle URL | redir /old /new permanent |
rewrite | Reecrire l’URI de la requete en interne | rewrite /app/* /index.html |
basicauth | Proteger des routes avec HTTP Basic Auth | basicauth /admin/* { ... } |
tls | Configurer les parametres TLS manuellement | tls internal |
log | Configurer la journalisation des acces | log { output file /var/log/caddy/access.log } |
handle | Regrouper des directives pour l’exclusivite mutuelle | handle /api/* { ... } |
handle_path | Comme handle, mais supprime le prefixe correspondant | handle_path /api/* { ... } |
respond | Renvoyer une reponse statique | respond "OK" 200 |
import | Inclure un autre fichier ou snippet | import /etc/caddy/snippets/* |
php_fastcgi | Rediriger les requetes PHP vers PHP-FPM | php_fastcgi unix//run/php/php-fpm.sock |
Snippets Reutilisables
Definissez des blocs de configuration reutilisables avec des snippets :
# Definir un snippet
(security_headers) {
header {
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
}
# Utiliser le snippet dans les blocs de site
app.example.com {
import security_headers
reverse_proxy localhost:3000
}
api.example.com {
import security_headers
reverse_proxy localhost:8000
}
Depannage
Problemes de Certificats
Si Caddy ne parvient pas a obtenir un certificat, verifiez ces causes courantes :
# Verifier la resolution DNS
dig +short example.com
# S'assurer que les ports 80 et 443 sont accessibles
sudo ss -tlnp | grep -E ':80|:443'
# Verifier si un autre service utilise le port 80
sudo lsof -i :80
# Consulter les logs de Caddy pour les erreurs ACME
sudo journalctl -u caddy --no-pager | grep -i "acme\|certificate\|tls"
Causes courantes d’echec de certificat :
- Le DNS ne pointe pas vers votre serveur — Le domaine doit resoudre vers l’IP publique du serveur
- Le port 80 est bloque par le pare-feu — Necessaire pour le defi HTTP-01
- Un autre service utilise le port 80 — Arretez Nginx, Apache ou tout autre serveur web
- Limites de debit — Let’s Encrypt limite l’emission de certificats a 5 par domaine par semaine
502 Bad Gateway
Cela signifie que Caddy ne peut pas joindre le backend upstream :
# Verifier que le backend est en cours d'execution
curl -I http://localhost:3000
# Verifier si le backend ecoute sur localhost ou toutes les interfaces
sudo ss -tlnp | grep 3000
# Solution courante : s'assurer que le backend ecoute sur 127.0.0.1, pas sur 0.0.0.0
Erreurs de Permissions
# S'assurer que l'utilisateur caddy a un acces en lecture au repertoire racine web
sudo chown -R caddy:caddy /var/www/mysite
# Verifier les permissions des fichiers
ls -la /var/www/mysite/
# Si Caddy ne peut pas se lier aux ports 80/443
sudo setcap 'cap_net_bind_service=+ep' /usr/bin/caddy
Validation de la Configuration
# Toujours valider avant de recharger
caddy validate --config /etc/caddy/Caddyfile
# Formater le Caddyfile (corriger l'indentation)
caddy fmt --overwrite /etc/caddy/Caddyfile
# Tester avec un adaptateur specifique (ex., pour une configuration JSON)
caddy adapt --config /etc/caddy/Caddyfile
API d’Administration de Caddy
Caddy expose une API d’administration locale sur localhost:2019 pour la configuration en temps reel :
# Voir la configuration actuelle en JSON
curl http://localhost:2019/config/
# Verifier les certificats charges
curl http://localhost:2019/pki/ca/local
# Recharger la configuration via l'API
curl -X POST http://localhost:2019/load \
-H "Content-Type: text/caddyfile" \
--data-binary @/etc/caddy/Caddyfile
Resume
Caddy elimine la complexite de la configuration d’un serveur web en fournissant le HTTPS automatique, une syntaxe de Caddyfile minimale et des parametres par defaut prets pour la production. Que vous serviez des fichiers statiques, redirigiez vers une application backend avec un reverse proxy, ou equilibriez la charge entre plusieurs instances, Caddy se charge du gros du travail — y compris la gestion des certificats TLS — pour que vous puissiez vous concentrer sur le developpement de votre application.
Pour en savoir plus sur la configuration du reverse proxy avec Nginx, consultez notre Guide Complet du Reverse Proxy Nginx. Si vous avez besoin de gerer manuellement les certificats avec Certbot pour des serveurs qui n’utilisent pas Caddy, consultez Automatiser les Certificats SSL avec Let’s Encrypt et Certbot.