PROFIL / INDEX© Clément Depernet / 2026

← Retour à la liste

28 juil. 20262 min de lecture

TLS sans douleur : ce que Caddy fait à ta place

Certbot t'oblige à comprendre les hooks de renouvellement, les timers systemd et les permissions sur /etc/letsencrypt. Caddy demande trois lignes. Voici ce qui se passe réellement derrière, pour ne pas déléguer aveuglément.

intermediate#tls#caddy#https#devops

Je vois passer beaucoup de configurations Nginx + Certbot en audit, et une proportion inquiétante a un certificat expiré parce que le timer de renouvellement a échoué en silence six semaines plus tôt. Caddy supprime cette classe entière de problèmes — mais déléguer sans comprendre reste une dette. Alors regardons sous le capot.

La configuration, d’abord

cdeper.net {
    encode zstd gzip
    root * /srv/site
    file_server
}

C’est tout. Au premier démarrage, Caddy obtient un certificat Let’s Encrypt, sert le site en HTTPS, redirige le port 80 vers 443, et programmera le renouvellement. Aucun timer à écrire, aucun hook à débugger.

Ce qui se passe réellement au premier lancement

  1. Caddy voit un nom de domaine dans le Caddyfile et en déduit qu’il doit gérer le TLS pour cdeper.net.
  2. Il génère une paire de clés de compte ACME et s’enregistre auprès de Let’s Encrypt.
  3. Il tente le challenge TLS-ALPN-01 sur le port 443. Si le 443 est joignable, aucun trafic HTTP n’est même nécessaire.
  4. En repli, il bascule sur HTTP-01 via le port 80.
  5. Le certificat obtenu est stocké dans son data directory, chiffré au repos.

Le point qui piège tout le monde : le challenge TLS-ALPN-01 a besoin du port 443, pas seulement du 80. Beaucoup de tutoriels n’ouvrent que le 80 « parce que c’est pour Let’s Encrypt » et se demandent pourquoi Caddy échoue.

Le renouvellement, la partie invisible

Caddy vérifie ses certificats deux fois par jour et renouvelle à 30 jours de l’expiration. Il n’y a pas de processus séparé, pas de timer systemd : c’est une goroutine dans le processus Caddy lui-même. Conséquence directe : si Caddy tourne, le renouvellement fonctionne. Le mode d’échec de Certbot — le service tourne, mais le timer de renouvellement est cassé — n’existe pas ici.

Le persistant, à ne pas oublier

La seule vraie erreur possible avec Caddy en conteneur, c’est d’oublier de persister son data directory. Sans volume, chaque redémarrage réémet un certificat, et tu atteins la limite de Let’s Encrypt (5 certificats identiques par semaine) en une après-midi de tests.

volumes:
  - caddy_data:/data      # certificats + clés de compte ACME — CRITIQUE
  - caddy_config:/config

caddy_data contient tes clés privées : traite ce volume comme un secret. Sauvegarde-le, ne le mets pas dans un bucket public, et ne le committe jamais.

Les en-têtes, tant qu’on y est

Le TLS chiffre le transport. Il ne dit rien au navigateur sur la manière de se comporter. Ces en-têtes, eux, le font :

header {
    Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    X-Content-Type-Options "nosniff"
    Referrer-Policy "strict-origin-when-cross-origin"
    -Server
}

Strict-Transport-Security mérite une nuance : le flag preload engage ton domaine dans une liste codée en dur dans les navigateurs. C’est difficilement réversible. Ne l’active que si tu es certain de vouloir du HTTPS sur ce domaine et tous ses sous-domaines pour longtemps.

Le compromis, honnêtement

Caddy fait des choix à ta place, et c’est précisément sa valeur — et sa limite. Pour du tuning fin (rate limiting granulaire, WAF ModSecurity, mTLS avec des politiques complexes), Nginx reste plus expressif. Pour servir un site statique en HTTPS correct sans y penser, Caddy gagne à chaque fois. Choisis en fonction de ce que tu as réellement besoin de contrôler.

SEC / OPS / CD-01

Astro + Tailwind, conteneurisé, servi derrière Caddy · Source · Thème sonore : Severance (Theodore Shapiro)

PRÊT / CD-01