Saltar al contenido

Backups

Supabase storage backup: tu copia de la base no tiene archivos

Un Supabase storage backup es una tarea aparte. Las copias de la base guardan la lista de tus archivos y ninguno de ellos, así que cada upload queda roto.

Vlad Tkachenko12 min de lectura
Una base de datos con tres filas, cada una unida por una línea fina a una imagen colocada en una bandeja aparte al lado.

En resumen

  • Un Supabase storage backup es una tarea distinta de la copia de la base de datos. Cada copia que Supabase toma, en cualquier plan, contiene la fila que describe cada archivo subido y ninguno de los archivos en sí.
  • Restaura solo la base de datos y tendrás una app que funciona, en la que cada avatar, factura y upload abre un error, porque el archivo al que apunta nunca estuvo en la copia.
  • El endpoint compatible con S3 es la forma de sacar los archivos. El camino de vuelta pasa por el propio Storage, que escribe la fila correspondiente a medida que llega cada archivo, de modo que la lista y los archivos no pueden discrepar.

Configuraste copias de seguridad para tu app de Lovable o Bolt, o pagas el plan de Supabase que las toma, y la palabra hizo su trabajo: dejaste de preocuparte. Luego una restauración, o una mudanza a un proyecto nuevo, y la app vuelve con una imagen rota donde antes estaba cada foto de perfil. Cada tabla y cada fila están ahí. Las fotos no, y con ellas cada factura, cada exportación y cada adjunto que un usuario haya subido alguna vez.

Aquí está la parte que la palabra copia esconde: un Supabase storage backup es una tarea aparte, porque una copia de la base de datos contiene una fila por cada archivo que subieron tus usuarios y ninguno de los archivos. La fila está en tu base de datos. El archivo está en Storage, un servicio aparte, y ninguna copia de la base de datos, en ningún plan, entra ahí. Este artículo explica cómo tomar esa segunda copia y en qué orden vuelven las dos mitades, que es la parte que sale mal incluso cuando tienes las dos.

Ayuda pensar en una biblioteca. El catálogo es un cajón de fichas, una por cada libro, y cada una dice en qué estantería está el libro. Los libros están en las estanterías. Una copia de la base de datos copia el cajón.

¿Supabase hace copia de mis archivos de Storage?

No, en ningún plan. La documentación de copias de seguridad de Supabase dice que las copias no contienen los archivos guardados a través de la API de Storage, solo sus metadatos en la base de datos, y el point-in-time recovery es una función de la base de datos, así que la misma frase lo cubre.

Lo que cada copia sí contiene es la lista. Supabase mantiene en tu base de datos Postgres una tabla llamada storage.objects, con una fila por archivo en cada bucket: en qué bucket está, su ruta, quién lo subió, cuánto ocupa y cuándo llegó. Esa tabla se copia junto con todo lo demás, y precisamente por eso un proyecto restaurado parece tan completo. Cada ficha está en el cajón.

Los bytes de cada archivo están en otro sitio. Viven en el almacenamiento de objetos, un servicio aparte junto a tu base de datos, y una herramienta que copia una base de datos nunca lo lee. El plan gratuito no toma copias automáticas de ningún tipo, así que ahí la pregunta ni se plantea; a partir de Pro, la copia diaria tiene tus filas y ninguno de tus uploads.

Dónde guarda Supabase tus archivos

En dos sitios, y una copia de la base de datos llega a uno de ellos.

Cuando un usuario sube un avatar, tu app le entrega el archivo a Storage. Storage escribe los bytes en el almacenamiento de objetos bajo el nombre del bucket y la ruta, y en la misma operación escribe una fila en storage.objects que lo describe. Tu app guarda entonces esa ruta en una de sus propias tablas, digamos una fila de profiles con una columna avatar_url, y construye un enlace a partir de ella cada vez que hace falta la imagen.

Así que una imagen subida son tres cosas: los bytes en el almacenamiento de objetos, la fila en storage.objects que mantiene Storage, y la ruta en tu propia tabla. Una copia de la base de datos lleva las dos últimas. Restáurala y tu app tiene cada ruta y Storage tiene cada fila, y el enlace que construyen entre las dos apunta a un lugar donde no hay nada.

Por eso el fallo es tan silencioso. Cada fila concuerda con todas las demás, cada recuento cuadra, y cada comprobación que lee la base de datos pasa, incluido el paso de verificación de la mayoría de las herramientas de copia, porque los archivos nunca estuvieron dentro de lo que se comprobaba.

Cómo se ve una restauración con solo la mitad

Un proyecto que pasa todas las comprobaciones y muestra una imagen rota en cada sitio donde debería aparecer un archivo.

La restauración informa de un éxito porque hizo lo que se le pidió: las tablas han vuelto y los recuentos de filas cuadran. Abre el panel y Storage lista cada bucket y cada archivo que contiene, con tamaños y fechas, porque ese listado se lee de la tabla que la restauración devolvió. La propia guía de Supabase para restaurar una copia del panel en un proyecto nuevo describe exactamente este estado: los buckets y los metadatos de los archivos aparecen, y los objetos que hay detrás no.

La forma en que te enteras es de lo más corriente. La página del equipo muestra una fila de iconos de imagen rota donde estaban los avatares. Un cliente responde al correo de la factura del mes pasado para decir que el enlace abre un error. Alguien hace clic en un archivo en el explorador de Storage y la descarga falla. La ficha dice estantería cuatro, tercero por la izquierda, y la estantería cuatro está vacía.

La restauración devolvió cada fila que describe un archivo. Los archivos que esas filas describen nunca estuvieron en la copia.

Nada te avisa antes de ese momento, porque cada aviso que tienes está conectado a la base de datos. Cómo restaurar una copia de Supabase repasa las cinco formas en que una restauración vuelve rota, y los archivos son la fila de esa tabla que no tiene arreglo, salvo que hayas hecho una copia de ellos.

Ya que tienes abierta la página de Storage, conviene saber qué le muestra a un desconocido. Nuestro escaneo gratuito lee tu app en vivo desde fuera y le pide a cada bucket su lista de archivos usando nada más que la clave que ya está en el código de tu app. En agosto de 2026 obtuvo una lista de 792 de las 27.269 apps que pudo comprobar, una cifra de nuestra propia investigación. Lee nombres y nunca descarga un archivo, tarda unos 20 segundos y no necesita cuenta: escanea tu app.

¿Cómo hago copia de un bucket de Supabase Storage?

A través del endpoint compatible con S3, con un solo comando que copia un bucket entero a una carpeta que tú guardas.

Supabase Storage habla el protocolo S3, lo que significa que las herramientas corrientes construidas para el almacenamiento de Amazon funcionan contra el tuyo. Este es el único paso de este artículo que ocurre en una línea de comandos, y merece la pena hacerlo una vez a mano para que sepas de qué está hecha la copia.

  1. En tu panel de Supabase, abre los ajustes de Storage y activa el protocolo S3. Esa misma página muestra la URL del endpoint y la región de tu proyecto; cópialas de ahí y no de aquí.
  2. En esa página, crea un par de claves de acceso S3. El secreto se muestra una sola vez, así que guárdalo en un gestor de contraseñas antes de cerrar el diálogo.
  3. Instala la línea de comandos de AWS, dale las dos claves como perfil y ejecuta una sincronización por bucket:
aws s3 sync s3://avatars ./supabase-files/avatars \
  --endpoint-url https://<project-ref>.storage.supabase.co/storage/v1/s3 \
  --region <region>

Vuelve a ejecutarlo mañana y solo copiará lo que cambió. rclone hace el mismo trabajo si lo prefieres; en un bucket grande, la nota de resolución de problemas de Supabase dice que pases --s3-list-version 2, o el listado puede detenerse antes de tiempo.

Dos cosas sobre esa clave. La página de autenticación S3 de Supabase dice que una clave de acceso S3 tiene acceso completo a todos los buckets y se salta Row Level Security, así que su sitio es un servidor o tu propia máquina, y nunca tu app. Y puede escribir además de leer, porque Supabase no emite ninguna clave de solo lectura para Storage; quien la tenga puede borrar archivos con la misma facilidad con que los copia. Trátala como tratarías tu clave service_role.

Luego pon la carpeta en algún sitio fuera de tu cuenta de Supabase, por la misma razón por la que una copia de la base de datos debería vivir fuera: un proyecto suspendido o un acceso perdido se lleva consigo cada copia guardada dentro de esa cuenta.

¿Primero los archivos, o primero las filas?

Primero la base de datos, luego los archivos, y los archivos vuelven a través de Storage para que sea Storage quien escriba las filas.

Cada upload que pasa por Storage, desde tu app, desde el endpoint S3 o desde la CLI de Supabase, hace dos cosas en una sola operación: guarda los bytes y escribe la fila de storage.objects que los describe. El libro se coloca en la estantería y la ficha la escribe la misma mano. Devuelve los archivos por ese camino y las filas llegan con ellos, y las dos cosas no pueden discrepar.

La otra dirección no tiene ningún mecanismo así. Copiar de vuelta filas de storage.objects con una herramienta de base de datos escribe fichas y no coloca nada. Además complica el paso siguiente: por defecto Storage rechaza un upload a una ruta que ya tiene fila, con un error que dice que el recurso ya existe, y la guía de subidas de Supabase dice que se supera activando la sobrescritura. Así que cuando la restauración de la base de datos ya ha devuelto las filas, que es lo que la propia guía de migración de Supabase te hace hacer, la copia de archivos que viene después tiene que poder sobrescribir.

Un archivo que llega a través de Storage escribe su propia fila. Una fila que llega a través de la base de datos no trae ningún archivo consigo.

El orden, entonces:

  1. Restaura la base de datos, como describe ese artículo.
  2. Copia los archivos de vuelta a través de Storage, con aws s3 sync en el sentido contrario (primero la carpeta, después el bucket) o con supabase storage cp -r, y con la sobrescritura activada. Un bucket que ya no existe hay que crearlo antes, con el mismo nombre y el mismo ajuste de público.
  3. Abre un archivo, y después varios más.

La versión más limpia de esto se salta por completo la reproducción de storage.objects en el paso de la base de datos y deja que los uploads escriban cada fila desde cero, de modo que nunca haya que sobrescribir nada. Así lo hace nuestra propia restauración. Requiere filtrar la copia antes de reproducirla, lo cual es un paso para la herramienta que hace la restauración.

Cómo comprobar que tienes las dos cosas

Abriendo archivos, porque cada lista que puedes sacar se lee de la tabla.

El explorador de archivos del panel, una consulta sobre storage.objects y el recuento de filas de un informe de copia describen todos el cajón, y después de una restauración de solo la base de datos el cajón está perfecto. La única petición que toca la estantería es una petición del archivo en sí.

Así que después de una restauración, y después de la primera copia que tomes, abre archivos. Elige un puñado de cada bucket, incluidos los más antiguos, y ábrelos a través de la app como lo haría un usuario. Un archivo que se abre ha vuelto. Un archivo que da error nunca estuvo ahí, diga lo que diga la lista.

Qué hacer esta semana

Qué hacer

  • Abre Storage en tu panel de Supabase y anota cada bucket y, a grandes rasgos, qué contiene. Todo lo que un usuario subió vive ahí y en ninguna copia de la base de datos.
  • Activa el protocolo S3, crea una clave de acceso y ejecuta un aws s3 sync por bucket a una carpeta fuera de tu cuenta de Supabase. Guarda el secreto en un gestor de contraseñas; puede borrar con la misma facilidad con que copia.
  • Vuelve a ejecutar la sincronización con una periodicidad que vayas a cumplir, sea un recordatorio en el calendario o una tarea en un servidor.
  • Apunta el orden de restauración en algún sitio donde lo encuentres: primero la base de datos, luego los archivos a través de Storage con la sobrescritura activada.
  • Restaura una vez en un proyecto desechable y abre diez archivos, para que la primera vez que sepas si la copia funciona no sea durante una caída.

Dónde encaja Reeve Care

Care copia los archivos junto con la base de datos, en el orden que describe este artículo, y los devuelve de la misma forma.

La copia de la base de datos se relee y pasa antes de que se copien los archivos. A la vuelta, la base de datos va primero, y los archivos regresan a través de Storage.
  • Los archivos que subieron tus usuarios también se copian, en cuanto conectas los buckets de Storage de tu app de Supabase. Es una segunda clave, pedida por separado, porque la clave que Supabase emite para Storage puede escribir además de leer, y preferimos pedirla antes que mezclarla con la clave de la base de datos, que no puede.
  • La copia de archivos se ejecuta después de que la copia de la base de datos se haya releído y verificado, nunca al lado, de modo que un punto de restauración nunca reclama archivos que no copió. Una copia que se quedó sin tiempo se marca como parcial, con los recuentos reales.
  • Cada punto de restauración registra qué ruta contenía qué archivo. Una base de datos devuelta al martes recibe los archivos del martes, y un archivo que sigue en su sitio se deja en paz.
  • La restauración devuelve los archivos a través de Storage, de modo que cada fila la escribe el upload que lleva el archivo. Nada de lo que existe hoy se sobrescribe ni se borra, lo que significa que pulsar el botón en pleno pánico no puede destruir lo que intentabas salvar.
  • Restaurar es un botón, y toma una instantánea del estado actual antes de empezar, de modo que la propia restauración tiene un deshacer.

Care empieza en $49 al mes para una app. Es un precio de lista, y la página de precios a veces está por debajo de la cifra de aquí y nunca por encima.

Cómo se toma, se comprueba y se devuelve una copia, archivos incluidos, está dibujado paso a paso en la página de copias de seguridad de Supabase.

Antes de cerrar esta pestaña, abre Storage en tu panel y cuenta los buckets. Cada uno es un conjunto de archivos que ninguna copia tomada por Supabase va a contener jamás, y el comando de sincronización de arriba es todo lo que hace falta para cambiarlo. Si además un bucket resultó ser listable, lo que un desconocido saca de esa lista es lo siguiente que leer.

Preguntas frecuentes

¿Supabase hace copia de mis buckets de Storage?

No. Supabase lo dice en su propia página de copias de seguridad: las copias de la base de datos no contienen los archivos guardados a través de la API de Storage, solo las filas de la base de datos que los describen. Eso vale para las copias diarias de los planes de pago y para el point-in-time recovery. El plan gratuito no toma copias automáticas de ningún tipo, así que ahí la pregunta ni se plantea. Tus archivos necesitan una copia propia en cualquier plan.

¿El point-in-time recovery cubre Supabase Storage?

No. El point-in-time recovery rebobina la base de datos, y Storage es un servicio aparte del que la base de datos solo guarda rutas. Un proyecto rebobinado al martes apunta a lo que haya hoy en los buckets, y un archivo borrado el miércoles sigue borrado después de una recuperación que salió perfecta.

¿Cómo descargo todos los archivos de un bucket de Supabase?

A través del endpoint compatible con S3. Activa el protocolo S3 en los ajustes de Storage de tu panel, crea un par de claves de acceso y apunta la línea de comandos de AWS o rclone al endpoint y la región que aparecen en esa misma página. Un solo comando de sincronización copia un bucket entero a una carpeta que tú guardas. El panel descarga un archivo cada vez, lo que sirve para un logo y no lleva a nada con un bucket.

¿Qué es storage.objects?

Una tabla de tu base de datos Postgres con una fila por cada archivo de cada bucket: en qué bucket está, su ruta, quién lo subió, su tamaño y tipo, y cuándo llegó. Es el índice. Los bytes del archivo no están ahí, y por eso una copia de la base de datos puede listar cada archivo que tienes sin contener ninguno.

Si restauro mi base de datos, ¿vuelven mis archivos?

No. La restauración devuelve las filas de storage.objects, así que el panel lista cada archivo y tu app dibuja cada enlace, y cada uno abre un error porque el archivo que hay detrás nunca estuvo en la copia. Los archivos hay que devolverlos por separado, a través de Storage, desde una copia que hayas tomado de ellos.

Escrito por

Vlad Tkachenko

Fundador de Reeve

Me paso el día mirando apps creadas con Lovable, Bolt, v0, Cursor y Replit, y la corta lista de errores que aparecen en ellas una y otra vez.

Más sobre el autor

Sigue leyendo

Todos los artículos

¿No sabes cómo está tu propia app?

Haz un escaneo gratuito y obtén una nota clara de la A a la F en unos 20 segundos. Sin cuenta y sin tarjeta.

Analizar mi app gratis

Comprobación externa automatizada, no una auditoría completa. La ausencia de hallazgos no es garantía de seguridad.