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 7·40 min

Modules et plugins — forward_auth, security, ratelimit, modules custom

L'écosystème de modules Caddy couvre l'authentification, le rate limiting, la sécurité, le DNS, le stockage. Ce chapitre couvre les modules les plus utiles en production et comment en écrire un from scratch.

xcaddy — compiler son propre Caddy

# Installer xcaddy
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
 
# Build avec modules
xcaddy build \
  --with github.com/caddy-dns/cloudflare \
  --with github.com/mholt/caddy-ratelimit \
  --with github.com/greenpau/caddy-security \
  --with github.com/caddyserver/cache-handler \
  --with github.com/dunglas/caddy-cbrotli
 
# Build avec version spécifique de Caddy
xcaddy build v2.9.1 \
  --with github.com/caddy-dns/cloudflare@latest
 
# Remplacer le binaire système
sudo mv ./caddy /usr/bin/caddy
sudo systemctl restart caddy

forward_auth — déléguer l'authentification

forward_auth envoie chaque requête à un service d'authentification externe avant de la transmettre à l'upstream. Si le service répond 2xx, la requête passe. Sinon, l'utilisateur reçoit l'erreur (401, 302 vers login, etc.).

example.com {
    forward_auth authelia:9091 {
        uri /api/authz/forward-auth
        copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
    }
 
    reverse_proxy backend:3000 {
        header_up X-User {header.Remote-User}
        header_up X-Groups {header.Remote-Groups}
    }
}

Avec Authentik (alternative à Authelia) :

example.com {
    forward_auth authentik:9000 {
        uri /outpost.goauthentik.io/auth/caddy
        copy_headers X-authentik-username X-authentik-groups X-authentik-email
    }
    reverse_proxy backend:3000
}

caddy-ratelimit

Module de rate limiting qui s'intègre proprement dans la chaîne de handlers :

xcaddy build --with github.com/mholt/caddy-ratelimit
api.example.com {
    rate_limit {
        distributed                    # partage l'état en cluster
        storage redis {
            address localhost:6379
        }
 
        zone api_global {
            key {remote_host}          # par IP
            events 1000
            window 1m
        }
 
        zone api_endpoint {
            key {remote_host}|{path}   # par IP + endpoint
            events 60
            window 1m
        }
    }
 
    @authenticated header Authorization "Bearer *"
    handle @authenticated {
        rate_limit {
            zone authenticated_users {
                key {header.Authorization}
                events 10000
                window 1m
            }
        }
        reverse_proxy backend:3000
    }
 
    handle {
        rate_limit {
            zone anonymous {
                key {remote_host}
                events 100
                window 1m
            }
        }
        reverse_proxy backend:3000
    }
}

caddy-security — authentification complète

caddy-security est un module qui implémente OAuth2, SAML, LDAP, MFA, et plus directement dans Caddy, sans service externe.

xcaddy build --with github.com/greenpau/caddy-security
{
    order authenticate before respond
    order authorize before reverse_proxy
 
    security {
        local identity store localdb {
            realm local
            path /etc/caddy/users.json
        }
 
        authentication portal myportal {
            crypto default token lifetime 3600
            crypto key sign-verify {env.JWT_SECRET}
            enable identity store localdb
            cookie domain example.com
            cookie insecure off
            ui {
                links {
                    "My App" /app icon "las la-rocket"
                }
            }
        }
 
        authorization policy mypolicy {
            set auth url https://auth.example.com/
            allow roles authp/admin authp/user
            crypto key verify {env.JWT_SECRET}
            acl rule {
                comment allow users
                match role authp/user
                allow stop log info
            }
        }
    }
}
 
auth.example.com {
    authenticate with myportal
}
 
app.example.com {
    authorize with mypolicy
    reverse_proxy backend:3000
}

cache-handler — cache HTTP intégré

xcaddy build --with github.com/caddyserver/cache-handler
api.example.com {
    cache {
        api {
            basepath /cache
        }
        regex {
            exclude .*
        }
        key {
            disable_body
            disable_host
            disable_method
            disable_query
            headers X-API-Version
        }
        ttl 5m
        default_cache_control "public, max-age=300"
    }
 
    reverse_proxy backend:3000
}

caddy-cbrotli — compression Brotli

Caddy inclut gzip/zstd natifs. Pour Brotli :

xcaddy build --with github.com/dunglas/caddy-cbrotli
example.com {
    encode zstd br gzip {
        minimum_length 1024
    }
    reverse_proxy backend:3000
}

Écrire un module custom

Un module Caddy est un package Go qui implémente une interface. Voici un handler qui ajoute un header de corrélation à chaque requête.

Structure

├── go.mod
├── go.sum
└── correlationid/
    └── correlationid.go

Code du module

correlationid/correlationid.go
package correlationid
 
import (
    "crypto/rand"
    "encoding/hex"
    "net/http"
 
    "github.com/caddyserver/caddy/v2"
    "github.com/caddyserver/caddy/v2/modules/caddyhttp"
)
 
func init() {
    caddy.RegisterModule(CorrelationID{})
}
 
// CorrelationID ajoute un X-Correlation-ID header à chaque requête
type CorrelationID struct {
    HeaderName string `json:"header_name,omitempty"`
}
 
func (CorrelationID) CaddyModule() caddy.ModuleInfo {
    return caddy.ModuleInfo{
        ID:  "http.handlers.correlation_id",
        New: func() caddy.Module { return new(CorrelationID) },
    }
}
 
func (c *CorrelationID) Provision(ctx caddy.Context) error {
    if c.HeaderName == "" {
        c.HeaderName = "X-Correlation-ID"
    }
    return nil
}
 
func (c CorrelationID) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
    id := r.Header.Get(c.HeaderName)
    if id == "" {
        b := make([]byte, 16)
        rand.Read(b)
        id = hex.EncodeToString(b)
        r.Header.Set(c.HeaderName, id)
    }
    w.Header().Set(c.HeaderName, id)
    return next.ServeHTTP(w, r)
}
 
var (
    _ caddy.Provisioner        = (*CorrelationID)(nil)
    _ caddyhttp.MiddlewareHandler = (*CorrelationID)(nil)
)

Compiler avec xcaddy

# Depuis le répertoire du module
xcaddy build \
  --with github.com/yourorg/caddy-correlationid=./
 
# Ou héberger sur GitHub puis
xcaddy build \
  --with github.com/yourorg/caddy-correlationid@v1.0.0

Utiliser le module dans la config JSON

{
  "handler": "correlation_id",
  "header_name": "X-Request-ID"
}
example.com {
    correlation_id {
        header_name X-Request-ID
    }
    reverse_proxy backend:3000
}

Interface complète d'un module

// Interfaces disponibles selon les besoins du module
type MyModule struct{}
 
// Obligatoire — identification du module
func (MyModule) CaddyModule() caddy.ModuleInfo
 
// Configuration et validation
func (*MyModule) Provision(ctx caddy.Context) error
func (*MyModule) Validate() error
func (*MyModule) Cleanup() error
 
// Selon le type de module
func (*MyModule) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error  // handler
func (*MyModule) Match(r *http.Request) bool  // matcher
 
// Sérialisation
type MyModule struct {
    Option string `json:"option,omitempty"`
}

DNS providers disponibles

cloudflare          github.com/caddy-dns/cloudflare
route53             github.com/caddy-dns/route53
digitalocean        github.com/caddy-dns/digitalocean
gcloud              github.com/caddy-dns/googlecloud
azure               github.com/caddy-dns/azure
namecheap           github.com/caddy-dns/namecheap
ovh                 github.com/caddy-dns/ovh
hetzner             github.com/caddy-dns/hetzner
bunny               github.com/caddy-dns/bunny

Storage backends

file_system         Intégré — stockage local (défaut)
redis               github.com/pberkel/caddy-storage-redis
s3                  github.com/sagikazarmark/caddy-fs-s3
consul              github.com/pteich/caddy-tlsconsul

Configuration du storage Redis (pour les clusters) :

{
  "storage": {
    "module": "redis",
    "host": "redis:6379",
    "password": "{env.REDIS_PASSWORD}",
    "db": 0,
    "key_prefix": "caddy:"
  }
}

Les modules sont maîtrisés. Dernier chapitre : production — logs structurés, métriques Prometheus, clustering, Docker et Kubernetes.

Précédent
Reverse proxy avancé — load balancing, health checks, transforms
Suivant
Production — logs, métriques Prometheus, clustering, Docker, Kubernetes

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