Aller au contenu
Bastide Connexion Créer un compte
Appuyez sur / pour chercher

Cache et images

EnglishMarkdownv0.3.0

Bastide tient trois mécanismes qui évitent de refaire le même travail : le cache HTTP de l'edge, qui sert une réponse déjà produite sans solliciter votre application ; la transformation d'images, incluse au forfait ; et le cache distant de construction, compatible Turborepo. Cette page dit comment chacun décide, comment le vider et ce qu'il coûte.

Le cache HTTP de l'edge

Le cache de l'edge suit un contrat publié : en lisant les en-têtes de votre réponse, vous savez sans essai si elle sera rangée. Rien n'est rangé par défaut ; c'est votre application qui le demande.

Ce qui se range

Une réponse est rangée quand toutes ces conditions tiennent :

  • la requête est un GET ou un HEAD, sans en-tête Range, Authorization ni Upgrade ;
  • l'en-tête qui gouverne porte une durée explicite, sans private, no-cache ni no-store ;
  • le statut est 200, 301, 302, 307, 308, 404 ou 410 ;
  • la réponse ne pose pas de témoin (Set-Cookie) et ne porte pas Vary: * ;
  • elle pèse 20 Mo au plus, et un 200 a un corps.

L'en-tête qui gouverne est le premier présent parmi Glowsoft-CDN-Cache-Control, CDN-Cache-Control et Cache-Control, et lui seul. Glowsoft-CDN-Cache-Control ne parle qu'au cache de la plateforme ; CDN-Cache-Control aussi à un CDN que vous placeriez devant ; Cache-Control s'adresse d'abord au navigateur.

La durée est s-maxage. max-age ne compte que dans un en-tête ciblé (Glowsoft-CDN-Cache-Control ou CDN-Cache-Control), jamais dans Cache-Control, où il reste la durée du navigateur. Elle est bornée à un an. Expires et les durées heuristiques ne sont pas lus.

Cache-Control: public, max-age=60, s-maxage=3600

Cette réponse est gardée une heure par l'edge et une minute par le navigateur.

Ce qu'il faut savoir

  • La clé du cache est la méthode, le nom d'hôte, le chemin et la chaîne de requête. Les témoins de la requête n'en font pas partie : une réponse rangeable ne doit pas en dépendre.
  • Un Vary autre que * range une variante par valeur des en-têtes nommés.
  • Le Cache-Control envoyé par un visiteur ne contourne rien : un no-cache du navigateur ne force pas l'origine.
  • Une entrée échue n'est jamais servie : stale-while-revalidate et stale-if-error ne sont pas encore honorés.
  • Un If-None-Match qui désigne l'entrée rangée reçoit 304, depuis le cache.
  • Un redéploiement de l'environnement purge tout ce que la version précédente avait rangé.
  • Glowsoft-CDN-Cache-Control et Glowsoft-Cache-Tag ne sont jamais renvoyés au visiteur.

Lire la décision du cache

Chaque réponse porte l'en-tête Cache-Status (RFC 9211) : hit quand elle vient du cache. Quand le cache ne l'a ni lue ni rangée, detail= donne le motif.

MotifCause
METHODENi GET ni HEAD.
PLAGEUn en-tête Range.
AUTORISATIONUn en-tête Authorization.
PASSAGEUn en-tête Upgrade (WebSocket).
STATUTUn statut hors de la liste.
TEMOINLa réponse pose un témoin.
VARY-ETOILEVary: *.
PRIVEprivate, no-cache ou no-store.
SANS-DUREEAucune durée explicite.
TROP-GRAND, TROP-GRAND-EN-FLUXPlus de 20 Mo, annoncés ou découverts en flux.
CORPS-VIDEUn 200 sans corps.

Révoquer par étiquette

Votre application peut étiqueter ses réponses par l'en-tête Glowsoft-Cache-Tag : des étiquettes séparées par des virgules, 256 caractères au plus chacune. Les étiquettes sont rangées par projet et par environnement : aucune ne traverse un autre locataire.

Glowsoft-Cache-Tag: produit:4512, catalogue

Quand le produit 4512 change, révoquez l'étiquette plutôt que tout le cache. Deux modes existent :

  • invalidate (recommandé) : l'entrée périmée est servie une dernière fois et revalidée derrière, si bien que le visiteur ne voit pas l'origine ralentir ;
  • delete : l'entrée est détruite. Employez-le pour retirer un contenu qui ne doit plus être servi.

La révocation prend effet en région en moins de deux secondes, d'après l'API.

Depuis la console

Ouvrez Domaines, puis la carte Cache de l'edge. Choisissez l'environnement (la production par défaut), saisissez les étiquettes une par ligne, choisissez le mode, puis Purger.

Par la ligne de commande ou l'API

bastide cache tag revoke --project-id prj_01JQ8ZK4M7NP2RSTVWXYZ34567 --tags '["produit:4512","catalogue"]'
{
  "projectId": "prj_01JQ8ZK4M7NP2RSTVWXYZ34567",
  "tags": ["produit:4512", "catalogue"],
  "mode": "invalidate",
  "idempotencyKey": "purge-produit-4512-2026-10-14"
}

Ce corps part en POST /v1/projects/{projectId}/cache/purge sur https://api.bastide.app. Sans environmentId, la révocation vise la production. Cent étiquettes au plus par appel, sans virgule. Le geste demande le rang Développeur et une personne : il n'est ouvert ni aux agents ni aux comptes de service.

Les transformations d'images

Chaque site sert /_bastide/image, qui redimensionne une image et la convertit en AVIF ou en WebP selon ce que le navigateur accepte. Les images du site lui-même sont toujours admises ; une source distante doit figurer dans la liste du projet. Chaque URL est signée : une URL non signée, mal signée ou dont la source n'est pas admise reçoit 403 avant toute lecture.

Les paramètres

ParamètreSens
srcUn chemin du site (/images/a.jpg) ou une URL https:// d'une source admise.
w, hLargeur et hauteur, de 1 à 8 192 pixels.
qQualité, de 1 à 100 ; 75 par défaut.
fitcover (défaut), contain ou fill.
formatavif, webp ou origin ; à défaut, négocié par l'en-tête Accept.
sLa signature. Tout autre paramètre est refusé.

Signer une URL

La signature est un HMAC-SHA256 de la chaîne canonique, encodé en base64url sans remplissage. La chaîne canonique reprend les paramètres présents parmi src, w, h, q, fit et format, dans cet ordre, sous la forme nom=valeur (valeur encodée comme par encodeURIComponent), séparés par &. La clé est celle que rend le réglage des images, en hexadécimal.

import { createHmac } from "node:crypto";

const cle = Buffer.from(process.env.IMAGES_CLE_DE_SIGNATURE, "hex");

export function urlDImage(src, largeur, qualite = 75) {
  const p = new URLSearchParams({ src, w: String(largeur), q: String(qualite) });
  const canonique = ["src", "w", "h", "q", "fit", "format"]
    .filter((n) => p.has(n))
    .map((n) => `${n}=${encodeURIComponent(p.get(n))}`)
    .join("&");
  p.set("s", createHmac("sha256", cle).update(canonique).digest("base64url"));
  return `/_bastide/image?${p}`;
}

Régler les sources et la clé

Ouvrez Domaines, puis la carte Images. Elle montre le compteur de transformations du mois, la génération de la clé et la liste des sources distantes admises, une par ligne (50 au plus, en https).

  • Enregistrer et montrer la clé règle la liste et affiche la clé de signature. Elle ne se montre qu'à ce moment : posez-la aussitôt en variable secrète de votre application. Voir Environnements et variables.
  • Renouveler la clé en tire une nouvelle : toutes les URL signées sous l'ancienne cessent d'être servies.
  • Optimiser à l'écriture donne à chaque image déposée au stockage une variante allégée, servie sans transformation à la lecture. Le réglage est éteint à l'origine.

Les mêmes réglages passent par image.configure et se lisent par image.read, par l'API (PUT et GET /v1/projects/{projectId}/images) ou la ligne de commande (bastide image configure, bastide image read). Régler demande le rang Mainteneur ; lire, le rang Lecteur. Aucun outil MCP ne les porte : la clé est un secret, et aucun outil ne rend de secret.

Ce qui est compté

Seule une transformation faite est comptée. Une image reprise du cache de l'edge ne l'est pas, ni une image servie telle quelle : un SVG, un GIF ou un WebP animé, une source de moins de 10 Ko, ou un format que la transformation ne lit pas. Ces images portent l'en-tête X-Image-Diagnostic, qui dit pourquoi.

Une image transformée est gardée 31 jours par l'edge, dans la portée de l'environnement et de sa version : un redéploiement la périme.

DécouverteStandardProSouverain
Transformations incluses par mois5 00050 000250 0001 000 000

Au-delà du volume inclus, l'image est servie telle quelle, sans transformation et sans facturation. Une alerte part à 80 % du volume du mois : l'événement project.images.threshold, vers vos webhooks et vos notifications.

Limites d'une image

LimiteValeur
Dimensions de la source8 192 pixels de côté
Poids de la source25 Mo
Poids de la sortie10 Mo
Sources distantes par projet50

Au-delà, la réponse est un 422 qui nomme la limite. Une source illisible donne 502 ; une transformation qui ne répond pas, 503.

Le cache distant de construction

Turborepo peut déposer et relire ses artefacts dans un cache distant tenu par Bastide, par le protocole /v8/artifacts. L'équipe Turborepo est le projet. Pour l'utiliser depuis votre poste ou votre intégration continue :

export TURBO_API=https://api.bastide.app
export TURBO_TEAM=prj_01JQ8ZK4M7NP2RSTVWXYZ34567
export TURBO_TOKEN=<jeton personnel ou de service>

Lire le cache demande le droit de lire le projet ; y déposer, celui de déployer (rang Développeur, portée deploy:write). Les constructions de la plateforme reçoivent leur propre jeton, limité au cache de leur projet et retiré dès la fin de la construction. Un artefact qui contient un secret est refusé, et le refus nomme le fichier. Un artefact de plus de 128 Mo n'est pas mis en cache ; Turborepo continue sans lui.

Rétention et purge

La rétention va de 1 à 30 jours, 7 par défaut ; elle vaut pour les dépôts suivants. La purge prend effet à l'appel : un artefact purgé n'est plus servi.

  • Console : Réglages du projet, carte Cache distant Turborepo. La purge y est totale.
  • Agent : l'outil build_cache_manage, qui purge aussi par empreinte Turborepo.
  • Ligne de commande : bastide build_cache manage --project-id prj_… --retention-days 14.
{
  "projectId": "prj_01JQ8ZK4M7NP2RSTVWXYZ34567",
  "purge": [],
  "idempotencyKey": "purge-cache-distant-2026-10-14"
}

Une liste purge vide vide tout le cache ; une liste d'empreintes (1 000 au plus) ne retire que celles-ci. La réponse dit combien d'artefacts et d'octets ont été purgés, et ce que le cache tient encore.

Erreurs fréquentes

Symptôme ou codeCauseRemède
Cache-Status avec detail=SANS-DUREEAucune durée pour l'edge.Ajouter s-maxage à Cache-Control, ou poser Glowsoft-CDN-Cache-Control.
detail=TEMOINLa page pose un témoin de session.Ne pas poser de témoin sur les réponses publiques.
detail=PRIVEprivate ou no-store dans l'en-tête qui gouverne.Retirer la directive, ou cibler l'edge par Glowsoft-CDN-Cache-Control.
Une page modifiée reste ancienneElle est encore dans sa durée de cache.Révoquer son étiquette, ou redéployer.
403 sur /_bastide/imageSignature fausse, paramètre non signé, ou source hors de la liste.Vérifier la chaîne canonique et la clé ; ajouter la source.
Images servies sans transformationPlafond du mois atteint, ou image exemptée.Lire X-Image-Diagnostic ; changer de palier si le plafond est en cause.
images_non_regleesLa transformation d'images n'est pas en service sur cette installation.Contacter le support.
valeur_rendue_une_foisRejeu d'un réglage qui a déjà rendu sa clé.Régler de nouveau pour obtenir la clé ; elle n'est pas gardée.

Voir aussi

Signaler une erreur sur cette page