CDN : mise en place et optimisation pour vos applications web
La réduction de latence et la disponibilité géographique sont deux défis majeurs pour toute application web moderne. Quand un utilisateur en Bretagne doit attendre le serveur d'origine situé en région parisienne, la performance en souffre. C'est là que le Content Delivery Network (CDN) intervient : en cachant vos contenus aux points de présence (PoPs) stratégiquement distribués, un CDN divise par 3 ou 4 le temps de réponse et soulage votre infrastructure.
Cet article couvre la mise en place pratique d'un CDN, la configuration des headers, les stratégies d'invalidation, et les pièges à éviter pour une intégration réussie avec votre stack existant.
Plan de l'article
- Comment fonctionne un CDN
- Quand utiliser un CDN
- Configuration des headers de cache
- Stratégies d'invalidation
- CDN et architecture multi-couches
- Nginx comme couche locale de cache
- Monitoring et observabilité
- HTTPS et sécurité au CDN
- Pièges courants
- Conclusion
Comment fonctionne un CDN
Un CDN repose sur trois composants essentiels :
Les edge servers (serveurs de périphérie) Situés dans des datacenters répartis mondialement (ou au minimum nationalement pour un CDN français), ils interceptent les requêtes des utilisateurs finaux et servent le contenu depuis leur cache local.
La hiérarchie de cache Chaque requête suit ce parcours : utilisateur → edge → mid-tier (optionnel) → shield (optionnel) → origin. Cette pyramide répartit la charge et réduit le coût de bande passante vers l'origine.
L'origin server Votre serveur réel (Nginx, Apache, app backend, etc.). Lui seul dispose de la version canonique du contenu. Une montée en charge mal gérée sur l'origin révèle immédiatement l'impact du CDN.
Par exemple, chez SHPV, notre backbone AS41652 avec ses 150 Gbps de capacité et 500+ peerings directs constitue un atout pour les clients ayant des besoins d'interconnexion haute disponibilité. Un CDN se combine bien à cette infrastructure : le CDN absorbe le pic d'utilisateurs, tandis que votre infrastructure interne — même modérée en capacité brute — reste stable.
Quand utiliser un CDN ?
Assets statiques : images, CSS, JavaScript, fonts. Cas d'usage classique et ROI immédiat.
API public : GET-only, réponses déterministes. Un CDN peut cacher des réponses JSON et réduire la charge de votre backend.
HTML pages : moins courant mais pertinent si votre HTML est stable (blogs, documentation). Exige une stratégie TTL courte.
Streaming vidéo/audio : le CDN décharge la quasi-totalité du coût de bande passante.
Cas où un CDN n'aide PAS : contenu personnalisé (pages utilisateur loggées), POST requests, websocket, contenu temps réel strictement < 1 seconde.
Configuration des headers de cache
Les headers HTTP dictent le comportement du CDN. Maîtrisez-les pour gagner en efficacité.
Cache-Control
Cache-Control: public, max-age=86400, immutable
public: le CDN peut cacher (contrairement àprivate, réservé aux navigateurs)max-age=86400: durée de validité en secondes (ici 24h)immutable: le CDN oublie rarement ce header même après expiration
Pour un asset versionnné (ex: bundle.abc123.js), utilisez max-age=31536000, immutable (1 an).
Surrogate-Control (CDN spécifique)
Surrogate-Control: max-age=3600, stale-while-revalidate=86400
Permet au CDN de servir du contenu "rassis" jusqu'à 24h le temps de revalider en arrière-plan. Indispensable pour masquer les pics de latence d'origine.
Vary
Vary: Accept-Encoding, Accept-Language
Force le CDN à créer des entrées séparées pour chaque valeur de ces headers. Attention : trop de variations fragmentent le cache (hit ratio baisse).
ETag et Last-Modified
ETag: "w/5d2—18e89a69"
Last-Modified: Wed, 15 Jan 2025 10:00:00 GMT
Permettent la revalidation 304 Not Modified. Très utile pour le contenu semi-statique (blog).
stale-while-revalidate
Cache-Control: max-age=300, stale-while-revalidate=3600
Le CDN sert du cache expiré (300s) pendant qu'il demande l'origin en arrière-plan (jusqu'à 3600s d'attente tolérance).
Stratégies d'invalidation
Cacher, c'est bien. Savoir invalider, c'est crucial.
TTL classique
Repose sur l'expiration naturelle. Simple, aucun risque de servir du vieux contenu en production. Mais : attend le TTL si correction urgente.
assets statiques : max-age=31536000 (versionnés)
pages HTML : max-age=3600
API : max-age=300
Purge immédiate
La plupart des CDN offrent une API purge. Exemples Cloudflare, Bunny CDN, AWS CloudFront.
curl -X POST https://api.example-cdn.com/purge \
-H "Authorization: Bearer token" \
-d '{"paths": ["/images/logo.png", "/api/users/*"]}'
Risque : sur-utilisation = limitation de débit API.
URLs versionnées
Au lieu de modifier /app.js, générez /app.abc123def456.js à chaque déploiement. Le CDN cache à vie ; les anciennes URLs expirent naturellement.
Framework bundler recommandé : Webpack, Vite, esbuild détectent les changements et renomment automatiquement.
Tag-based purge
Associez des tags à chaque asset :
Content-Surrogate-Key: prod, homepage, v2.1.0
Puis invalidez par tag :
curl -X POST purge \
-H "Surrogate-Key-Purge: v2.1.0"
Puissant pour les déploiements atomiques.
CDN et architecture multi-couches
Une vraie infrastructure CDN comporte plusieurs étages :
User Request
↓
[Edge Servers] ← Cache Hit (90%+ des cas)
↓ Cache Miss
[Shields / Mid-tier] ← Agrège les requêtes redondantes
↓ Cache Miss
[Origin] ← Votre serveur
Pull vs Push :
- Pull : CDN demande l'origin à la demande (standard)
- Push : vous versez pré-activement le contenu aux edges (couteux, mais zéro latence initiale)
Failover : si origin craque, certains CDN peuvent servir du stale content indéfiniment. À configurer selon votre RTO.
Nginx comme couche locale de cache
Si vous hébergez votre origin chez vous ou avez besoin d'une couche cache avant le CDN (pour déduplication), Nginx est une solution légère.
Configuration de base
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m
max_size=1g inactive=60m use_temp_path=off;
upstream backend {
server app.local:8000;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_cache my_cache;
proxy_pass http://backend;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 1h;
proxy_cache_valid 404 10m;
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
proxy_cache_bypass $http_cache_control;
add_header X-Cache-Status $upstream_cache_status;
}
}
Points clés :
keys_zone: nom et taille (ici 10 MB en mémoire, répertoire /var/cache/nginx pour le disque)proxy_cache_use_stale: sert du contenu expiré si backend en erreurX-Cache-Status: header custom pour déboguer (HIT/MISS/BYPASS)
Cache warming
Pré-remplissez le cache Nginx avec une simple boucle au démarrage :
#!/bin/bash
while IFS= read -r url; do
curl -s "$url" > /dev/null
done < /tmp/urls_to_warm.txt
Monitoring CDN
Ne laissez jamais un CDN sans observabilité.
Métriques critiques :
- Cache Hit Ratio : % requêtes servies depuis cache. Cible : 80%+ pour assets, 60%+ pour API.
- Bandwidth savings : bande passante économisée (origin utilisation réduite).
- Origin offload : % du traffic absorbé par CDN (doit être 95%+).
- Latency percentiles : p50, p95, p99. Le CDN doit avoir p95 < 100 ms depuis France.
Dashboards recommandés
Utiliser Grafana + Prometheus, ou les outils natifs du CDN :
# Prometheus
- job_name: 'cdn_metrics'
static_configs:
- targets: ['api.cdn.local:9090']
Alertez sur :
- hit ratio < 70% (cache dégradé)
- origin bandwidth > seuil normal
- latency p99 > 1000ms
CDN et HTTPS
Tout CDN moderne gère HTTPS en transparence.
TLS Termination : le CDN chiffre user ↔ edge, puis origin ↔ edge (http ou https selon config).
HTTP/2 et HTTP/3 : les bons CDN poussent HTTP/2 par défaut, HTTP/3 (QUIC) pour les clients modernes. Cela réduit latence et améliore throughput.
Certificate Management : le CDN auto-renouvelle vos certificats (Lets Encrypt gratuit). Aucune action requise.
Conseils :
- Activez HSTS (Strict-Transport-Security)
- Refusez explicitement HTTP (redirect 301 vers HTTPS)
- Utilisez des certificats wildcard si multi-domaine
Pièges courants
1. Cache poisoning
Un attaquant envoie une requête malveillante (X-Forwarded-For: fake, Host: attacker.com) qui contamine le cache global. Mitigation : ne cachez jamais sur headers non-contrôlés.
# ❌ Mauvais
proxy_cache_key "$host$request_uri$http_x_forwarded_for";
# ✓ Bon
proxy_cache_key "$http_host$request_uri";
2. Stale content après déploiement
Vos utilisateurs voient l'ancienne version 48h après un deploy. Cause : TTL élevé sans versioning. Solution : versionnez les URLs ou déclenchez purge API au deploy.
3. Cookie-based caching
Un CDN cacherait une réponse Set-Cookie destinée à un utilisateur, puis la servirait à un autre. Catastrophe.
Cache-Control: private, max-age=0 /* ← Obligatoire si cookies */
4. CORS et CDN
Les headers Access-Control-* doivent être cachés par domaine demandeur. Sinon le premier visiteur depuis domainA décide pour tous les autres.
proxy_cache_key "$scheme$request_method$host$request_uri$http_origin";
5. Origin bottleneck
Le CDN fonctionne bien, mais origin craque. Avant de pointer 10 000 utilisateurs au CDN, vérifiez que origin absorbe le traffic miss.
Perspectives complémentaires
Pour approfondir :
- Optimiser Nginx et le cache côté serveur : approche complémentaire sans CDN externe
- Varnish Cache : architecture haute performance : alternative légère à un CDN pour infra interne
- Nginx + Varnish : déduplication multi-layer : combiner les deux
- Core Web Vitals et SEO : CDN améliore LCP et FID
- Optimiser le temps de chargement d'un site : stratégie globale
- HTTP/3 et performance : bénéfices du protocole moderne
Infrastructure et CDN
Rappel important : un CDN n'est PAS un remplaçant d'infrastructure solide. Chez SHPV, nos clients hébergés opèrent avec un SLA 99.9%+ grâce à une infrastructure dimensionnée correctement — backbone AS41652 avec 150 Gbps de capacité et 500+ peerings directs garantissent une rétro-propagation stable des requêtes. Un CDN optimise l'arrivée au client ; l'infrastructure optimise le retour vers vos datas.
Si vous êtes basé en France et recherchez une infrastructure robuste pour complémenter votre CDN (failover sain, hébergement applicatif, transit garantis), les solutions infrastructure et transit SHPV couvrent ces aspects.
Sources
- Cloudflare, "How do Content Delivery Networks (CDNs) work?", https://www.cloudflare.com/en-gb/learning/cdn/what-is-a-cdn/
- Nginx, "Module ngx_http_proxy_module", https://nginx.org/en/docs/http/ngx_http_proxy_module.html
- RFC 7234, "HTTP Caching", https://tools.ietf.org/html/rfc7234
- OWASP, "Cache Poisoning Attacks", https://owasp.org/www-community/attacks/Cache_Poisoning
- MDN Web Docs, "HTTP Caching", https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching
- HTTP Working Group, "HTTP/2 Specifications", https://http2.github.io/
Conclusion
Mettre en place un CDN n'est pas trivial : il faut comprendre les headers HTTP, configurer intelligemment les TTLs, prévoir l'invalidation, et monitorer en continu. Les erreurs les plus fréquentes viennent d'une mauvaise compréhension de la hiérarchie cache et des pièges de sécurité.
Cette mise en place, couplée à une architecture d'infrastructure robuste et une stratégie de versioning, vous permettra de servir vos utilisateurs 3 à 5× plus vite, tout en réduisant la charge de vos serveurs d'origine.
À vous de jouer !


