iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
Formations
HCL / JSON / Bash · Avancé

Caddy

Caddy de A à Z pour experts : Admin API REST, HTTPS automatique (ACME, DNS challenge, PKI interne), reverse proxy avancé, modules, on-demand TLS, clustering et production.

Caddy 2CaddyfileAdmin APIACMEDocker
01Pourquoi Caddy — ce qu'Apache et Nginx ne font pas02Architecture interne — Apps, modules et config JSON03Caddyfile avancé — matchers, snippets, directives04Admin API — configuration dynamique en JSON05HTTPS et PKI — ACME, wildcards, on-demand TLS, CA interne06Reverse proxy avancé — load balancing, health checks, transforms07Modules et plugins — forward_auth, security, ratelimit, modules custom08Production — logs, métriques Prometheus, clustering, Docker, Kubernetes
Chapitre 2·25 min

Architecture interne — Apps, modules et config JSON

Caddy n'est pas un serveur HTTP avec quelques options. C'est un runtime de modules où le serveur HTTP est lui-même un module. Comprendre cette architecture change la façon dont on pense la configuration.

La config JSON native

Tout ce que Caddy fait est décrit par un objet JSON. Le Caddyfile est un format humain qui se compile vers ce JSON. La structure de base :

{
  "admin": {
    "listen": "localhost:2019"
  },
  "logging": { ... },
  "storage": { ... },
  "apps": {
    "http": { ... },
    "tls": { ... },
    "pki": { ... }
  }
}

Les apps sont les modules de haut niveau. Chaque app est indépendante — vous pouvez avoir Caddy sans serveur HTTP (juste PKI + TLS), ou avec plusieurs serveurs HTTP sur des ports différents.

L'app HTTP

{
  "apps": {
    "http": {
      "http_port": 80,
      "https_port": 443,
      "servers": {
        "main": {
          "listen": [":443"],
          "routes": [
            {
              "match": [{"host": ["example.com"]}],
              "handle": [
                {
                  "handler": "reverse_proxy",
                  "upstreams": [{"dial": "localhost:3000"}]
                }
              ]
            }
          ]
        }
      }
    }
  }
}

Routes, matchers et handlers

Une route = match + handle. L'évaluation suit l'ordre de déclaration — pas de score comme Nginx.

Matchers disponibles :

{
  "match": [
    {
      "host": ["example.com", "*.example.com"],
      "path": ["/api/*"],
      "method": ["GET", "POST"],
      "header": {"X-Custom": ["value*"]},
      "header_regexp": {"Authorization": "Bearer (?P<token>.+)"},
      "remote_ip": {"ranges": ["10.0.0.0/8"]},
      "not": [{"path": ["/health"]}]
    }
  ]
}

Les conditions dans un même objet matcher sont ET. Plusieurs objets matcher dans le tableau sont OU.

Handler chain : les handlers s'exécutent en séquence dans l'ordre du tableau. Un handler peut décider de passer la requête au suivant ou de l'absorber.

{
  "handle": [
    {"handler": "authentication", "providers": {...}},
    {"handler": "rate_limit", ...},
    {"handler": "rewrite", "uri": "/internal{path}"},
    {"handler": "reverse_proxy", "upstreams": [...]}
  ]
}

L'app TLS

Gère les certificats indépendamment de l'app HTTP. Elle peut obtenir des certificats pour des domaines qui ne sont pas encore routés.

{
  "apps": {
    "tls": {
      "automation": {
        "policies": [
          {
            "subjects": ["example.com", "*.example.com"],
            "issuers": [
              {
                "module": "acme",
                "ca": "https://acme-v02.api.letsencrypt.org/directory",
                "challenges": {
                  "dns": {
                    "provider": {
                      "name": "cloudflare",
                      "api_token": "{env.CF_API_TOKEN}"
                    }
                  }
                }
              }
            ],
            "key_type": "p256"
          }
        ]
      },
      "certificates": {
        "automate": ["example.com", "*.example.com"]
      }
    }
  }
}

L'app PKI — CA interne

Caddy peut être une autorité de certification interne. Elle émet des certificats pour vos services internes signés par une CA que vous contrôlez.

{
  "apps": {
    "pki": {
      "certificate_authorities": {
        "local": {
          "name": "Caddy Local Authority",
          "root": {
            "format": "pem_file",
            "certificate": "/etc/caddy/root.crt",
            "private_key": "/etc/caddy/root.key"
          }
        }
      }
    }
  }
}

Ensuite dans la politique TLS :

{
  "issuers": [
    {
      "module": "internal",
      "ca": "local"
    }
  ]
}

Tous les certificats internes sont signés par votre CA. Distribuez le certificat root à vos clients une fois, et tous les services qui utilisent cette CA sont automatiquement reconnus.

Comment le Caddyfile compile vers JSON

Le Caddyfile est un DSL qui mappe vers la structure JSON. Comprendre la correspondance évite les surprises.

{
    admin localhost:2019
    email admin@example.com
    key_type p256
}
 
example.com {
    tls {
        dns cloudflare {env.CF_API_TOKEN}
    }
    reverse_proxy localhost:3000
}

Compile vers (simplifié) :

{
  "admin": {"listen": "localhost:2019"},
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [":443", ":80"],
          "routes": [{
            "match": [{"host": ["example.com"]}],
            "handle": [{
              "handler": "subroute",
              "routes": [{
                "handle": [{"handler": "reverse_proxy", "upstreams": [{"dial": "localhost:3000"}]}]
              }]
            }]
          }]
        }
      }
    },
    "tls": {
      "automation": {
        "policies": [{
          "subjects": ["example.com"],
          "issuers": [{"module": "acme", "challenges": {"dns": {"provider": {"name": "cloudflare"}}}}]
        }]
      }
    }
  }
}

Voir la compilation en live :

caddy adapt --config Caddyfile --adapter caddyfile

Indispensable pour déboguer une configuration Caddyfile qui ne se comporte pas comme attendu — vous voyez exactement ce que Caddy exécute.

Modules — le registre

Chaque type de handler, matcher, logger, storage est un module avec un nom unique :

Handlers    : file_server, reverse_proxy, static_response, rewrite,
              redirect, authenticate, rate_limit, templates, encode
Matchers    : host, path, method, header, remote_ip, expression, not
Storage     : file_system, redis, s3
Loggers     : console, json, filter
Issuers     : acme, internal, zerossl
Challenges  : http-01, tls-alpn-01, dns
# Lister tous les modules disponibles dans votre build
caddy list-modules
 
# Modules HTTP spécifiquement
caddy list-modules --packages | grep http

L'architecture est claire. Le chapitre suivant couvre le Caddyfile avancé : snippets, matchers nommés, import, @, et les patterns de configuration réels.

Précédent
Pourquoi Caddy — ce qu'Apache et Nginx ne font pas
Suivant
Caddyfile avancé — matchers, snippets, directives

Développeur fullstack passionné. J'apprends en construisant et je documente tout — front, back, outils. Le code s'apprend mieux en public.

Naviguer

IndexTous les articlesFormationsProfilOutilsBibliothech

Ailleurs

GitHub RSS

Newsletter

Les articles, libs et découvertes. Une fois par semaine, pas plus.

© 2026 William LoreeConçu & codé à la main