CDN et performance web - 03 - CDN devant un bucket : servir des images et fichiers statiques

Mettre un CDN devant un bucket S3/GCS pour servir images et fichiers statiques. Configuration, cache et economies.

03 - CDN devant un bucket : servir des images et fichiers statiques

Ce que tu vas apprendre

  • Le pattern bucket + CDN pour les fichiers statiques
  • Configurer R2, GCS ou S3 derrière Cloudflare
  • Les coûts réels de chaque solution
  • L'optimisation d'images a la volee

Prerequisites


Pourquoi un bucket plutot que ton serveur

Tu pourrais servir tes images et fichiers statiques directement depuis ton VPS. Ca marche. Mais ca a des limites : l'espace disque du VPS est fini, les I/O disque consomment des ressources, et si ton serveur tombe, tout tombe.

Un bucket de stockage objet (S3 chez AWS, GCS chez Google Cloud, R2 chez Cloudflare) resout ces problèmes. Le stockage est quasi illimite, le service est redondant, et tu separes le statique de l'applicatif. L'architecture classique : ton appli tourne sur le VPS, tes fichiers vivent dans un bucket, et un CDN sert le tout depuis le edge.

Le problème des buckets servis directement : chaque requête coûte de l'argent (frais par requête), il n'y a pas de cache edge, et le bucket est dans une seule region. Un CDN devant le bucket regle tout ca. Les requêtes repetees sont servies depuis le cache, l'origin (le bucket) est contacte rarement, et les frais par requête baissent.

Cloudflare R2 : zero frais de sortie

R2, c'est le service de stockage objet de Cloudflare. Compatible S3 (tu peux utiliser les SDK AWS avec), mais avec une différence fondamentale : zero egress fees. Tu ne paies pas pour la bande passante sortante. Jamais.

Pour comprendre pourquoi c'est énorme, regarde les prix de la concurrence. Sur AWS S3, le transfert sortant coûte environ $0.09/Go apres le premier Go gratuit. Sur GCS, c'est $0.12/Go. Si tu sers 1 To d'images par mois :

  • AWS S3 : environ $90 juste en egress (plus le stockage, plus les requêtes)
  • GCS : environ $120 en egress
  • Cloudflare R2 : $0 en egress. Tu paies $0.015/Go/mois de stockage et $0.36 par million de requêtes de lecture.

Pour 50 Go stockes et 10 millions de requêtes par mois, R2 te coûte environ $4.35. Le meme usage sur S3 avec 1 To de transfert te coûte plus de $100. Le calcul est vite fait.

Configurer R2 avec un domaine personnalise

R2 s'intégré nativement avec Cloudflare. La configuration est presque triviale.

Cree un bucket R2 dans le dashboard Cloudflare, ou via Wrangler :

bashnpx wrangler r2 bucket create media-paltemps

Pour connecter un domaine personnalise (genre media.paltemps.fr), va dans les paramètres du bucket R2, section "Custom Domains", et ajoute ton sous-domaine. Cloudflare configure automatiquement le DNS et le proxy. Le CDN est actif immédiatement, sans Page Rule ni Cache Rule supplementaire.

Upload des fichiers via l'API S3-compatible ou via Wrangler :

bashnpx wrangler r2 object put media-paltemps/photos/paris.webp --file=./paris.webp

Et c'est accessible sur https://media.paltemps.fr/photos/paris.webp. Cache automatique, SSL automatique, CDN mondial.

Configurer GCS derrière Cloudflare

Si tu utilises deja Google Cloud Storage (c'est mon cas pour certains projets, dont des images pour paltemps.fr), tu peux mettre Cloudflare devant.

La méthode : créer un bucket GCS avec acces public en lecture, puis configurer Cloudflare pour proxifier les requêtes vers le bucket.

Dans le DNS Cloudflare, créé un CNAME :

media.tonsite.fr -> storage.googleapis.com (proxy: ON)

Le bucket GCS doit porter le nom du sous-domaine (media.tonsite.fr) pour que le routing fonctionne. C'est une contrainte de GCS.

Ensuite, ajoute une Cache Rule dans Cloudflare pour ce sous-domaine :

Si: hostname = media.tonsite.fr
Alors: Cache eligibility = Eligible for cache
       Edge TTL = 1 mois
       Browser TTL = 1 semaine

Avec ca, Cloudflare cache tout le contenu du bucket GCS. Les requêtes repetees ne touchent jamais GCS, et tu economises sur les frais d'egress Google.

Un détail qui m'a fait perdre du temps : GCS renvoie des headers x-goog-* dans les réponses. Cloudflare les transmet tels quels par défaut. Ca ne pose pas de problème de fonctionnement, mais ca expose le fait que tu utilises GCS en backend. Si ca te derange, un Cloudflare Worker de trois lignes peut supprimer ces headers.

L'optimisation d'images

Servir des images depuis un CDN, c'est bien. Les optimiser au passage, c'est mieux.

Cloudflare Polish (plan Pro, $20/mois) optimise automatiquement les images : compression lossless ou lossy, conversion en WebP ou AVIF selon le header Accept du navigateur. Un JPEG de 500 Ko devient un AVIF de 80 Ko pour les navigateurs compatibles, sans que tu changes quoi que ce soit dans ton code.

Cloudflare Images (service séparé, $5/mois + $1 par 100 000 images) va plus loin avec du redimensionnement a la volee. Tu peux demander /photo.jpg?width=400&format=avif et Cloudflare généré la variante en temps réel, la cache, et la sert.

Si tu ne veux pas payer, tu peux faire le travail toi-meme au moment du build ou de l'upload. Des outils comme sharp (Node.js) ou cwebp generent des versions WebP/AVIF de tes images. Tu uploades les variantes dans ton bucket et tu utilises la balise <picture> en HTML pour servir le bon format.

bash# Convertir en WebP avec cwebp
cwebp -q 80 photo.jpg -o photo.webp

# Convertir en AVIF avec avifenc
avifenc --min 20 --max 30 photo.jpg photo.avif

Personnellement, je pre-généré mes images en WebP au moment de l'upload et je laisse Cloudflare cacher le résultat. Ca fonctionne sur le plan gratuit et le résultat est suffisant pour la plupart des cas.

L'architecture complète

Pour résumer, l'architecture que je recommande pour un petit ou moyen projet :

Utilisateur -> Cloudflare Edge -> R2 Bucket (fichiers statiques)
                              -> VPS/Caddy (contenu dynamique)

Le contenu statique (images, CSS, JS, fonts) vit dans R2 sur un sous-domaine dédié. Le contenu dynamique (HTML, API) passe par le VPS. Cloudflare cache les deux, mais avec des stratégies différentes : TTL long et agressif pour le statique, TTL court ou pas de cache pour le dynamique.

Ca séparé bien les responsabilités. Ton VPS se concentre sur la logique applicative. Le bucket gere le stockage. Cloudflare gere la distribution et la sécurité.

Prochain article : La sécurité offerte par un CDN.


Navigation : Precedent : 02 - Configurer Cloudflare | Suivant : 04 - Sécurité CDN


Sources

Retrouve d'autres articles techniques sur paltemps.fr.

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.