TL;DR — Résumé Rapide

Deployez Caddy comme serveur web avec HTTPS automatique. Decouvrez Caddyfile, le reverse proxy, l equilibrage de charge et la comparaison avec Nginx.

ARCHITECTURE HTTPS AUTOMATIQUE DE CADDY Clients Navigateur / API Mobile / CLI HTTPS :443 Caddy Server HTTPS Auto (ACME) Reverse Proxy Equilibrage de Charge Compression HTTP/2 & HTTP/3 reverse_proxy HTTP Node.js :3000 app.exemple.com Python :8000 api.exemple.com Docker :9000 admin.exemple.com Let's Encrypt ACME CA Caddy obtient les certificats automatiquement et redirige vers vos backends

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 :

  1. Obtenir un certificat TLS pour example.com automatiquement
  2. Servir les fichiers depuis /var/www/mysite
  3. Activer HTTP/2 et HTTP/3
  4. 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 :

  1. Verification DNS – Verifie que le domaine pointe vers l’IP publique du serveur
  2. Demande de certificat – Contacte Let’s Encrypt (ou ZeroSSL en secours) via le protocole ACME
  3. Completion du defi HTTP-01 – Prouve la propriete du domaine en servant un jeton sur le port 80
  4. Installation du certificat – Configure TLS avec le certificat et la cle obtenus
  5. Redirection HTTP vers HTTPS – Cree une redirection automatique sur le port 80
  6. 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_ca lors 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 caddy avec sudo 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.

Articles Connexes