Cloudflare
Migração
Workers
Pages
Arquitetura

Migrer de Pages vers Workers : quand cela a du sens et quel est le coût réel du changement

Migrer de Pages vers Workers signifie reconstruire manuellement ce que Pages propose gratuitement : pipeline de création, aperçu des branches et CDN pour les actifs statiques, sans frais par demande.

Migrer de Pages vers Workers : quand cela a du sens et quel est le coût réel du changement

Les équipes adoptent Pages car le flux git push avec construction automatique et déploiement instantané est véritablement plus simple que de créer un pipeline CI à partir de zéro. C'est un réel avantage, pas du marketing. Le problème apparaît lorsque le projet grandit et que vous commencez à atteindre des limites que Pages ne peut pas résoudre : déclencheurs cron, plusieurs travailleurs avec des responsabilités distinctes, mise en scène avec des liaisons différentes. À ce stade, la migration vers Workers semble évidente, mais le véritable coût est rarement calculé avant de commencer.

Les véritables déclencheurs de la migration

Le déclencheur le plus courant est le déclencheur cron. Pages ne prend pas en charge cron de manière native. Si vous avez besoin d'une tâche qui s'exécute périodiquement (traitement des paiements, synchronisation des données externes, génération de rapports planifiés), vous disposez déjà d'un Worker distinct qui s'exécute parallèlement à votre projet Pages. À mesure que le nombre de travailleurs satellites augmente, l’équipe commence à se demander s’il ne serait pas plus logique de tout regrouper dans les travailleurs.

Le deuxième déclencheur est la fragmentation du déploiement. Un projet Pages est une unité de déploiement monolithique : frontend, fonctions, le tout ensemble. Lorsque vous souhaitez répartir les responsabilités entre des Workers spécialisés (un pour l'API publique, un pour le traitement interne, un pour les webhooks), Pages n'offre pas cette granularité. Le déploiement d'une modification dans le gestionnaire de webhooks déclenche une reconstruction de l'intégralité du frontend.

La troisième est la mise en scène avec parité de production. Les pages disposent d'environnements de production et d'aperçu, mais elles n'ont pas d'environnements nommés avec des liaisons complètement différentes. Si vous souhaitez une base de données intermédiaire D1 complètement distincte de celle de production, avec des variables d'environnement différentes et peut-être même un modèle KV différent, la solution dans Pages consiste à créer un projet Pages distinct et à gérer la synchronisation manuellement. Dans Workers, c'est en wrangler.toml avec les blocs [env.staging] et [env.production].

Ce que vous perdez lorsque vous quittez Pages

Avant de migrer, le calcul correct consiste à répertorier les offres Pages que vous devrez remplacer.

Le pipeline de build est l’élément le plus sous-estimé. Pages se connecte au référentiel, détecte le framework, exécute la build et télécharge les ressources. Dans Workers, vous assumez cette responsabilité : posséder CI/CD (GitHub Actions, GitLab CI, peu importe), créer un script et télécharger des actifs sur R2 si vous avez toujours besoin de servir des fichiers statiques.

Les déploiements en aperçu par branche constituent le deuxième élément. Pages génère automatiquement une URL d'aperçu pour chaque branche : push, URL disponible, commentaire sur PR. La réplication de cela dans Workers nécessite du travail : un script CI qui détecte le nom de la branche, se déploie avec un nom de Worker dérivé de la branche (minha-api-pr-247) et commente l'URL dans le PR via l'API GitHub. Cela fonctionne, mais c'est du code infra que vous écrivez et maintenez.

Le troisième élément est le CDN pour les actifs statiques. C’est le plus coûteux à ignorer.

Le compte des actifs statiques

Dans Pages, les ressources statiques (HTML, CSS, JS, images) sont servies directement à partir du CDN Cloudflare sans déclencher le runtime Workers. Chaque demande d'actif statique coûte 0 $ par demande, quel que soit le volume.

Dans Workers, vous n’avez pas cette primitive nativement. Pour servir les actifs, vous avez besoin de R2 (stockage d'objets) et d'une logique dans le Worker qui recherche l'actif correct, applique les en-têtes de cache et renvoie le contenu. Chaque requête qui transite par le runtime compte comme un appel de Worker.

Le plan payant pour les travailleurs comprend 10 millions de demandes par mois et facture 0,30 $ par million au-delà. Un site web avec 100 millions de requêtes mensuelles, dont 90 millions pour des actifs statiques : sur Pages, le coût de la requête est de 0$. Dans Workers, il y a 90 millions d'invocations au-dessus du forfait inclus, soit 27 $/mois pour ce seul delta, augmentant linéairement avec le trafic.

Pour un site web avec 500 millions de requêtes mensuelles avec 85% d'actifs statiques : la différence s'élève à plus de 120$/mois. Le coût du forfait Pages pro est de 20 $/mois. Dans ce scénario, migrer vers Workers est une décision qui augmente les coûts opérationnels en échange de flexibilité.

Le wrangler.toml pour servir les actifs R2

Si la migration a du sens malgré le coût, le modèle correct pour servir les actifs statiques dans Workers utilise R2 avec l'API Cache :

# wrangler.toml name = "meu-site" main = "src/index.ts" compatibility_date = "2024-09-24" [[r2_buckets]] binding = "ASSETS" bucket_name = "meu-site-assets" [[routes]] pattern = "meusite.com/*" zone_name = "meusite.com"
// src/index.ts export default { async fetch(request: Request, env: Env): Promise<Response> { const cache = caches.default; const cached = await cache.match(request); if (cached) return cached; const url = new URL(request.url); const key = url.pathname.slice(1) || "index.html"; const object = await env.ASSETS.get(key); if (!object) { return new Response("Not Found", { status: 404 }); } const response = new Response(object.body, { headers: { "Content-Type": object.httpMetadata?.contentType ?? "application/octet-stream", "Cache-Control": "public, max-age=31536000, immutable", }, }); await cache.put(request, response.clone()); return response; }, };

Cela reproduit le comportement CDN de Pages, mais vous payez pour chaque échec de cache (première requête par fichier par Cloudflare PoP). Le CDN Pages dispose de cette couche de mise en cache sans frais supplémentaires par requête.

Comment migrer sans temps d'arrêt

La séquence la moins risquée : tout d’abord, maintenir le projet Pages en cours d’exécution. Créez de nouveaux Workers en parallèle. Configurez les routes qui envoient le trafic aux nouveaux Workers pour des chemins spécifiques (en commençant par ceux qui présentent le risque le plus faible, tels que les webhooks ou les routes d'administration). Validez le comportement en production avec du trafic réel avant de déplacer les chemins principaux. Ensuite seulement, désactivez les fonctions Pages correspondantes.

Pour le frontend, ne migrez pas les ressources Pages vers R2 tant que vous n'êtes pas sûr que le coût supplémentaire est conforme au budget du projet. Dans de nombreux cas, l'architecture hybride (Pages pour le frontend et les actifs, Workers pour les tâches asynchrones et les services spécialisés) est moins chère et tout aussi flexible qu'une migration complète.

Ce que la migration résout réellement

Déclencheurs Cron, plusieurs Workers avec routage granulaire, staging avec des environnements complètement isolés : tels sont les vrais problèmes qui justifient la migration. Si vous migrez pour une autre raison, il vaut la peine de vérifier que vous n'échangez pas une limitation contre un coût plus élevé.

La flexibilité des travailleurs a un prix opérationnel concret : vous assumez le pipeline CI, le déploiement préliminaire et le coût de service des actifs statiques. Pour les services backend purs sans actifs significatifs, ce coût est faible. Pour les applications avec une interface lourde et un volume de trafic statique élevé, cela peut être substantiel.

A lire aussi