Cómo integrar Supabase con Laravel para base de datos y storage

Última actualización: 5 de diciembre de 2025
  • Configurar Laravel para usar la base de datos Postgres de Supabase implica ajustar correctamente el driver, el esquema y las variables de entorno.
  • El driver específico de Supabase para Laravel resuelve de forma automática los problemas habituales con columnas UUID en consultas y joins.
  • El adaptador de Flysystem permite tratar Supabase Storage como un disco más de Laravel, integrando fácilmente la subida de archivos.
  • Usar claves de servicio privilegiadas y buckets bien configurados es clave para evitar errores de escritura y garantizar un flujo estable.

Supabase para Laravel

Si trabajas con Laravel y te dedicas a la programación backend y te apetece dar el salto a una base de datos PostgreSQL gestionada y moderna como Supabase, seguramente te habrás dado cuenta de que no basta con cambiar un par de variables en el .env. Hay detalles de conexión, esquemas, autenticación y almacenamiento de archivos que, si no los mimas, terminan provocando errores bastante crípticos.

Además, cuando quieres ir un paso más allá y usar Supabase como almacenamiento de ficheros integrado con el sistema de discos de Laravel (Storage), la cosa se complica un poco más: claves de servicio, buckets, endpoints, drivers personalizados de Flysystem, etc. La buena noticia es que se puede dejar todo perfectamente integrado, tanto la base de datos como el storage y el tratamiento de UUIDs, de forma bastante limpia.

Conectar Laravel con la base de datos de Supabase

Lo primero es tener un proyecto de Laravel funcionando y enlazarlo con la base de datos Postgres que nos ofrece Supabase. Para ello necesitas un entorno con PHP y Composer actualizados y crear un proyecto nuevo o usar uno existente. Desde consola bastaría con generar el proyecto con el comando típico de Laravel y, a partir de ahí, empezar a montar la conexión.

Una vez tienes el esqueleto del proyecto, lo habitual es instalar un sistema de autenticación sencillo. Laravel Breeze encaja muy bien porque incluye plantillas Blade y flujo básico de login y registro, lo que te permite validar rápidamente que tu conexión con la base de datos está bien configurada y que puedes crear usuarios sin problemas.

Para obtener los datos de conexión, entra en tu panel de Supabase y crea un nuevo proyecto de base de datos (puedes hacerlo directamente desde database.new, que redirige al asistente). Si todavía no tienes cuenta, verás primero la pantalla de alta; si ya la tienes, irás directamente a la configuración del proyecto y a la sección donde puedes consultar el string de conexión.

Dentro de la página del proyecto, en el apartado de conexión, encontrarás un botón tipo “Connect” o similar. Al pulsarlo, Supabase te muestra varios formatos de cadena de conexión (URI, parámetros sueltos, etc.). Copia la URI completa, pero recuerda que debes reemplazar la contraseña por la que realmente uses en la base de datos, ya que a menudo se muestra una por defecto o un placeholder.

Con esa información, toca ir al archivo .env de tu proyecto Laravel y actualizar las variables DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME y DB_PASSWORD, o bien configurar la variable DATABASE_URL si prefieres usar el formato de cadena completa. El objetivo es que todo apunte al cluster Postgres de Supabase y no a tu localhost.

Configurar el driver Postgres y el esquema para Supabase en Laravel

En Laravel, el archivo clave para la configuración de la base de datos es config/database.php. Aunque puedes utilizar directamente el driver pgsql que trae el framework, cuando trabajas con Supabase es habitual aplicar algunos ajustes adicionales, sobre todo en lo referente a esquemas y opciones específicas de Postgres.

Una configuración típica para Postgres en Laravel puede verse así, dentro del array connections, bajo la clave ‘pgsql’:

'pgsql' => ,

La clave aquí está en el parámetro search_path. Supabase, por defecto, utiliza el esquema public, que es el que se expone a través de sus APIs. Si quieres mantener tu aplicación Laravel separada de ese esquema y evitar conflictos de tablas o políticas, es muy recomendable cambiar el search_path a un esquema propio, por ejemplo laravel, como se ve en el ejemplo anterior.

De este modo, las migraciones y las tablas que genere tu proyecto se crearán en ese esquema alternativo y no en public. Esta separación facilita mucho gestionar reglas de seguridad, RLS y acceso desde el panel de Supabase sin pisar nada que no debas y manteniendo organizada la estructura de la base de datos.

  Crear funciones en MySQL: Una guía completa

Una vez ajustado el archivo de configuración, puedes lanzar las migraciones con los comandos habituales de Laravel. Eso creará las tablas de autenticación y cualquier otra tabla que tengas definida. Si todo está bien configurado, los comandos se ejecutarán contra el Postgres de Supabase sin que tengas que hacer nada más.

Con las migraciones completadas, arranca el servidor de desarrollo con artisan serve y prueba a registrar usuarios y a iniciar sesión. Si no aparecen errores de conexión ni de migración, significa que Laravel está dialogando correctamente con Supabase y puedes seguir construyendo tu lógica de negocio con normalidad.

Usar un driver específico de Supabase en Laravel

Aunque el driver pgsql estándar funciona, existe un paquete que añade un driver de base de datos supabase para Laravel, extendiendo el comportamiento de PostgreSQL con mejoras muy útiles, sobre todo en lo que respecta al tratamiento de columnas UUID y al modo en que se construyen las consultas.

Este paquete, distribuido como prahsys/laravel-supabase, se instala vía Composer y registra un driver adicional llamado supabase que puedes utilizar en tu archivo config/database.php. Internamente se basa en el driver de Postgres de Laravel, pero incorpora ajustes y gramáticas de consulta optimizados para el entorno concreto de Supabase.

Una vez instalado, podrías declarar algo como lo siguiente dentro de la sección connections:

'connections' => ,
    // otras conexiones...
],

La gracia de usar este driver es que sigues obteniendo toda la potencia del motor Postgres, pero además se gestionan automáticamente ciertos detalles delicados de Supabase, especialmente cuando trabajas con UUIDs como claves primarias o campos de relación. Esto evita tener que andar escribiendo casting manual en cada consulta complicada.

El paquete también está pensado para encajar bien con versiones modernas del framework y de PHP, ofreciendo compatibilidad oficial con Laravel 10.x, 11.x y 12.x y con PHP a partir de la versión 8.1, además de cualquier base de datos PostgreSQL estandar, incluyendo por supuesto Supabase.

Para asegurarte de que todo funciona correctamente, el paquete incluye un conjunto de pruebas automáticas. Puedes lanzar los tests con el comando composer test, que usará una base de datos SQLite en memoria para ir rápido, o preparar un .env.testing apuntando a tu Supabase y ejecutar composer test-supabase para verificar el comportamiento en un entorno real con Postgres remoto.

Gestión de UUIDs en Supabase y Laravel

Supabase tiene una particularidad con las columnas UUID: si intentas comparar un UUID directamente con una cadena de texto sin hacer cast, la consulta puede fallar o devolver resultados inesperados. En un Postgres “a pelo” podrías solventarlo con casts globales u operadores personalizados, pero en Supabase no se permiten esas personalizaciones globales.

Esto implica que una consulta directa del estilo:

SELECT *
FROM users
WHERE id = '123e4567-e89b-12d3-a456-426614174000';

No funcionará como esperarías. En cambio, si realizas el casting explícito:

SELECT *
FROM users
WHERE CAST(id AS TEXT) = '123e4567-e89b-12d3-a456-426614174000';

la consulta sí tiene éxito. El problema es que en Laravel, cuando escribes consultas con Eloquent o con el query builder, no te apetece ir metiendo CAST en cada where. Ahí es donde entra en juego el driver supabase del paquete mencionado, que se encarga de añadir esos casts por ti.

Con ese driver activo, puedes realizar consultas habituales como:

$user = User::find($uuidString);
$user = User::where('id', $uuidString)->first();
$users = User::whereIn('id', )->get();

Y no solo en consultas directas, también en joins. Por ejemplo, si quieres obtener posts y unirlos con la tabla users usando un campo UUID, podrías hacer algo así:

$posts = Post::join('users', 'posts.user_id', '=', 'users.id')
    ->where('users.email', 'test@example.com')
    ->get();

El driver se encarga de aplicar los casts necesarios a texto en las columnas UUID implicadas, de forma transparente. De esa manera, tu código sigue siendo idiomático de Laravel y no necesitas escribir SQL crudo ni trucos extraños en cada consulta compleja.

  Oracle Data Integrator: Estrategias para Optimizar tus Procesos de Integración

Si quieres un control más fino sobre qué columnas se consideran UUID, el paquete ofrece el trait CastsUuidColumns para tus modelos Eloquent. Basta con usarlo en la clase del modelo y definir un array protegidos de columnas adicionales:

use Prahsys\Supabase\Traits\CastsUuidColumns;

class Post extends Model
{
    use CastsUuidColumns;

    protected $uuidColumns = ;
}

Este trait hace tres cosas importantes: incluye la clave primaria como UUID por defecto, añade cualquier columna que declares en la propiedad $uuidColumns y comunica esa información al query builder para que sepa dónde aplicar los casts. Así, todo el acceso a datos que implique UUIDs se vuelve consistente y automatizado.

Para casos todavía más avanzados, puedes registrar un detector de columnas UUID personalizado. Usando la gramática PostgresGrammar del paquete, puedes indicar una función de callback que, en función del nombre de la columna o del contexto de la consulta, decida si debe tratarse como UUID. Por ejemplo:

use Prahsys\Supabase\Database\Query\Grammars\PostgresGrammar;

PostgresGrammar::detectUuidColumnsWith(function ($columnName, $query) {
    return str_contains($columnName, 'uuid_')
        || in_array($columnName, );
});

Con esta función establecida, el sistema puede considerar como UUID todas las columnas cuyo nombre tenga cierto patrón o esté dentro de una lista determinada, adaptándose a convenciones de nombres muy específicas de tu proyecto.

Integrar Supabase Storage como sistema de archivos en Laravel

Además de la base de datos, muchos proyectos necesitan guardar imágenes, documentos u otros ficheros subidos por los usuarios. Supabase incluye un servicio de almacenamiento basado en buckets que puedes aprovechar como disco de Laravel mediante Flysystem. Para ello, existe un adaptador específico que permite tratar Supabase Storage como un driver más dentro de config/filesystems.php.

El paquete en cuestión provee un adaptador de Flysystem que se integra con el sistema Storage del framework de forma transparente. Cumple con los requisitos mínimos de PHP >= 8.1, Laravel 10.x o 11.x y la extensión de PHP fileinfo (ext-fileinfo), que Laravel ya suele recomendar para tratar ficheros. La instalación se hace con Composer y, una vez incluido, solo queda definir el disco supabase en la configuración.

En el archivo config/filesystems.php, dentro del array disks, añadirías algo parecido a lo siguiente:

'supabase' => ,
    ],
    'signedUrlExpires' => 60 * 60 * 24,
],

El parámetro bucket suele ser simplemente el nombre del bucket de almacenamiento que hayas creado en el panel de Supabase (por ejemplo, myapp-file-uploads). El endpoint es la URL base del servicio de almacenamiento del proyecto, también visible en la sección correspondiente del panel, y suele derivarse de la URL del proyecto y la región.

La opción public indica si el contenido del bucket se tratará como público por defecto. Si es true, el adaptador generará URLs accesibles sin firma especial; si es false, entra en juego la opción defaultUrlGeneration, que puede forzar la generación de URLs firmadas (signed) con un tiempo de expiración dado por signedUrlExpires. Esta configuración te permite equilibrar seguridad y comodidad según el tipo de ficheros que manejes.

La URL general del disco se deja normalmente en null para que el adaptador la derive automáticamente a partir del endpoint. Solo deberías tocarla si estás utilizando un proxy o CDN intermedio y quieres que las rutas generadas apunten a ese dominio en lugar del dominio nativo de Supabase.

Resolver errores de subida y entender la clave de Supabase Storage

Un problema bastante habitual al intentar subir archivos a Supabase Storage desde Laravel es recibir mensajes del tipo “Unable to write file at location: uploads/…”. Esto suele indicar que, aunque el driver está configurado, Supabase está denegando la operación de escritura por falta de permisos adecuados o por una mala configuración de la clave.

En el disco supabase de config/filesystems.php, la configuración habla de usar una «clave privilegiada» en el campo key, avisando expresamente de que una clave de solo lectura no funcionará. Esto significa que necesitas usar una clave de servicio que tenga permisos de escritura sobre el bucket, no simplemente una API key pública pensada para el cliente ni una clave pensada para compatibilidad S3 sin permisos de modificación.

En el panel de Supabase, dentro de la sección de configuración de API y de almacenamiento, podrás encontrar tanto las claves anónimas como las service_role o equivalentes, que son las que tienen privilegios ampliados. Es esa clave de servicio, y no la pública, la que deberías colocar en la variable SUPABASE_SECRET_ACCESS_KEY que luego leerá el driver a través de env(‘SUPABASE_SECRET_ACCESS_KEY’).

  Los Mejores ejemplos de Bases de Datos para Desarrolladores y Administradores

Si has estado probando con la clave S3 de la configuración de almacenamiento o con las claves API genéricas del proyecto, es muy probable que esas credenciales no tengan permiso para escribir en el bucket concreto, lo que se traduce en el error de escritura. Cambiando el valor de key a una clave de servicio válida con permisos de escritura y confirmando que el bucket existe y está bien escrito, el problema suele resolverse.

Además de la clave, conviene revisar que el bucket definido en SUPABASE_STORAGE_BUCKET coincide exactamente con el creado en la interfaz de Supabase, respetando mayúsculas y minúsculas, y que el endpoint se corresponde con la URL correcta para esa instancia de almacenamiento. Un detalle como un carácter de más o un dominio incorrecto puede impedir que el adaptador pueda localizar el destino real de los archivos.

Flujo de trabajo con Laravel Breeze, Blade y Supabase Storage

Cuando ya tienes base de datos y almacenamiento configurados, el siguiente paso natural es integrarlo todo con tu interfaz Laravel Breeze y plantillas Blade. De esta forma, los usuarios pueden registrarse, autenticarse y subir archivos a Supabase sin salir del ecosistema Laravel.

Dentro de tus controladores, utilizarías la fachada Storage apuntando al disco supabase. Por ejemplo, para subir un archivo que llegue desde un formulario con un input file, podrías hacer algo como:

if ($request->hasFile('file')) {
    $path = $request->file('file')
        ->store('uploads', 'supabase');
}

Este código le indica a Laravel que use el disco supabase y que coloque el archivo dentro de la carpeta virtual uploads dentro del bucket configurado. Si la clave y el endpoint son correctos, el archivo se subirá al almacenamiento de Supabase y podrás recuperar su ruta o generar URLs públicas o firmadas usando los métodos habituales de Storage.

La ventaja de este enfoque es que tu aplicación mantiene una única interfaz para el almacenamiento, sin importar si está utilizando el disco local, Amazon S3, Supabase u otro servicio soportado. Cambiar de proveedor se reduce a ajustar config/filesystems.php y las variables de entorno, sin tocar la lógica de negocio.

Al combinar esto con Blade y Breeze, puedes ofrecer formularios de subida, listados de archivos y enlaces de descarga totalmente integrados en la experiencia de usuario de tu aplicación. Además, el hecho de que Supabase Storage se base en buckets y políticas te permite aprovechar sus controles de acceso y reglas de seguridad para definir qué puede ver o descargar cada usuario.

Todo este ecosistema de paquetes, drivers y configuraciones hace que Laravel pueda trabajar de forma muy cómoda con Supabase, tanto en la parte de datos relacionales con Postgres como en la de almacenamiento de ficheros y gestión de UUIDs. Ajustando bien las claves, los esquemas y los drivers, tienes una integración muy sólida que evita muchos de los errores típicos cuando se intenta conectar ambas plataformas de forma manual y sin estas capas de ayuda.

Conectar Laravel con Supabase para la base de datos y el almacenamiento, aprovechar el driver específico supabase para gestionar UUIDs sin dolores de cabeza y usar el adaptador de Flysystem para Storage permite construir aplicaciones modernas donde toda la infraestructura compleja queda encapsulada detrás de la API limpia de Laravel, desde las migraciones y autenticación hasta la subida de archivos a buckets seguros.

directiva blade hasstack en laravel
Artículo relacionado:
Directiva Blade hasStack en Laravel y control avanzado de stacks