Guía de despliegue

Alojar Supabase en un VPS en 2026

Desplegar en un VPS Cloud →

Tutorial

Alojar Supabase en un VPS en 2026

Bases de datos14 min de lectura22 pasos

Supabase es la alternativa de código abierto a Firebase construida sobre PostgreSQL: base de datos, autenticación, almacenamiento, edge functions y API autogenerada. Desde agosto de 2026, la stack self-hosted ha migrado de Kong a **Envoy Gateway** como proxy interno de la API. Autoalojarlo en un VPS le da un backend completo, sin tope de proyectos ni facturación por uso, con sus datos en su propio Postgres.

Contenido· Por qué autoalojar Supabase en un VPS1/16
  1. 01Por qué autoalojar Supabase en un VPS
  2. 02Los beneficios concretos de un Supabase autoalojado
  3. 03Requisitos de hardware y software
  4. 04Desplegar Supabase self-hosted con Docker
  5. 05Supabase vs Appwrite: ¿qué BaaS autoalojado elegir?
  6. 06Despliegue a partir de la stack oficial de Supabase, no de un compose casero
  7. 07Haz copias de seguridad automáticas de tu instancia
  8. 08Aligerar la pila: el servicio analytics
  9. 09Migración Kong→Envoy: qué cambia y a quién le rompe
  10. 10Pasar a Envoy sin romper tu pasarela
  11. 11Kong y Envoy, punto por punto
  12. 12CVE-2026-31813: fallo OIDC en GoTrue — actualice
  13. 13Actualizar GoTrue para corregir CVE-2026-31813
  14. 14Desactivar temporalmente el Social Auth si no puede actualizar de inmediato
  15. 15Migración PostgreSQL 15 → 17: fije la imagen antes de actualizar
  16. 16Migrar de PostgreSQL 15 a 17 sin perder sus datos

Por qué autoalojar Supabase en un VPS

Supabase no es una caja negra: es un conjunto de servicios de código abierto (PostgreSQL, GoTrue para la autenticación, PostgREST para la API, Realtime, Storage, Kong como gateway) orquestados juntos. La versión cloud factura por proyecto y por usuario activo, y pausa los proyectos gratuitos inactivos. Al autoalojarlo en un VPS, obtiene un backend-as-a-service completo sin esos límites, con acceso directo a su PostgreSQL para las migraciones, las extensiones (pgvector, PostGIS) y el tuning. Es ideal para una agencia que aloja varias aplicaciones de clientes, un SaaS que arranca y quiere controlar sus costes, o cualquier proyecto que exija soberanía de los datos. Usted mismo gestiona las actualizaciones y la copia de seguridad, a cambio de una libertad total.

Los beneficios concretos de un Supabase autoalojado

  • Backend completo: base de datos Postgres, Auth, Storage, Realtime y API REST/GraphQL en una sola stack.
  • Acceso directo al PostgreSQL subyacente: migraciones SQL, extensiones y políticas RLS sin límite.
  • Sin pausas ni facturación por usuario activo mensual.
  • Studio incluido: interfaz de administración web para gestionar tablas, auth y buckets.
  • Extensiones de IA mediante pgvector para el RAG y la búsqueda semántica, activadas libremente.
  • Multiproyecto en un mismo VPS: práctico para una agencia o un estudio de desarrollo.

Requisitos de hardware y software

Supabase self-hosted levanta una decena de contenedores (Postgres, Kong, GoTrue, PostgREST, Realtime, Storage, Studio, Meta, Imgproxy...), por lo que es una stack más exigente que una simple base de datos. Cuente con un mínimo de 2 vCPU y 4 GB de RAM para un entorno de pruebas, y más bien 4 vCPU con 8 GB de RAM y 80 GB de SSD para producción. En el plano del software: Ubuntu 22.04/24.04 LTS, Docker y Docker Compose v2, un nombre de dominio que apunte al VPS (por ejemplo api.monsaas.com) para exponer la gateway en HTTPS, y un reverse proxy como Caddy, Traefik o Nginx para gestionar el SSL. Prevea también generar secretos robustos (JWT_SECRET, claves anon y service_role).

Desplegar Supabase self-hosted con Docker

  1. Clonar el repositorio oficial y preparar el entorno

    Recupere la carpeta docker del repositorio de Supabase, copie .env.example a .env y genere después secretos únicos: POSTGRES_PASSWORD, JWT_SECRET y las claves ANON_KEY / SERVICE_ROLE_KEY derivadas del JWT. No despliegue nunca con los valores de ejemplo.

  2. Configurar las URLs y la contraseña de Studio

    En .env, defina SITE_URL, API_EXTERNAL_URL y SUPABASE_PUBLIC_URL con su dominio, y proteja Supabase Studio con DASHBOARD_USERNAME y DASHBOARD_PASSWORD: el Studio da un acceso de administrador total a su proyecto.

  3. Lanzar la stack

    Arranque con docker compose up -d y siga después el arranque de los servicios mediante docker compose ps. La primera inicialización de Postgres y la aplicación de las migraciones internas tardan de uno a dos minutos; compruebe que no haya errores en docker compose logs.

  4. Colocar un reverse proxy con SSL

    Ponga Caddy o Traefik delante de Kong (el puerto 8000 de la gateway) para exponer su API en HTTPS. Caddy obtiene y renueva automáticamente los certificados Let's Encrypt: basta con un simple bloque monsaas.com { reverse_proxy localhost:8000 }. No exponga nunca Postgres (5432) públicamente.

  5. Activar las políticas RLS

    Conéctese al Studio, cree sus tablas, active después Row Level Security en cada una y defina sus policies. Sin RLS, su clave anon expone todos sus datos: es el ajuste que hay que hacer antes de exponer nada.

  6. Hacer copia de seguridad de Postgres y del Storage

    Programe un pg_dump diario de la base de datos y archive el volumen de Storage (buckets de archivos) hacia un almacenamiento externo. Pruebe la restauración completa en un VPS de staging antes de contar con ella en producción.

Supabase vs Appwrite: ¿qué BaaS autoalojado elegir?

Desplace la tabla

CriterioSupabaseAppwrite
Base de datosPostgreSQL nativo, SQL completoMariaDB internamente, API de documentos/colecciones
Modelo de datosRelacional, RLS de PostgresDocumentos y colecciones, permisos por regla
API autogeneradaREST (PostgREST) + GraphQLREST, GraphQL y múltiples SDK
AutenticaciónGoTrue, OAuth, magic linksAuth integrada, OAuth, equipos, JWT
Huella de recursosMás pesada (~10 contenedores)Moderada, stack más compacta
Búsqueda vectorial / IANativa mediante pgvectorNo nativa, hay que externalizarla
Ideal paraApps relacionales, RAG, SQL avanzadoApps móviles/web orientadas a documentos
Curva de aprendizajeCómoda si conoce SQLRápida para desarrolladores front/móvil

Actualice Supabase con prudencia: como las imágenes están versionadas en el docker-compose.yml, haga siempre un pg_dump completo y un snapshot del VPS antes de un docker compose pull && docker compose up -d. Algunas subidas de versión afectan al esquema interno de los servicios. Para producción, aísle Postgres en un volumen dedicado de alto IOPS y active pgvector desde el principio si prevé búsqueda semántica: añadirlo más tarde impone una migración de esquema.

Despliegue a partir de la stack oficial de Supabase, no de un compose casero

Es tentador escribir un docker-compose mínimo con solo los pocos servicios que necesita. En la práctica, eso se rompe: la imagen supabase/postgres ejecuta su propio script de migración (migrate.sh) que aprovisiona los roles de base (supabase_admin, authenticator, supabase_auth_admin...) y la totalidad del esquema de autenticación, y espera la presencia de los archivos SQL de inicialización de Supabase montados como archivos, con expansión de las variables en tiempo de ejecución. Un compose inline autónomo no puede reproducir eso (Docker Compose interpola las variables dentro de las configuraciones inline, dejando el esquema de autenticación migrado a medias y GoTrue fallando con 'must be owner of function auth.uid()'). El enfoque robusto — el que utiliza ServOrbit — consiste en desplegar los archivos Docker oficiales de Supabase, fijados en una versión concreta, y dejar que su migrate.sh haga el arranque exactamente como lo prevé el upstream.

Haz copias de seguridad automáticas de tu instancia

El despliegue Docker de Supabase no hace ninguna copia de seguridad por sí solo: es la carencia que más señalan quienes lo autoalojan. Se complementan dos mecanismos. El primero, pg_dump, produce una copia lógica completa: lánzalo por cron desde el anfitrión, hacia un volumen distinto del de la base, y conserva varias generaciones. El segundo, el archivado WAL, registra cada transacción y permite volver a un instante preciso en lugar de al último volcado. El primero basta para la mayoría de los proyectos; el segundo se hace necesario en cuanto perder un día de escrituras resulta inaceptable. En ambos casos, una copia de seguridad solo vale lo que prueba una restauración: levanta una instancia en blanco y reproduce tu volcado en ella antes de necesitarla de verdad.

Aligerar la pila: el servicio analytics

La composición Docker oficial incluye Logflare, el servicio de analítica interna de Supabase, bajo el nombre analytics. No es imprescindible ni para la API, ni para la autenticación, ni para el almacenamiento: es una herramienta de observabilidad. En un VPS con recursos ajustados, es habitual verlo en estado unhealthy sin que el resto de la pila se resienta, y muchos autoalojadores acaban comentándolo en su docker-compose.yml. Mida primero lo que consume en su caso con docker stats antes de decidir: si su monitorización ya pasa por una herramienta externa no pierde nada; si contaba con sus registros, desactívelo solo cuando tenga un sustituto conectado.

Migración Kong→Envoy: qué cambia y a quién le rompe

La semana del 9 de agosto de 2026, Supabase convirtió a Envoy en la gateway de API por defecto de las instalaciones self-hosted; Kong pasa a ser una capa opcional. Envoy ya estaba disponible en varias versiones anteriores a través de docker-compose.envoy.yml — lo que cambia es el predeterminado.

En docker-compose.yml, el servicio ahora se llama api-gw y el contenedor supabase-envoy, pero el alias de red kong se conserva: los servicios que llaman a la gateway por ese nombre siguen funcionando. El puerto HTTP sigue siendo 8000, configurable mediante API_GW_HTTP_PORT, así que su reverse proxy Caddy o Nginx no necesita ningún cambio.

⚠️ Supabase califica este cambio de disruptivo para UNA PARTE de los autoalojadores, y hay que saber si usted es uno de ellos. Tres casos: dependía del puerto HTTPS 8443 integrado en Kong — ya no se suministra por defecto, la terminación TLS pasa por docker-compose.caddy.yml o docker-compose.nginx.yml; tenía un volumes/api/kong.yml personalizado — las rutas y plugins deben portarse a la configuración de Envoy, que vive en volumes/api/envoy/; sus scripts referencian la gateway por nombre de servicio. En los tres casos también puede quedarse en Kong: sh run.sh config add kong.

Pasar a Envoy sin romper tu pasarela

  1. Saber qué está ejecutando

    Ejecute docker compose ps. Un contenedor supabase-kong significa que sigue en Kong; supabase-envoy indica que el cambio ya se hizo. Compruebe también si volumes/api/kong.yml difiere del del repositorio — ese archivo decide si la migración le cuesta trabajo.

  2. Hacer copia de seguridad antes de tocar el compose

    Haga un pg_dump completo y, si su proveedor lo permite, un snapshot del VPS. Cambiar de gateway no toca el esquema de PostgreSQL, pero cambia la ruta de entrada de todas sus peticiones: una vuelta atrás rápida vale más que un diagnóstico en caliente.

  3. Decidir: portar o quedarse

    Si su kong.yml es el del repositorio, no hay nada que portar. Si contiene rutas o plugins propios, dos vías: traducirlos a configuración Envoy en volumes/api/envoy/, o quedarse en Kong con sh run.sh config add kong mientras lo hace. Quedarse es una decisión legítima, no un fracaso.

  4. Obtener el nuevo compose y reiniciar

    Descargue la última versión de la carpeta docker del repositorio oficial de Supabase, luego docker compose down && docker compose up -d. Compruebe que api-gw alcanza el estado healthy y que la API responde en el puerto 8000.

  5. Restablecer TLS si usaba el 8443 de Kong

    El puerto HTTPS integrado ya no se suministra. Añada terminación TLS con docker-compose.caddy.yml o docker-compose.nginx.yml, o deje que su reverse proxy existente lo gestione frente al puerto 8000. Este es el punto que rompe con más frecuencia, y solo se aprecia en la primera llamada HTTPS directa.

  6. Verificar el almacenamiento y las URLs firmadas

    Pruebe una descarga desde un bucket privado a través de una URL prefirmada. Si obtiene un 403 tras el cambio, mire primero la reescritura del encabezado Host y el valor de la URL pública de su servicio de almacenamiento: ahí es donde difieren las dos gateways.

Kong y Envoy, punto por punto

Desplace la tabla

AspectoKong (antes de agosto 2026)Envoy (predeterminado desde)
Servicio en `docker-compose.yml``kong``api-gw` — alias de red `kong` conservado
Contenedor`supabase-kong``supabase-envoy`
Puerto HTTP80008000 — vía `API_GW_HTTP_PORT`
Puerto HTTPS integrado8443**eliminado** — TLS vía `docker-compose.caddy.yml` / `.nginx.yml`
Configuración`volumes/api/kong.yml``volumes/api/envoy/` (YAML versionado)
Volver a Kong—`sh run.sh config add kong`

CVE-2026-31813: fallo OIDC en GoTrue — actualice

En 2026 se divulgó una vulnerabilidad en GoTrue (el servicio de autenticación de Supabase) bajo la referencia CVE-2026-31813. El fallo está en la validación del claim iss durante la autenticación OIDC: un token JWT firmado por un proveedor de identidad externo (Apple o Azure) pero con un iss distinto del configurado en GoTrue se aceptaba en ciertas condiciones de configuración.

En la práctica, un atacante que controle un proveedor OIDC registrado en la aplicación cliente puede emitir tokens válidos para usuarios arbitrarios de su instancia de Supabase. El alcance real depende de la configuración: solo están afectadas las instancias con al menos un proveedor OAuth externo activado (Social Auth). Las instancias que utilizan únicamente la autenticación por correo/contraseña o los magic links no están expuestas.

La corrección está incluida en Supabase Auth (GoTrue) 2.185.0. Para comprobar su versión: docker compose exec auth gotrue version. Si su versión de gotrue es anterior a 2.185.0, actualice de inmediato.

Actualizar GoTrue para corregir CVE-2026-31813

  1. Identificar la versión en curso

    Desde el directorio de su stack Supabase: docker compose exec auth gotrue version. Si la salida indica una versión < 2.185.0, su instancia está expuesta al CVE-2026-31813. Anote también la versión global de la stack: grep 'SUPABASE_VERSION' .env (si la ha fijado) o docker compose images | grep supabase.

  2. Hacer copia de seguridad antes de la actualización

    Antes de cualquier actualización, haga una copia de seguridad de la base de datos: docker compose exec db pg_dumpall -U postgres > /tmp/supabase-backup-$(date +%F).sql. La actualización de GoTrue no implica migración del esquema de PostgreSQL, pero una copia de seguridad previa sigue siendo la regla antes de cualquier cambio de versión en producción.

  3. Actualizar Supabase Auth a 2.185.0 o posterior

    En su docker-compose.yml, actualice la etiqueta de la imagen supabase/gotrue a v2.185.0 o más reciente, o si sigue la stack global, descargue la última versión compatible: docker compose pull && docker compose up -d auth. Actualizar solo GoTrue no obliga a reiniciar los demás servicios. Compruebe con docker compose exec auth gotrue version que la nueva versión está activa.

  4. Comprobar la autenticación OIDC

    Tras la actualización, pruebe un flujo de autenticación completo con cada proveedor OIDC configurado: inicio de sesión, cierre de sesión, reconexión. Compruebe en los logs de GoTrue (docker compose logs auth) que no aparece ningún mensaje de error relativo a la validación iss en condiciones normales de uso.

Desactivar temporalmente el Social Auth si no puede actualizar de inmediato

Si una actualización inmediata no es posible (se requiere una ventana de mantenimiento), puede reducir la superficie de exposición desactivando temporalmente los proveedores OAuth externos en el Studio de Supabase: Authentication → Providers, y desactive después cada proveedor Social. La autenticación por correo/contraseña sigue funcionando. Esta solución alternativa es temporal: no corrige el fallo, solo reduce la superficie de ataque mientras prepara la actualización.

Migración PostgreSQL 15 → 17: fije la imagen antes de actualizar

En junio de 2026, Supabase cambió silenciosamente la imagen de PostgreSQL por defecto de la versión 15 a la versión 17 en su docker-compose.yml oficial (changelog anunciado el 2026-05-18, efectivo desde el 2026-06-17). Este cambio es silencioso y destructivo si no lo conoce: PostgreSQL 17 no puede leer un volumen de datos creado por PostgreSQL 15 y se niega a arrancar. Un simple docker compose pull sin fijar la imagen supabase/postgres dejará su instancia inservible — la discusión [#46080](https://github.com/orgs/supabase/discussions/46080) abierta en mayo de 2026 acumuló cientos de informes.

Segunda trampa: las extensiones timescaledb, plv8, plcoffee y plls han sido eliminadas de la imagen oficial de PG 17. Si su base de datos las usa, la migración requiere reinstalarlas desde repositorios comunitarios, o renunciar a la actualización. Compruébelo primero: docker compose exec db psql -U postgres -c "\dx" lista las extensiones activas.

Migrar de PostgreSQL 15 a 17 sin perder sus datos

  1. Fijar la imagen PG 15 antes de cualquier `docker compose pull`

    Abra su docker-compose.yml y encuentre la línea de imagen del servicio db. Reemplace supabase/postgres:latest (o cualquier etiqueta flotante) por una etiqueta de versión fija de PG 15, por ejemplo supabase/postgres:15.8.1.060. Compruebe la última etiqueta 15.x disponible en Docker Hub de Supabase. Mientras esta etiqueta esté fija, un docker compose pull no tocará su base de datos.

  2. Volcado completo de la base de datos PostgreSQL 15

    Desde el anfitrión, exporte todos sus datos con pg_dumpall: docker compose exec db pg_dumpall -U postgres > supabase-pg15-dump-$(date +%F).sql. Este archivo contiene roles, esquemas y datos. Verifique que no está vacío y que termina con -- PostgreSQL database cluster dump complete. Consérvelo en un volumen separado del VPS y en almacenamiento externo.

  3. Detener la stack y eliminar el volumen de datos de PG 15

    Detenga todos los servicios: docker compose down. Identifique el volumen de la base de datos con docker volume ls | grep supabase. Antes de eliminarlo, asegúrese de que su volcado está completo y es legible. Luego elimine únicamente el volumen de datos de Postgres: docker volume rm <nombre_volumen_postgres>. No elimine los volúmenes de Storage ni de otros servicios.

  4. Cambiar a la imagen de PostgreSQL 17 en docker-compose.yml

    Cambie la línea de imagen del servicio db para apuntar a PostgreSQL 17, por ejemplo supabase/postgres:17.4.1.060 (compruebe la última etiqueta 17.x disponible en Docker Hub). Revise también las variables de entorno y el health check del servicio — la imagen PG 17 puede tener rutas o parámetros ligeramente distintos a los de PG 15.

  5. Arrancar el contenedor PG 17 vacío y restaurar el volcado

    Arranque solo el servicio de base de datos: docker compose up -d db. Espere a que alcance el estado healthy (docker compose ps). Luego restaure el export: docker compose exec -T db psql -U postgres -f /dev/stdin < supabase-pg15-dump-$(date +%F).sql. La restauración tarda unos minutos según el volumen de datos; los avisos sobre roles existentes son normales.

  6. Verificar las extensiones y reiniciar la stack completa

    Antes de relanzar todos los servicios, verifique las extensiones: docker compose exec db psql -U postgres -c "\dx". Si timescaledb, plv8, plcoffee o plls estaban presentes en PG 15, ya no existen en la imagen oficial de PG 17 — instálelas desde sus repositorios comunitarios respectivos, o elimine las referencias en su esquema. Una vez listo, arranque la stack completa: docker compose up -d. Compruebe cada servicio con docker compose ps y pruebe una llamada API completa antes de dar la migración por terminada.

Autoaloje su backend Supabase

El VPS Cloud ServOrbit, con plantilla Docker preconfigurada y RAM generosa, aloja toda la stack de Supabase: Postgres, Auth, Storage y API, en HTTPS.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva