Skip to content
smallPict

Tu propio almacenamiento + CDN

Conecta tu propio almacenamiento de objetos y tu propia CDN en los planes API Velocity y Momentum: configuración por proveedor, permisos mínimos, la comprobación de la conexión y qué ocurre al cambiar de modo.

Disponible en: los planes API Velocity y Momentum. No disponible en Ignite (no tiene CDN), en el sandbox para desarrolladores (los archivos del sandbox son temporales) ni en los planes de WordPress (usan la CDN gestionada de smallPict).

En resumen: en el modo BYO, smallPict escribe tus originales y tus imágenes optimizadas en tu bucket, y tu CDN las sirve. El almacenamiento y la CDN siempre se conectan juntos: no puedes traer uno sin el otro.


Qué es BYO

Velocity y Momentum tienen dos modos de entrega. Eliges uno en Panel → CDN y almacenamiento.

  • Gestionado (el predeterminado): smallPict guarda tus originales en su almacenamiento cifrado (se mueven a un archivo a largo plazo después de 90 días) y sirve las imágenes optimizadas desde cdn.smallpict.app. No hay nada que configurar.
  • Usa tu propio almacenamiento + CDN (BYO): conectas un bucket compatible con S3 en tu propia cuenta y una CDN en tu propia cuenta. Cada trabajo nuevo escribe el original y el archivo optimizado en tu bucket, y la API devuelve URL en el dominio de tu CDN.

La regla de ir juntos existe porque smallPict tiene que poder hacer las dos mitades de la entrega: escribir archivos y eliminar de la caché las copias obsoletas. Un bucket sin CDN dejaría las purgas de caché sin destino; una CDN sin bucket no tendría nada que servir.


Gestionado frente a BYO

Gestionado (predeterminado)Usa tu propio almacenamiento + CDN
OriginalesAlmacenamiento cifrado de smallPictoriginals/<job_id>/<file> en tu bucket
Archivos optimizadosServidos desde cdn.smallpict.appoptimized/<job_id>.<ext> en tu bucket, servidos desde el dominio de tu CDN
Cuota de almacenamientoVelocity 50 GB, Momentum 100 GBNo se cuenta. Pagas a tu proveedor de almacenamiento.
Ancho de banda de la CDNVelocity 30 GB/mes, Momentum 200 GB/mesNo se cuenta. Pagas a tu proveedor de CDN.
TransformacionesCuentan para tu planCuentan para tu plan
Copia que guarda smallPictSí, mientras tu cuenta esté activaNinguna. Solo la subida temporal de procesamiento, que se elimina en un plazo de 24 horas.
Purga de cachéAutomáticaAutomática, a través de la API de tu CDN
Rendimiento, dominio y costes de la CDNsmallPictTú. smallPict no es responsable del rendimiento, los dominios ni las facturas de tu CDN.

Proveedores compatibles

Almacenamiento (disponible hoy): Amazon S3, Cloudflare R2, Google Cloud Storage (interoperabilidad S3), Alibaba Cloud OSS, Tencent Cloud COS, DigitalOcean Spaces, SumoPod Storage, MinIO y cualquier otro servicio compatible con S3 mediante un endpoint personalizado (por ejemplo Hetzner, Vultr o Wasabi).

CDN (disponible hoy): Cloudflare y Amazon CloudFront.

Previsto: Azure Blob Storage y otras CDN. Puedes solicitar acceso anticipado en la página Proveedores en la nube.


Antes de empezar

  1. Tienes el plan API Velocity o Momentum y has iniciado sesión como administrador de la cuenta.
  2. Tienes un bucket y una CDN que sirve archivos de ese bucket por HTTPS.
  3. El endpoint de almacenamiento es accesible desde internet por HTTPS. Los endpoints privados, internos o solo HTTP se rechazan.
  4. Has creado claves restringidas para smallPict (consulta Permisos mínimos más abajo). No uses las claves raíz ni de administrador de tu cuenta.

Después abre Panel → CDN y almacenamiento, elige Usa tu propio almacenamiento + CDN, completa las dos partes y selecciona Guardar almacenamiento + CDN. smallPict ejecuta la comprobación de la conexión (descrita más abajo) y solo te cambia a BYO si se supera.


Guías de configuración

A. Amazon S3 + Amazon CloudFront

  1. Crea el bucket en la región que quieras, por ejemplo my-images en ap-southeast-1. Deja activado Block Public Access.
  2. Crea una distribución de CloudFront con el bucket como origen. Usa Origin access control (OAC) para que CloudFront pueda leer el bucket mientras este sigue siendo privado, y aplica la política de bucket que te ofrece CloudFront.
  3. Opcional: tu propio dominio. Añade a la distribución un nombre de dominio alternativo (por ejemplo images.example.com) y un certificado, y apunta un registro DNS a la distribución.
  4. Crea un usuario (o rol) de IAM para el almacenamiento con esta política:
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "s3:PutObject",        "s3:GetObject",        "s3:DeleteObject"      ],      "Resource": "arn:aws:s3:::my-images/*"    }  ]}
  1. Crea un usuario de IAM para CloudFront (puede ser el mismo usuario) con esta política. cloudfront:GetDistribution es opcional; con él, smallPict puede detectar el dominio de la distribución cuando dejas vacío el dominio de la CDN.
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "cloudfront:CreateInvalidation",        "cloudfront:GetDistribution"      ],      "Resource": "arn:aws:cloudfront::123456789012:distribution/E2QWRUHAPOMQZL"    }  ]}
  1. En el panel:
    • Proveedor de almacenamiento Amazon S3, bucket my-images, región ap-southeast-1, endpoint vacío (se usa el endpoint estándar de la región), y el access key ID y el secreto del almacenamiento.
    • CDN Amazon CloudFront, el Distribution ID (por ejemplo E2QWRUHAPOMQZL), el access key ID y el secreto de CloudFront y, opcionalmente, el dominio de la CDN (https://images.example.com). Deja el dominio vacío para usar el dominio *.cloudfront.net propio de la distribución.

B. Cloudflare R2 + Cloudflare

  1. Crea un bucket de R2, por ejemplo my-images.
  2. Conecta un dominio personalizado al bucket (R2 → tu bucket → Settings → Custom Domains), por ejemplo images.example.com, en una zona de la misma cuenta de Cloudflare. Las solicitudes a ese dominio pasan por la caché de Cloudflare. No uses la URL de desarrollo r2.dev en producción.
  3. Crea un token de API de R2 (R2 → Manage API tokens) con Object Read & Write, limitado solo a este bucket. Copia el Access Key ID y el Secret Access Key que muestra.
  4. Crea un token de API de Cloudflare (My Profile → API Tokens) para la zona con Zone → Cache Purge → Purge. Zone → Zone → Read es opcional.
  5. En el panel:
    • Proveedor de almacenamiento Cloudflare R2, bucket my-images, endpoint https://<account_id>.r2.cloudflarestorage.com (se muestra en los detalles de la API de S3 de tu bucket), región auto, y el Access Key ID y el Secret Access Key de R2.
    • CDN Cloudflare, el Zone ID (página Overview del dominio, sección API), el token de API y el dominio de la CDN https://images.example.com.

C. Google Cloud Storage + Cloudflare

Google Cloud Storage se conecta mediante su API XML compatible con S3, con claves HMAC.

  1. Crea el bucket, por ejemplo my-images.
  2. Crea una cuenta de servicio y concédele Storage Object User (roles/storage.objectUser) solo en este bucket.
  3. Crea una clave HMAC para la cuenta de servicio: Cloud Storage → Settings → Interoperability → Create a key for a service account. Copia el ID de acceso y el secreto.
  4. Haz que tu CDN pueda leer los archivos optimizados. Cloudflare obtiene los archivos de Cloud Storage por HTTPS, así que los objetos de optimized/ deben poder leerse públicamente. Con el acceso uniforme a nivel de bucket, conceder a allUsers el rol Storage Object Viewer hace legible todo el bucket, incluido originals/. Si tus originales deben seguir siendo privados, coloca delante una capa que autentique (por ejemplo un Cloudflare Worker que firme las solicitudes al bucket).
  5. Apunta un registro DNS de Cloudflare con proxy a Cloud Storage, por ejemplo images.example.com. Puedes nombrar el bucket como el nombre de host y usar un CNAME con proxy hacia c.storage.googleapis.com, o usar una Origin Rule de Cloudflare que envíe las solicitudes a storage.googleapis.com con el nombre del bucket al principio de la ruta.
  6. Crea un token de API de Cloudflare para la zona con Zone → Cache Purge → Purge (Zone → Zone → Read opcional).
  7. En el panel: proveedor de almacenamiento Google Cloud Storage, bucket, endpoint https://storage.googleapis.com, región auto, el ID de acceso y el secreto HMAC; CDN Cloudflare, Zone ID, token de API y dominio de la CDN https://images.example.com.

D. MinIO o cualquier almacenamiento compatible con S3 + Cloudflare

Esto cubre MinIO y servicios compatibles con S3 como Hetzner, Wasabi, Vultr, SumoPod, Alibaba Cloud OSS, Tencent Cloud COS y DigitalOcean Spaces.

ProveedorQué elegir en el panelEndpointNotas
MinIOMinIOTu servidor, p. ej. https://minio.example.comSolicitudes path-style activadas. El servidor debe ser accesible desde internet por HTTPS.
Hetzner Object StoragePersonalizado compatible con S3https://<location>.your-objectstorage.com
WasabiPersonalizado compatible con S3https://s3.<region>.wasabisys.com
Vultr Object StoragePersonalizado compatible con S3https://<region>.vultrobjects.com
SumoPod StorageSumoPod StorageEn tu panel de almacenamiento de SumoPodPath-style activado por defecto.
Alibaba Cloud OSSAlibaba Cloud OSShttps://oss-<region>.aliyuncs.comSolo estilo virtual-hosted.
Tencent Cloud COSTencent Cloud COShttps://cos.<region>.myqcloud.comEl nombre del bucket incluye tu APPID, p. ej. my-images-1250000000.
DigitalOcean SpacesDigitalOcean Spaceshttps://<region>.digitaloceanspaces.com
  1. Crea el bucket y una clave limitada a ese bucket con permisos de put, get y delete sobre los objetos (consulta Permisos mínimos más abajo).
  2. Haz que tu CDN pueda leer optimized/, por ejemplo con una política de bucket que permita s3:GetObject anónimo solo en optimized/*. En MinIO:
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Principal": {        "AWS": [          "*"        ]      },      "Action": [        "s3:GetObject"      ],      "Resource": [        "arn:aws:s3:::my-images/optimized/*"      ]    }  ]}
  1. Pon Cloudflare delante del bucket: un registro DNS con proxy para images.example.com que apunte al host público del bucket. Si el proveedor necesita su propio nombre de host en la solicitud, añade una Origin Rule de Cloudflare que reescriba la cabecera Host (y, en hosts path-style, añada el nombre del bucket a la ruta).
  2. Crea un token de API de Cloudflare para la zona con Zone → Cache Purge → Purge (Zone → Zone → Read opcional).
  3. En el panel: elige el proveedor de la tabla, introduce el bucket, el endpoint, la región (auto si el proveedor no tiene) y las claves; activa las solicitudes path-style donde la tabla lo indique; después CDN Cloudflare, Zone ID, token de API y dominio de la CDN.

Permisos mínimos

Da a smallPict claves que solo puedan hacer lo que necesita, en un único bucket.

ProveedorPermisos
Amazon S3s3:PutObject, s3:GetObject, s3:DeleteObject en arn:aws:s3:::<bucket>/*
Amazon CloudFrontcloudfront:CreateInvalidation en la distribución; cloudfront:GetDistribution opcional para poder detectar el dominio
Cloudflare R2Token de API de R2 con Object Read & Write, limitado al bucket
Cloudflare (CDN)Token de API para la zona con Zone → Cache Purge → Purge; Zone → Zone → Read opcional
Google Cloud StorageClave HMAC para una cuenta de servicio con roles/storage.objectUser en el bucket
Alibaba Cloud OSSUsuario RAM con oss:PutObject, oss:GetObject, oss:DeleteObject en el bucket
Tencent Cloud COSSubusuario CAM con cos:PutObject, cos:GetObject, cos:DeleteObject en el bucket (el nombre del bucket incluye el APPID)
DigitalOcean SpacesClave de acceso de Spaces limitada al bucket con lectura, escritura y eliminación
MinIO / personalizado compatible con S3Put, get y delete en <bucket>/*; el endpoint debe ser HTTPS público

La comprobación de la conexión

Cada vez que guardas (y cuando seleccionas Repetir comprobación), smallPict comprueba toda la conexión antes de usarla:

  1. Almacenamiento: escribe un pequeño archivo de prueba en .smallpict-probe/ de tu bucket, lo vuelve a leer y lo elimina.
  2. Cloudflare: envía a tu zona una purga de prueba de una sola URL.
  3. CloudFront: crea una invalidación de prueba para una ruta /.smallpict-probe/.... Cuenta para tus rutas de invalidación de CloudFront del mes.

Si falla cualquier paso, no se cambia nada. El panel muestra el motivo junto al campo afectado, por ejemplo el nombre del bucket o el token de API. La comprobación de la conexión está limitada a 5 intentos por minuto.


Acceso de tu CDN al bucket

  • optimized/ debe poder leerlo tu CDN: o bien lectura pública en ese prefijo, o bien acceso de origen de la CDN a un bucket privado (Origin access control de CloudFront o un dominio personalizado de R2).
  • originals/ puede seguir siendo privado. Tu CDN nunca lo necesita.
  • CORS solo hace falta si los navegadores obtienen las imágenes entre orígenes desde JavaScript (por ejemplo con fetch() o un canvas). Las etiquetas <img> normales no lo necesitan. Si lo necesitas, permite GET y HEAD desde el origen de tu sitio.

Estructura de objetos y URL

QuéClave en tu bucketURL
Originaloriginals/<job_id>/<file>No se sirve
Archivo optimizadooptimized/<job_id>.<ext><cdn_domain>/optimized/<job_id>.<ext>

El dominio de la CDN puede incluir un prefijo de ruta, por ejemplo https://example.com/images; la URL queda entonces https://example.com/images/optimized/<job_id>.<ext>.


Cabeceras de caché

Los archivos optimizados se escriben con Cache-Control: public, max-age=31536000, immutable. Cada trabajo recibe una clave única, así que un resultado nuevo siempre tiene una URL nueva y rara vez hace falta purgar. Evita que las reglas de caché de tu CDN sustituyan esta cabecera por una duración más corta.


Purga de caché

  • Las solicitudes de purga hechas a través de la API (POST /v1/purge) van a tu CDN, agrupadas en lotes.
  • En Cloudflare, los archivos se purgan por URL. «Purge all» purga solo tu host de entrega y tu prefijo de ruta, no toda tu zona.
  • En CloudFront, los archivos se purgan con invalidaciones. «Purge all» crea una invalidación /*. AWS factura a tu cuenta las rutas de invalidación que superen la asignación mensual gratuita de CloudFront.

Cambiar de modo

Cambiar de modo no mueve los archivos existentes. Los archivos ya entregados conservan sus URL actuales; solo los trabajos nuevos usan el nuevo modo.

  • Gestionado → BYO: los trabajos nuevos van a tu bucket y los sirve tu CDN. Los archivos que ya están en cdn.smallpict.app se quedan allí.
  • BYO → gestionado: los trabajos nuevos vuelven a usar el almacenamiento y la CDN gestionados. Tus ajustes y claves de BYO siguen guardados pero sin usar, para que puedas volver sin introducirlos de nuevo, hasta que selecciones Desconectar.
  • Desconectar: elimina las claves y los ajustes de BYO guardados y te devuelve al modo gestionado. Los archivos de tu bucket no se tocan.

Cuando algo falla

  • Si smallPict no puede escribir en tu bucket, lo reintenta y después marca el trabajo como fallido con un motivo que puedes leer en la respuesta de la API.
  • El panel muestra el último error y cuándo ocurrió, con un botón Repetir comprobación.
  • Recibes un correo por incidente, no uno por cada trabajo fallido.
  • smallPict nunca recurre al almacenamiento gestionado. Tus archivos nunca se guardan en un lugar que no hayas elegido.

Seguridad

  • Las claves se guardan en un almacén de secretos cifrado. Nunca se vuelven a mostrar, la API nunca las devuelve y nunca se escriben en los registros.
  • Para rotar una clave, introduce la nueva y guarda; la comprobación de la conexión se ejecuta con la clave nueva. Deja vacío un campo de clave para conservar la clave guardada.
  • Los endpoints de almacenamiento y de CDN deben usar HTTPS. Se rechazan los endpoints que resuelven a direcciones privadas, de loopback, link-local u otras direcciones internas.
  • Usa claves separadas y restringidas para smallPict, y revócalas en la consola de tu proveedor si dejas de usar BYO.