Skip to content
smallPict

Votre propre stockage + CDN

Connectez votre propre stockage objet et votre propre CDN avec les offres API Velocity et Momentum : configuration par fournisseur, autorisations minimales, vérification de la connexion et ce qui se passe lorsque vous changez de mode.

Disponible avec : les offres API Velocity et Momentum. Non disponible avec Ignite (sans CDN), dans le sandbox développeur (les fichiers du sandbox sont temporaires), ni avec les offres WordPress (elles utilisent le CDN smallPict géré).

En bref : en mode BYO, smallPict écrit vos originaux et vos images optimisées dans votre bucket, et votre CDN les diffuse. Le stockage et le CDN sont toujours connectés ensemble : vous ne pouvez pas apporter l’un sans l’autre.


Qu’est-ce que le BYO

Velocity et Momentum proposent deux modes de diffusion. Vous en choisissez un dans Tableau de bord → CDN et stockage.

  • Géré (par défaut) : smallPict conserve vos originaux dans son stockage chiffré (déplacés vers une archive longue durée après 90 jours) et diffuse les images optimisées depuis cdn.smallpict.app. Rien à configurer.
  • Votre propre stockage + CDN (BYO) : vous connectez un bucket compatible S3 dans votre propre compte et un CDN dans votre propre compte. Chaque nouvelle tâche écrit l’original et le fichier optimisé dans votre bucket, et l’API renvoie des URL sur le domaine de votre CDN.

Cette règle de couplage existe parce que smallPict doit pouvoir assurer les deux moitiés de la diffusion : écrire les fichiers et retirer les copies obsolètes du cache. Un bucket sans CDN laisserait les purges de cache sans destination ; un CDN sans bucket n’aurait rien à diffuser.


Géré ou BYO

Géré (par défaut)Votre propre stockage + CDN
OriginauxStockage chiffré smallPictoriginals/<job_id>/<file> dans votre bucket
Fichiers optimisésDiffusés depuis cdn.smallpict.appoptimized/<job_id>.<ext> dans votre bucket, diffusés depuis le domaine de votre CDN
Quota de stockageVelocity 50 Go, Momentum 100 GoNon décompté. Vous payez votre fournisseur de stockage.
Bande passante CDNVelocity 30 Go/mois, Momentum 200 Go/moisNon décomptée. Vous payez votre fournisseur de CDN.
TransformationsDécomptées de votre offreDécomptées de votre offre
Copie conservée par smallPictOui, tant que votre compte est actifAucune. Seul le téléversement temporaire de traitement, supprimé sous 24 heures.
Purge du cacheAutomatiqueAutomatique, via l’API de votre CDN
Performances, domaine et coûts du CDNsmallPictVous. smallPict n’est pas responsable des performances, des domaines ni des factures de votre CDN.

Fournisseurs pris en charge

Stockage (disponible dès aujourd’hui) : Amazon S3, Cloudflare R2, Google Cloud Storage (interopérabilité S3), Alibaba Cloud OSS, Tencent Cloud COS, DigitalOcean Spaces, SumoPod Storage, MinIO, ainsi que tout autre service compatible S3 via un point de terminaison personnalisé (par exemple Hetzner, Vultr ou Wasabi).

CDN (disponible dès aujourd’hui) : Cloudflare et Amazon CloudFront.

Prévu : Azure Blob Storage et d’autres CDN. Vous pouvez demander un accès anticipé sur la page Fournisseurs cloud.


Avant de commencer

  1. Vous disposez de l’offre API Velocity ou Momentum et êtes connecté en tant qu’administrateur du compte.
  2. Vous avez un bucket, ainsi qu’un CDN qui diffuse les fichiers de ce bucket en HTTPS.
  3. Le point de terminaison de stockage est joignable depuis Internet en HTTPS. Les points de terminaison privés, internes ou en HTTP simple sont refusés.
  4. Vous avez créé des clés restreintes pour smallPict (voir Autorisations minimales ci-dessous). N’utilisez pas les clés root ou administrateur de votre compte.

Ouvrez ensuite Tableau de bord → CDN et stockage, choisissez Votre propre stockage + CDN, remplissez les deux parties et sélectionnez Enregistrer stockage + CDN. smallPict exécute la vérification de la connexion (décrite ci-dessous) et ne vous fait passer en BYO que si elle réussit.


Guides de configuration

A. Amazon S3 + Amazon CloudFront

  1. Créez le bucket dans la région de votre choix, par exemple my-images dans ap-southeast-1. Laissez Block Public Access activé.
  2. Créez une distribution CloudFront avec le bucket comme origine. Utilisez Origin access control (OAC) pour que CloudFront puisse lire le bucket tout en le gardant privé, et appliquez la stratégie de bucket que CloudFront vous propose.
  3. Facultatif : votre propre domaine. Ajoutez à la distribution un nom de domaine alternatif (par exemple images.example.com) et un certificat, puis faites pointer un enregistrement DNS vers la distribution.
  4. Créez un utilisateur (ou un rôle) IAM pour le stockage avec cette stratégie :
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "s3:PutObject",        "s3:GetObject",        "s3:DeleteObject"      ],      "Resource": "arn:aws:s3:::my-images/*"    }  ]}
  1. Créez un utilisateur IAM pour CloudFront (il peut s’agir du même utilisateur) avec cette stratégie. cloudfront:GetDistribution est facultatif ; avec cette autorisation, smallPict peut détecter le domaine de la distribution lorsque vous laissez le domaine CDN vide.
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "cloudfront:CreateInvalidation",        "cloudfront:GetDistribution"      ],      "Resource": "arn:aws:cloudfront::123456789012:distribution/E2QWRUHAPOMQZL"    }  ]}
  1. Dans le tableau de bord :
    • Fournisseur de stockage Amazon S3, bucket my-images, région ap-southeast-1, point de terminaison vide (le point de terminaison standard de la région est utilisé), ainsi que l’access key ID et le secret du stockage.
    • CDN Amazon CloudFront, le Distribution ID (par exemple E2QWRUHAPOMQZL), l’access key ID et le secret CloudFront et, si vous le souhaitez, le domaine CDN (https://images.example.com). Laissez le domaine vide pour utiliser le domaine *.cloudfront.net propre à la distribution.

B. Cloudflare R2 + Cloudflare

  1. Créez un bucket R2, par exemple my-images.
  2. Connectez un domaine personnalisé au bucket (R2 → votre bucket → Settings → Custom Domains), par exemple images.example.com, sur une zone du même compte Cloudflare. Les requêtes vers ce domaine passent par le cache Cloudflare. N’utilisez pas l’URL de développement r2.dev en production.
  3. Créez un jeton d’API R2 (R2 → Manage API tokens) avec Object Read & Write, limité à ce seul bucket. Copiez l’Access Key ID et le Secret Access Key affichés.
  4. Créez un jeton d’API Cloudflare (My Profile → API Tokens) pour la zone avec Zone → Cache Purge → Purge. Zone → Zone → Read est facultatif.
  5. Dans le tableau de bord :
    • Fournisseur de stockage Cloudflare R2, bucket my-images, point de terminaison https://<account_id>.r2.cloudflarestorage.com (affiché dans les détails de l’API S3 de votre bucket), région auto, ainsi que l’Access Key ID et le Secret Access Key R2.
    • CDN Cloudflare, le Zone ID (page Overview du domaine, section API), le jeton d’API et le domaine CDN https://images.example.com.

C. Google Cloud Storage + Cloudflare

Google Cloud Storage se connecte via son API XML compatible S3, avec des clés HMAC.

  1. Créez le bucket, par exemple my-images.
  2. Créez un compte de service et attribuez-lui Storage Object User (roles/storage.objectUser) sur ce bucket uniquement.
  3. Créez une clé HMAC pour le compte de service : Cloud Storage → Settings → Interoperability → Create a key for a service account. Copiez l’ID d’accès et le secret.
  4. Rendez les fichiers optimisés lisibles par votre CDN. Cloudflare récupère les fichiers dans Cloud Storage en HTTPS, donc les objets sous optimized/ doivent être lisibles publiquement. Avec l’accès uniforme au niveau du bucket, accorder le rôle Storage Object Viewer à allUsers rend tout le bucket lisible, originals/ compris. Si vos originaux doivent rester privés, placez une couche d’authentification devant (par exemple un Cloudflare Worker qui signe les requêtes vers le bucket).
  5. Faites pointer un enregistrement DNS Cloudflare proxifié vers Cloud Storage, par exemple images.example.com. Nommez le bucket d’après le nom d’hôte et utilisez un CNAME proxifié vers c.storage.googleapis.com, ou utilisez une Origin Rule Cloudflare qui envoie les requêtes vers storage.googleapis.com avec le nom du bucket au début du chemin.
  6. Créez un jeton d’API Cloudflare pour la zone avec Zone → Cache Purge → Purge (Zone → Zone → Read facultatif).
  7. Dans le tableau de bord : fournisseur de stockage Google Cloud Storage, bucket, point de terminaison https://storage.googleapis.com, région auto, l’ID d’accès et le secret HMAC ; CDN Cloudflare, Zone ID, jeton d’API et domaine CDN https://images.example.com.

D. MinIO ou tout stockage compatible S3 + Cloudflare

Cette section couvre MinIO et les services compatibles S3 tels que Hetzner, Wasabi, Vultr, SumoPod, Alibaba Cloud OSS, Tencent Cloud COS et DigitalOcean Spaces.

FournisseurChoix dans le tableau de bordPoint de terminaisonRemarques
MinIOMinIOVotre serveur, p. ex. https://minio.example.comRequêtes path-style activées. Le serveur doit être joignable depuis Internet en HTTPS.
Hetzner Object StoragePersonnalisé compatible S3https://<location>.your-objectstorage.com
WasabiPersonnalisé compatible S3https://s3.<region>.wasabisys.com
Vultr Object StoragePersonnalisé compatible S3https://<region>.vultrobjects.com
SumoPod StorageSumoPod StorageDans votre tableau de bord de stockage SumoPodPath-style activé par défaut.
Alibaba Cloud OSSAlibaba Cloud OSShttps://oss-<region>.aliyuncs.comStyle virtual-hosted uniquement.
Tencent Cloud COSTencent Cloud COShttps://cos.<region>.myqcloud.comLe nom du bucket inclut votre APPID, p. ex. my-images-1250000000.
DigitalOcean SpacesDigitalOcean Spaceshttps://<region>.digitaloceanspaces.com
  1. Créez le bucket et une clé limitée à ce bucket avec les droits put, get et delete sur les objets (voir Autorisations minimales ci-dessous).
  2. Rendez optimized/ lisible par votre CDN, par exemple avec une stratégie de bucket qui autorise s3:GetObject anonyme sur optimized/* uniquement. Sur MinIO :
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Principal": {        "AWS": [          "*"        ]      },      "Action": [        "s3:GetObject"      ],      "Resource": [        "arn:aws:s3:::my-images/optimized/*"      ]    }  ]}
  1. Placez Cloudflare devant le bucket : un enregistrement DNS proxifié pour images.example.com qui pointe vers l’hôte public du bucket. Si le fournisseur exige son propre nom d’hôte dans la requête, ajoutez une Origin Rule Cloudflare qui réécrit l’en-tête Host (et, pour les hôtes path-style, ajoute le nom du bucket au chemin).
  2. Créez un jeton d’API Cloudflare pour la zone avec Zone → Cache Purge → Purge (Zone → Zone → Read facultatif).
  3. Dans le tableau de bord : choisissez le fournisseur dans le tableau, saisissez le bucket, le point de terminaison, la région (auto si le fournisseur n’en a pas) et les clés ; activez les requêtes path-style lorsque le tableau l’indique ; puis CDN Cloudflare, Zone ID, jeton d’API et domaine CDN.

Autorisations minimales

Donnez à smallPict des clés qui ne peuvent faire que le nécessaire, sur un seul bucket.

FournisseurAutorisations
Amazon S3s3:PutObject, s3:GetObject, s3:DeleteObject sur arn:aws:s3:::<bucket>/*
Amazon CloudFrontcloudfront:CreateInvalidation sur la distribution ; cloudfront:GetDistribution facultatif pour que le domaine puisse être détecté
Cloudflare R2Jeton d’API R2 avec Object Read & Write, limité au bucket
Cloudflare (CDN)Jeton d’API pour la zone avec Zone → Cache Purge → Purge ; Zone → Zone → Read facultatif
Google Cloud StorageClé HMAC pour un compte de service disposant de roles/storage.objectUser sur le bucket
Alibaba Cloud OSSUtilisateur RAM avec oss:PutObject, oss:GetObject, oss:DeleteObject sur le bucket
Tencent Cloud COSSous-utilisateur CAM avec cos:PutObject, cos:GetObject, cos:DeleteObject sur le bucket (le nom du bucket inclut l’APPID)
DigitalOcean SpacesClé d’accès Spaces limitée au bucket, avec lecture, écriture et suppression
MinIO / personnalisé compatible S3Put, get et delete sur <bucket>/* ; le point de terminaison doit être en HTTPS public

La vérification de la connexion

À chaque enregistrement (et lorsque vous sélectionnez Relancer la vérification), smallPict vérifie l’ensemble de la connexion avant de l’utiliser :

  1. Stockage : écrit un petit fichier de test sous .smallpict-probe/ dans votre bucket, le relit puis le supprime.
  2. Cloudflare : envoie à votre zone une purge de test portant sur une seule URL.
  3. CloudFront : crée une invalidation de test pour un chemin /.smallpict-probe/.... Elle est décomptée de vos chemins d’invalidation CloudFront du mois.

Si une étape échoue, rien n’est basculé. Le tableau de bord affiche la raison à côté du champ concerné, par exemple le nom du bucket ou le jeton d’API. La vérification de la connexion est limitée à 5 tentatives par minute.


Accès de votre CDN au bucket

  • optimized/ doit être lisible par votre CDN : soit en lecture publique sur ce préfixe, soit via un accès d’origine du CDN à un bucket privé (Origin access control de CloudFront ou domaine personnalisé R2).
  • originals/ peut rester privé. Votre CDN n’en a jamais besoin.
  • CORS n’est nécessaire que si des navigateurs récupèrent les images en cross-origin depuis JavaScript (par exemple avec fetch() ou un canvas). Les balises <img> simples n’en ont pas besoin. Si vous en avez besoin, autorisez GET et HEAD depuis l’origine de votre site.

Organisation des objets et URL

QuoiClé dans votre bucketURL
Originaloriginals/<job_id>/<file>Non diffusé
Fichier optimiséoptimized/<job_id>.<ext><cdn_domain>/optimized/<job_id>.<ext>

Le domaine CDN peut inclure un préfixe de chemin, par exemple https://example.com/images ; l’URL devient alors https://example.com/images/optimized/<job_id>.<ext>.


En-têtes de cache

Les fichiers optimisés sont écrits avec Cache-Control: public, max-age=31536000, immutable. Chaque tâche reçoit une clé unique : un nouveau résultat a donc toujours une nouvelle URL, et une purge est rarement nécessaire. Veillez à ce que les règles de cache de votre CDN ne remplacent pas cet en-tête par une durée plus courte.


Purge du cache

  • Les demandes de purge faites via l’API (POST /v1/purge) sont envoyées par lots à votre CDN.
  • Sur Cloudflare, les fichiers sont purgés par URL. « Purge all » purge uniquement votre hôte de diffusion et votre préfixe de chemin, pas toute votre zone.
  • Sur CloudFront, les fichiers sont purgés au moyen d’invalidations. « Purge all » crée une invalidation /*. Les chemins d’invalidation au-delà du quota gratuit mensuel de CloudFront sont facturés par AWS à votre compte.

Changer de mode

Changer de mode ne déplace pas les fichiers existants. Les fichiers déjà diffusés conservent leurs URL actuelles ; seules les nouvelles tâches utilisent le nouveau mode.

  • Géré → BYO : les nouvelles tâches vont dans votre bucket et sont diffusées par votre CDN. Les fichiers déjà présents sur cdn.smallpict.app y restent.
  • BYO → géré : les nouvelles tâches utilisent à nouveau le stockage et le CDN gérés. Vos paramètres et clés BYO restent enregistrés mais inutilisés, afin que vous puissiez revenir en arrière sans les saisir à nouveau, jusqu’à ce que vous sélectionniez Déconnecter.
  • Déconnecter : supprime les clés et les paramètres BYO enregistrés et vous ramène au mode géré. Les fichiers de votre bucket ne sont pas touchés.

En cas d’échec

  • Si smallPict ne peut pas écrire dans votre bucket, il réessaie, puis fait échouer la tâche avec une raison que vous pouvez lire dans la réponse de l’API.
  • Le tableau de bord affiche la dernière erreur et sa date, avec un bouton Relancer la vérification.
  • Vous recevez un e-mail par incident, et non un par tâche échouée.
  • smallPict ne se replie jamais sur le stockage géré. Vos fichiers ne sont jamais stockés à un endroit que vous n’avez pas choisi.

Sécurité

  • Les clés sont conservées dans un coffre de secrets chiffré. Elles ne sont plus jamais affichées, jamais renvoyées par l’API et jamais écrites dans les journaux.
  • Pour renouveler une clé, saisissez la nouvelle et enregistrez ; la vérification de la connexion s’exécute avec la nouvelle clé. Laissez un champ de clé vide pour conserver la clé enregistrée.
  • Les points de terminaison de stockage et de CDN doivent utiliser HTTPS. Les points de terminaison qui se résolvent en adresses privées, de loopback, link-local ou autres adresses internes sont refusés.
  • Utilisez des clés distinctes et restreintes pour smallPict, et révoquez-les dans la console de votre fournisseur si vous cessez d’utiliser le BYO.