Aller au contenu

Les Primitives de Calcul Cloudflare

Cloudflare offre trois primitives de calcul distinctes sur la plateforme Workers. Choisir la bonne dès le début évite des migrations coûteuses.

PrimitiveIdéal pourÉviter quand
WorkerLogique applicative, APIs, middleware, routage, tâches légères en arrière-planVous avez besoin d’un runtime complet, d’un système de fichiers ou d’un environnement Linux
Dynamic WorkerExécuter du code non fiable ou généré par IA dans un bac à sableVous avez besoin de calcul CPU intensif, d’un système de fichiers complet ou d’images container existantes
ContainerCharges lourdes, images container existantes, serveurs WebSocket, jobs cron, Region:EarthVous avez seulement besoin de gestion simple de requêtes ou d’inférence IA

La primitive par défaut. Déployez du JavaScript ou TypeScript sur le réseau edge de Cloudflare avec des démarrages à froid rapides et sans gestion d’infrastructure.

  • Gestion HTTP, routes API, middleware
  • Tâches en arrière-plan via Queues ou Workflows
  • Services stateful avec Durable Objects
  • Bindings R2, D1, KV, Vectorize
  • Inférence Workers AI
export default {
async fetch(request: Request, env: Env): Promise<Response> {
return new Response("Hello from a Worker");
},
};

Lancez des Workers isolés au runtime pour exécuter du code arbitraire dans un bac à sable sécurisé. Le Worker parent contrôle les bindings reçus par le dynamic Worker et s’il peut accéder au réseau.

  • Exécution de code d’agent IA: Laissez un agent écrire et exécuter ses propres outils de manière sécurisée.
  • Code utilisateur non fiable: Exécutez du code soumis par des utilisateurs dans un bac à sable que vous contrôlez.
  • Previews et playgrounds: Chargez du code généré en millisecondes.
  • Automatisations personnalisées: Créez des outils à la volée pour des tâches ponctuelles.
  • “Vibe coding”: Exécutez des prototypes générés par IA en isolement.

Sécurité basée sur les capacités via Workers RPC Les bindings utilisent Cap’n Web RPC. Un Dynamic Worker ne reçoit accès qu’à ce que vous lui passez explicitement comme stub. Si vous ne passez jamais un binding, il ne peut pas être atteint.

Controle de l’egress Définissez globalOutbound: null pour bloquer tout accès réseau sortant. Le Dynamic Worker ne peut utiliser que les bindings que vous lui donnez. Ou interceptez et réécrivez les requêtes via une passerelle.

Observabilité via Tail Workers Attachez un Tail Worker pour capturer console.log, les exceptions et les métadonnées de requête du Dynamic Worker. Les logs sont écrits après le retour de la réponse, donc ils n’ajoutent pas de latence.

import { getContainer } from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 4000;
sleepAfter = "10m";
}
export default {
async fetch(request, env) {
const { "session-id": sessionId } = await request.json();
const containerInstance = getContainer(env.MY_CONTAINER, sessionId);
return containerInstance.fetch(request);
},
};
wrangler.jsonc
{
"name": "container-starter",
"main": "src/index.js",
"compatibility_date": "2026-03-30",
"containers": [
{
"class_name": "MyContainer",
"image": "./Dockerfile",
"max_instances": 5
}
],
"durable_objects": {
"bindings": [
{ "class_name": "MyContainer", "name": "MY_CONTAINER" }
]
},
"migrations": [
{ "new_sqlite_classes": ["MyContainer"], "tag": "v1" }
]
}

Pattern Sécurité: Binding personnalisé pour un Bac à Sable Agent

Section intitulée « Pattern Sécurité: Binding personnalisé pour un Bac à Sable Agent »
import { WorkerEntrypoint } from "cloudflare:workers";
export class ChatRoom extends WorkerEntrypoint<Env, ChatRoomProps> {
async post(text: string): Promise<void> {
text = `[${this.ctx.props.botName}]: ${text}`;
await postToChat(this.ctx.props.apiKey, this.ctx.props.roomName, text);
}
}
type ChatRoomProps = {
apiKey: string;
roomName: string;
botName: string;
};

L’agent ne voit que la méthode ChatRoom.post(). Il ne voit jamais la clé API et ne peut poster dans aucune autre salle.

Pattern Sécurité: Bloquer l’Accès Reseau Externe

Section intitulée « Pattern Sécurité: Bloquer l’Accès Reseau Externe »
const worker = env.LOADER.get(id, () => ({
mainModule: "index.js",
modules: { "index.js": code },
globalOutbound: null,
}));

Le Dynamic Worker ne peutagir que via les bindings que vous lui passez.

export class DynamicWorkerTail extends WorkerEntrypoint {
async tail(events) {
for (const event of events) {
for (const log of event.logs) {
console.log({
source: "dynamic-worker-tail",
workerId: this.ctx.props.workerId,
level: log.level,
message: log.message,
});
}
}
}
}
const worker = env.LOADER.get(workerId, () => ({
mainModule: WORKER_MAIN,
modules: { [WORKER_MAIN]: WORKER_SOURCE },
tails: [ctx.exports.DynamicWorkerTail({ props: { workerId } })],
}));

Exécutez du code écrit dans n’importe quel langage, compilé pour n’importe quel runtime, dans le cadre d’une application Workers. Les instances de container démarrent à la demande et sont contrôlées par votre code Worker.

Disponible sur le plan Workers Payant.

  • Charges de travail intensives en ressources: Cores CPU en parallèle, grande quantité de mémoire ou de disque.
  • Accès complet au système de fichiers: Applications qui nécessitent un vrai environnement de type Linux.
  • Images container existantes: Outils distribues en tant qu’images Docker.
  • Serveurs WebSocket: Connexions longue duree qui ne correspondent pas au modèle Workers.
  • Jobs cron: Exécutez un container sur un planning avec des triggers CRON.
  • Conformité Region:Earth: Exigences de résidence des données.
PatternCas d’usage
Frontend statique + Backend containerSPA avec un backend API containerise
Cron ContainerCharges de travail planifiées via trigger cron
Interface Durable ObjectAppeler des containers directement depuis des DOs
Env vars et secretsPasser des identifiants de façon sécurisée dans les containers
Instances statelessPasser à l’échelle sur le réseau Cloudflare
Status hooksRéagir aux événements du cycle de vie du container
Websocket vers ContainerForwarder les connexions WebSocket vers un container
R2 FUSE mountMonter des buckets R2 comme systèmes de fichiers dans un container
wrangler.jsonc
{
"name": "my-container-app",
"main": "src/index.js",
"compatibility_date": "2026-03-30",
"containers": [
{
"class_name": "MyContainer",
"image": "./Dockerfile",
"max_instances": 5
}
],
"durable_objects": {
"bindings": [
{ "class_name": "MyContainer", "name": "MY_CONTAINER" }
]
}
}
import { Container, getContainer } from "@cloudflare/containers";
export class MyContainer extends Container {
defaultPort = 8080;
sleepAfter = "5m";
}
export default {
async fetch(request, env) {
const id = request.headers.get("X-Session-Id") ?? "default";
const instance = getContainer(env.MY_CONTAINER, id);
return instance.fetch(request);
},
};
DimensionDynamic WorkerContainer
Vitesse de démarrageSub-millisecondeSecondes à minutes
RuntimeIsolats V8 (JavaScript/TypeScript)Container Linux complet
Modèle de sécuritéRPC base sur les capacités, pas de réseau par défautIsolation réseau configurable
Génération de codeOui - l’agent écrit du code au runtimeNon - l’image doit exister au préalable
CPU/mémoireLégerAccès CPU et mémoire complet
Systeme de fichiersNonAccès complet
Idéal pourBac à sable agent IA, code non fiable, previews rapidesImages préconstruites, charges lourdes, WebSockets

Règle empirique: utilisez Dynamic Workers quand le Worker écrit ou génère le code. Utilisez Containers quand vous devez expédier et exécuter une image préconstruite.

  1. Bloquer le réseau par défaut: Définissez globalOutbound: null et n’accordez l’accès que via des bindings étroits.
  2. Utiliser des bindings basés sur les capacités: Passez des stubs avec seulement les méthodes dont le Worker à besoin, pas des identifiants bruts.
  3. Injecter les identifiants à la passerelle: N’exposez jamais les secrets au Dynamic Worker; réécrivez ou injectez à la limite.
  4. Utiliser les Tail Workers pour l’observabilité: Capturez les logs sans ajouter de latence à la requête.