Skip to content
smallPict

Eigen opslag + CDN

Koppel je eigen objectopslag en je eigen CDN op de API-abonnementen Velocity en Momentum: instellen per provider, minimale machtigingen, de verbindingscontrole en wat er gebeurt als je van modus wisselt.

Beschikbaar op: de API-abonnementen Velocity en Momentum. Niet beschikbaar op Ignite (dat heeft geen CDN), in de ontwikkelaarssandbox (sandboxbestanden zijn tijdelijk) en op WordPress-abonnementen (die gebruiken het beheerde smallPict-CDN).

Kort gezegd: In BYO-modus schrijft smallPict je originelen en geoptimaliseerde afbeeldingen naar jouw bucket, en jouw CDN levert ze uit. Opslag en CDN worden altijd samen gekoppeld: je kunt het een niet zonder het ander meebrengen.


Wat BYO is

Velocity en Momentum hebben twee leveringsmodi. Je kiest er een in Dashboard → CDN en opslag.

  • Beheerd (de standaard): smallPict bewaart je originelen in zijn versleutelde opslag (na 90 dagen verplaatst naar langetermijnarchief) en levert geoptimaliseerde afbeeldingen vanaf cdn.smallpict.app. Niets in te stellen.
  • Eigen opslag + CDN (BYO): je koppelt een S3-compatibele bucket in je eigen account en een CDN in je eigen account. Elke nieuwe taak schrijft het origineel en het geoptimaliseerde bestand naar je bucket, en de API geeft URL’s op je CDN-domein terug.

De koppelregel bestaat omdat smallPict beide helften van de levering moet kunnen uitvoeren: bestanden schrijven en verouderde kopieën uit de cache verwijderen. Een bucket zonder CDN zou cachepurges nergens naartoe kunnen sturen; een CDN zonder bucket zou niets te leveren hebben.


Beheerd vs. BYO

Beheerd (standaard)Eigen opslag + CDN
OriginelenVersleutelde opslag van smallPictoriginals/<job_id>/<file> in je bucket
Geoptimaliseerde bestandenGeleverd vanaf cdn.smallpict.appoptimized/<job_id>.<ext> in je bucket, geleverd vanaf je CDN-domein
OpslagquotumVelocity 50 GB, Momentum 100 GBTelt niet mee. Je betaalt je opslagprovider.
CDN-bandbreedteVelocity 30 GB/maand, Momentum 200 GB/maandTelt niet mee. Je betaalt je CDN-provider.
TransformatiesTellen mee voor je abonnementTellen mee voor je abonnement
Kopie bewaard door smallPictJa, zolang je account actief isGeen. Alleen de tijdelijke upload voor verwerking, die binnen 24 uur wordt verwijderd.
CachepurgeAutomatischAutomatisch, via de API van je CDN
CDN-prestaties, domein en kostensmallPictJij. smallPict is niet verantwoordelijk voor de prestaties, domeinen of rekeningen van je CDN.

Ondersteunde providers

Opslag (nu beschikbaar): Amazon S3, Cloudflare R2, Google Cloud Storage (S3-interoperabiliteit), Alibaba Cloud OSS, Tencent Cloud COS, DigitalOcean Spaces, SumoPod Storage, MinIO en elke andere S3-compatibele dienst via een aangepast endpoint (bijvoorbeeld Hetzner, Vultr of Wasabi).

CDN (nu beschikbaar): Cloudflare en Amazon CloudFront.

Gepland: Azure Blob Storage en andere CDN’s. Je kunt vroege toegang aanvragen op de pagina Cloudproviders.


Voordat je begint

  1. Je zit op API Velocity of Momentum en bent ingelogd als accountbeheerder.
  2. Je hebt een bucket, en een CDN dat bestanden uit die bucket via HTTPS levert.
  3. Het opslag-endpoint is via HTTPS bereikbaar vanaf internet. Privé-, interne en gewone HTTP-endpoints worden geweigerd.
  4. Je hebt beperkte sleutels voor smallPict aangemaakt (zie Minimale machtigingen hieronder). Gebruik niet de root- of beheerderssleutels van je account.

Open daarna Dashboard → CDN en opslag, kies Eigen opslag + CDN, vul beide delen in en selecteer Opslag + CDN opslaan. smallPict voert de verbindingscontrole uit (hieronder beschreven) en schakelt je alleen over naar BYO als die slaagt.


Installatiehandleidingen

A. Amazon S3 + Amazon CloudFront

  1. Maak de bucket aan in de gewenste regio, bijvoorbeeld my-images in ap-southeast-1. Laat Block Public Access aan staan.
  2. Maak een CloudFront-distributie aan met de bucket als origin. Gebruik Origin access control (OAC) zodat CloudFront de bucket kan lezen terwijl die privé blijft, en pas het bucketbeleid toe dat CloudFront je aanbiedt.
  3. Optioneel: je eigen domein. Voeg een alternatieve domeinnaam (bijvoorbeeld images.example.com) en een certificaat toe aan de distributie, en laat een DNS-record naar de distributie wijzen.
  4. Maak een IAM-gebruiker (of rol) voor opslag aan met dit beleid:
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "s3:PutObject",        "s3:GetObject",        "s3:DeleteObject"      ],      "Resource": "arn:aws:s3:::my-images/*"    }  ]}
  1. Maak een IAM-gebruiker voor CloudFront aan (dit mag dezelfde gebruiker zijn) met dit beleid. cloudfront:GetDistribution is optioneel; daarmee kan smallPict het domein van de distributie detecteren als je het CDN-domein leeg laat.
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "cloudfront:CreateInvalidation",        "cloudfront:GetDistribution"      ],      "Resource": "arn:aws:cloudfront::123456789012:distribution/E2QWRUHAPOMQZL"    }  ]}
  1. In het dashboard:
    • Opslagprovider Amazon S3, bucket my-images, regio ap-southeast-1, endpoint leeg (het standaard-endpoint van de regio wordt gebruikt), en de access key ID en het secret voor opslag.
    • CDN Amazon CloudFront, de distributie-ID (bijvoorbeeld E2QWRUHAPOMQZL), de access key ID en het secret voor CloudFront, en optioneel het CDN-domein (https://images.example.com). Laat het domein leeg om het eigen *.cloudfront.net-domein van de distributie te gebruiken.

B. Cloudflare R2 + Cloudflare

  1. Maak een R2-bucket aan, bijvoorbeeld my-images.
  2. Koppel een aangepast domein aan de bucket (R2 → je bucket → Settings → Custom Domains), bijvoorbeeld images.example.com, op een zone in hetzelfde Cloudflare-account. Verzoeken naar dat domein gaan via de Cloudflare-cache. Gebruik de ontwikkel-URL r2.dev niet voor productie.
  3. Maak een R2 API-token aan (R2 → Manage API tokens) met Object Read & Write, beperkt tot alleen deze bucket. Kopieer de Access Key ID en Secret Access Key die worden getoond.
  4. Maak een Cloudflare API-token aan (My Profile → API Tokens) voor de zone met Zone → Cache Purge → Purge. Zone → Zone → Read is optioneel.
  5. In het dashboard:
    • Opslagprovider Cloudflare R2, bucket my-images, endpoint https://<account_id>.r2.cloudflarestorage.com (staat bij de S3 API-gegevens van je bucket), regio auto, en de R2 Access Key ID en Secret Access Key.
    • CDN Cloudflare, de zone-ID (Overview-pagina van het domein, onderdeel API), het API-token en het CDN-domein https://images.example.com.

C. Google Cloud Storage + Cloudflare

Google Cloud Storage wordt gekoppeld via de S3-compatibele XML API met HMAC-sleutels.

  1. Maak de bucket aan, bijvoorbeeld my-images.
  2. Maak een serviceaccount aan en geef het Storage Object User (roles/storage.objectUser) op alleen deze bucket.
  3. Maak een HMAC-sleutel aan voor het serviceaccount: Cloud Storage → Settings → Interoperability → Create a key for a service account. Kopieer de access-ID en het secret.
  4. Maak de geoptimaliseerde bestanden leesbaar voor je CDN. Cloudflare haalt bestanden via HTTPS op uit Cloud Storage, dus objecten onder optimized/ moeten openbaar leesbaar zijn. Met uniforme toegang op bucketniveau maakt het toekennen van de rol Storage Object Viewer aan allUsers de hele bucket leesbaar, inclusief originals/. Als je originelen privé moeten blijven, zet er dan een authenticerende laag voor (bijvoorbeeld een Cloudflare Worker die verzoeken aan de bucket ondertekent).
  5. Laat een geproxied Cloudflare-DNS-record naar Cloud Storage wijzen, bijvoorbeeld images.example.com. Geef de bucket de naam van de hostnaam en gebruik een geproxiede CNAME naar c.storage.googleapis.com, of gebruik een Cloudflare Origin Rule die verzoeken naar storage.googleapis.com stuurt met de bucketnaam aan het begin van het pad.
  6. Maak een Cloudflare API-token aan voor de zone met Zone → Cache Purge → Purge (Zone → Zone → Read optioneel).
  7. In het dashboard: opslagprovider Google Cloud Storage, bucket, endpoint https://storage.googleapis.com, regio auto, de HMAC-access-ID en het secret; CDN Cloudflare, zone-ID, API-token en CDN-domein https://images.example.com.

D. MinIO of andere S3-compatibele opslag + Cloudflare

Dit geldt voor MinIO en S3-compatibele diensten zoals Hetzner, Wasabi, Vultr, SumoPod, Alibaba Cloud OSS, Tencent Cloud COS en DigitalOcean Spaces.

ProviderKies in het dashboardEndpointOpmerkingen
MinIOMinIOJe server, bijv. https://minio.example.comPath-style-verzoeken aan. De server moet via HTTPS bereikbaar zijn vanaf internet.
Hetzner Object StorageAangepast S3-compatibelhttps://<location>.your-objectstorage.com
WasabiAangepast S3-compatibelhttps://s3.<region>.wasabisys.com
Vultr Object StorageAangepast S3-compatibelhttps://<region>.vultrobjects.com
SumoPod StorageSumoPod StorageUit je SumoPod-opslagdashboardPath-style standaard aan.
Alibaba Cloud OSSAlibaba Cloud OSShttps://oss-<region>.aliyuncs.comAlleen virtual-hosted-stijl.
Tencent Cloud COSTencent Cloud COShttps://cos.<region>.myqcloud.comDe bucketnaam bevat je APPID, bijv. my-images-1250000000.
DigitalOcean SpacesDigitalOcean Spaceshttps://<region>.digitaloceanspaces.com
  1. Maak de bucket aan en een sleutel die beperkt is tot die bucket, met put, get en delete op objecten (zie Minimale machtigingen hieronder).
  2. Maak optimized/ leesbaar voor je CDN, bijvoorbeeld met een bucketbeleid dat anonieme s3:GetObject alleen op optimized/* toestaat. Op MinIO:
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Principal": {        "AWS": [          "*"        ]      },      "Action": [        "s3:GetObject"      ],      "Resource": [        "arn:aws:s3:::my-images/optimized/*"      ]    }  ]}
  1. Zet Cloudflare voor de bucket: een geproxied DNS-record voor images.example.com dat naar de openbare host van de bucket wijst. Als de provider zijn eigen hostnaam in het verzoek nodig heeft, voeg dan een Cloudflare Origin Rule toe die de Host-header herschrijft (en bij path-style-hosts de bucketnaam aan het pad toevoegt).
  2. Maak een Cloudflare API-token aan voor de zone met Zone → Cache Purge → Purge (Zone → Zone → Read optioneel).
  3. In het dashboard: kies de provider uit de tabel, vul de bucket, het endpoint, de regio (auto als de provider er geen heeft) en de sleutels in; zet path-style-verzoeken aan waar de tabel dat aangeeft; daarna CDN Cloudflare, zone-ID, API-token en CDN-domein.

Minimale machtigingen

Geef smallPict sleutels die alleen kunnen wat nodig is, op één bucket.

ProviderMachtigingen
Amazon S3s3:PutObject, s3:GetObject, s3:DeleteObject op arn:aws:s3:::<bucket>/*
Amazon CloudFrontcloudfront:CreateInvalidation op de distributie; optioneel cloudfront:GetDistribution zodat het domein kan worden gedetecteerd
Cloudflare R2R2 API-token met Object Read & Write, beperkt tot de bucket
Cloudflare (CDN)API-token voor de zone met Zone → Cache Purge → Purge; optioneel Zone → Zone → Read
Google Cloud StorageHMAC-sleutel voor een serviceaccount met roles/storage.objectUser op de bucket
Alibaba Cloud OSSRAM-gebruiker met oss:PutObject, oss:GetObject, oss:DeleteObject op de bucket
Tencent Cloud COSCAM-subgebruiker met cos:PutObject, cos:GetObject, cos:DeleteObject op de bucket (de bucketnaam bevat de APPID)
DigitalOcean SpacesSpaces-toegangssleutel beperkt tot de bucket, met lezen, schrijven en verwijderen
MinIO / aangepast S3-compatibelPut, get en delete op <bucket>/*; het endpoint moet openbare HTTPS zijn

De verbindingscontrole

Telkens wanneer je opslaat (en wanneer je Opnieuw controleren selecteert), controleert smallPict de hele verbinding voordat die wordt gebruikt:

  1. Opslag: schrijft een klein testbestand onder .smallpict-probe/ in je bucket, leest het terug en verwijdert het.
  2. Cloudflare: stuurt één testpurge voor één URL naar je zone.
  3. CloudFront: maakt één testinvalidatie aan voor een pad /.smallpict-probe/.... Die telt mee voor je CloudFront-invalidatiepaden van die maand.

Als een stap mislukt, wordt er niets overgeschakeld. Het dashboard toont de reden naast het betreffende veld, bijvoorbeeld de bucketnaam of het API-token. De verbindingscontrole is beperkt tot 5 pogingen per minuut.


Buckettoegang voor je CDN

  • optimized/ moet leesbaar zijn voor je CDN: openbaar leesbaar op dat prefix, of CDN-origintoegang tot een privébucket (CloudFront origin access control of een aangepast R2-domein).
  • originals/ kan privé blijven. Je CDN heeft het nooit nodig.
  • CORS is alleen nodig als browsers de afbeeldingen cross-origin ophalen vanuit JavaScript (bijvoorbeeld fetch() of een canvas). Gewone <img>-tags hebben het niet nodig. Als je het wel nodig hebt, sta dan GET en HEAD toe vanaf de origin van je site.

Objectindeling en URL’s

WatSleutel in je bucketURL
Origineeloriginals/<job_id>/<file>Niet geleverd
Geoptimaliseerd bestandoptimized/<job_id>.<ext><cdn_domain>/optimized/<job_id>.<ext>

Het CDN-domein mag een padprefix bevatten, bijvoorbeeld https://example.com/images; de URL wordt dan https://example.com/images/optimized/<job_id>.<ext>.


Cacheheaders

Geoptimaliseerde bestanden worden geschreven met Cache-Control: public, max-age=31536000, immutable. Elke taak krijgt een unieke sleutel, dus een nieuw resultaat heeft altijd een nieuwe URL en purgen is zelden nodig. Zorg dat de cacheregels van je CDN deze header niet overschrijven met een kortere tijd.


Cachepurge

  • Purgeverzoeken via de API (POST /v1/purge) gaan gebundeld naar jouw CDN.
  • Bij Cloudflare worden bestanden per URL gepurged. "Alles purgen" purget alleen je leveringshost en padprefix, niet je hele zone.
  • Bij CloudFront worden bestanden gepurged met invalidaties. "Alles purgen" maakt een invalidatie /* aan. Invalidatiepaden boven de maandelijkse gratis hoeveelheid van CloudFront worden door AWS aan je account gefactureerd.

Van modus wisselen

Van modus wisselen verplaatst geen bestaande bestanden. Bestanden die al zijn geleverd, houden hun huidige URL’s; alleen nieuwe taken gebruiken de nieuwe modus.

  • Beheerd → BYO: nieuwe taken gaan naar je bucket en worden door je CDN geleverd. Bestanden die al op cdn.smallpict.app staan, blijven daar.
  • BYO → beheerd: nieuwe taken gebruiken weer beheerde opslag en CDN. Je BYO-instellingen en sleutels blijven opgeslagen maar ongebruikt, zodat je terug kunt schakelen zonder ze opnieuw in te vullen, totdat je Ontkoppelen selecteert.
  • Ontkoppelen: verwijdert de opgeslagen sleutels en BYO-instellingen en zet je terug op beheerd. Bestanden in je bucket worden niet aangeraakt.

Als er iets misgaat

  • Als smallPict niet naar je bucket kan schrijven, probeert het opnieuw en laat het daarna de taak mislukken met een reden die je in het API-antwoord kunt lezen.
  • Het dashboard toont de laatste fout en wanneer die optrad, met een knop Opnieuw controleren.
  • Je krijgt één e-mail per incident, niet één per mislukte taak.
  • smallPict valt nooit terug op beheerde opslag. Je bestanden worden nooit opgeslagen op een plek die je niet zelf hebt gekozen.

Beveiliging

  • Sleutels worden bewaard in een versleutelde opslag voor geheimen. Ze worden nooit meer getoond, nooit door de API teruggegeven en nooit naar logs geschreven.
  • Om een sleutel te roteren, vul je de nieuwe in en sla je op; de verbindingscontrole wordt met de nieuwe sleutel uitgevoerd. Laat een sleutelveld leeg om de opgeslagen sleutel te behouden.
  • Opslag- en CDN-endpoints moeten HTTPS gebruiken. Endpoints die verwijzen naar privé-, loopback-, link-local- of andere interne adressen worden geweigerd.
  • Gebruik aparte, beperkte sleutels voor smallPict en trek ze in via de console van je provider als je stopt met BYO.