Saltar al contenido
Infrastructure 2026-09-06 15 min de lectura

Cómo instalar Supabase en tu propio VPS

Supabase autoalojado te da PostgreSQL, autenticación, API REST automática, almacenamiento de archivos y suscripciones en tiempo real en tu propio VPS, con el mismo código que corre en la nube de Supabase. Lo que no te da son los backups automáticos ni el soporte. Esta guía instala el despliegue oficial con Docker y explica qué asumes al hacerlo.

Cómo instalar Supabase en tu propio VPS
#Supabase#PostgreSQL#backend#VPS#Docker#self-hosting
T
Equipo Terranode
Editorial

Qué instalas realmente

Supabase no es un programa: es un conjunto de servicios de código abierto coordinados alrededor de una base PostgreSQL. El despliegue con Docker levanta más de una docena de contenedores:

  • PostgreSQL: la base de datos. Todo lo demás gira a su alrededor.
  • Kong: la puerta de entrada. Recibe las peticiones en el puerto 8000 y las enruta.
  • GoTrue (auth): registro, inicio de sesión, enlaces mágicos y proveedores externos.
  • PostgREST: convierte tus tablas en una API REST automática.
  • Realtime: envía cambios de la base por WebSocket.
  • Storage: archivos, con una API compatible con S3.
  • Studio: el panel gráfico donde escribes SQL y gestionas tablas.
  • Analytics, Meta, Imgproxy y funciones Edge: servicios de apoyo.

Todos comparten el mismo VPS. Por eso los requisitos no son los de "una base de datos pequeña".

Requisitos y cuándo conviene

La documentación oficial pide un mínimo de 4 GB de RAM, 2 núcleos y 40 GB de disco SSD, y recomienda 8 GB o más, 4 núcleos y 80 GB. No son cifras infladas: con 2 GB los contenedores arrancan y luego el sistema empieza a matar procesos por falta de memoria.

EscenarioRAMvCPUDisco
Desarrollo y pruebas4 GB240 GB
Aplicación en producción pequeña8 GB480 GB
Producción con Storage intensivo16 GB8150 GB o más

Autoalojar tiene sentido si ya administras servidores, si tu política exige que los datos permanezcan bajo tu control, o si necesitas extensiones de PostgreSQL que la nube no habilita. No tiene sentido si el equipo no tiene a nadie que responda a las tres de la mañana cuando PostgreSQL no arranca: los 25 dólares mensuales del plan Pro de Supabase Cloud compran backups automáticos, monitoreo y soporte que aquí tendrás que construir tú.

Comprueba el servidor antes de empezar y activa swap si vas justo, como explica la guía de configurar swap en Ubuntu:

bash
free -h
nproc
df -h /
docker --version
docker compose version

Descargar y preparar el despliegue

El método oficial clona el repositorio en una rama fijada de autoalojamiento y copia solo la carpeta docker. Fijar la versión importa: seguir master significa despertar un día con un cambio incompatible.

bash
git clone --depth 1 --branch self-hosted/v0.8.0 https://github.com/supabase/supabase
mkdir supabase-project
cp -rf supabase/docker/. supabase-project
cd supabase-project
cp .env.example .env
printf 'ref=self-hosted/v0.8.0\n' > .supabase-version

Existe también un instalador rápido, curl -fsSL https://supabase.link/setup.sh | sh, que hace lo mismo de forma guiada en Linux. Si lo usas, revisa el script antes: canalizarlo a sh ejecuta código descargado con tus privilegios.

Cambiar todas las credenciales por defecto

El archivo .env.example trae claves públicas y conocidas: un despliegue que arranque con ellas queda comprometido desde el primer minuto. Este es el paso que más se salta y el que más incidentes causa.

Hay que cambiar, como mínimo:

VariableQué esRiesgo si la dejas por defecto
POSTGRES_PASSWORDContraseña de la baseAcceso total a los datos
JWT_SECRETFirma todos los tokensCualquiera emite tokens válidos
ANON_KEYClave pública del clienteAcceso con rol anon
SERVICE_ROLE_KEYClave del servidorIgnora la seguridad por fila
DASHBOARD_USERNAMEUsuario del panelAcceso al Studio
DASHBOARD_PASSWORDContraseña del panelAcceso al Studio
SECRET_KEY_BASECifrado de RealtimeSesiones manipulables
VAULT_ENC_KEYCifrado de secretosSecretos legibles

Genera valores fuertes:

bash
openssl rand -base64 48    # POSTGRES_PASSWORD
openssl rand -hex 32       # JWT_SECRET (mínimo 32 caracteres)
openssl rand -base64 64    # SECRET_KEY_BASE

ANON_KEY y SERVICE_ROLE_KEY no son cadenas aleatorias: son tokens JWT firmados con tu JWT_SECRET, con los roles anon y service_role respectivamente. La documentación de autoalojamiento incluye un generador para producirlos a partir de tu secreto. Si generas el secreto pero conservas las claves de ejemplo, nada funcionará: las firmas no coincidirán.

Define también la URL pública, porque el panel y los enlaces de correo la usan:

bash
SUPABASE_PUBLIC_URL=https://api.ejemplo.com
API_EXTERNAL_URL=https://api.ejemplo.com
SITE_URL=https://app.ejemplo.com

Levantar los servicios

bash
docker compose pull
docker compose up -d
docker compose ps

La primera arrancada tarda varios minutos porque descarga imágenes y ejecuta migraciones. Verifica que todos los contenedores estén healthy, no solo running:

bash
docker compose ps --format 'table {{.Name}}\t{{.Status}}'
docker compose logs --tail=50 db
docker compose logs --tail=50 auth

El Studio queda disponible en el puerto 8000, protegido con autenticación básica usando DASHBOARD_USERNAME y DASHBOARD_PASSWORD. Ese mismo puerto sirve la API a través de Kong.

Un error frecuente: si un contenedor reinicia en bucle, casi siempre es una variable de .env mal formada o una clave JWT que no coincide con el secreto. Léelo en los logs antes de tocar el volumen de datos.

Publicar con dominio propio y HTTPS

Nunca expongas el puerto 8000 directamente a internet: pon Nginx delante con TLS. Ajusta primero el mapeo de puertos para que Kong solo escuche en local, editando docker-compose.yml:

yaml
  kong:
    ports:
      - "127.0.0.1:8000:8000/tcp"

Y configura el proxy:

nginx
server {
    listen 443 ssl;
    server_name api.ejemplo.com;

    client_max_body_size 50M;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Las cabeceras Upgrade y Connection no son opcionales: sin ellas, Realtime no establece el WebSocket y las suscripciones en vivo quedan mudas sin dar error claro.

bash
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d api.ejemplo.com

client_max_body_size debe cubrir el archivo más grande que subas a Storage; el valor por defecto de Nginx (1 MB) rechaza cualquier imagen decente con un error 413.

Configurar el correo

El servicio de autenticación necesita SMTP propio para enviar confirmaciones, enlaces mágicos y recuperación de contraseña. El despliegue autoalojado no trae un remitente listo para producción; sin SMTP, los registros que requieran confirmación simplemente no llegan.

bash
SMTP_HOST=smtp.tuproveedor.com
SMTP_PORT=587
[email protected]
SMTP_PASS=CLAVE
SMTP_SENDER_NAME=Ejemplo
[email protected]

Usa un servicio de envío transaccional real y configura SPF, DKIM y DMARC en el dominio. Mandar correo de autenticación desde la IP de un VPS recién creado termina en la carpeta de spam; la guía sobre por qué el correo cae en spam explica los registros necesarios.

Migrar una aplicación desde Supabase Cloud

La migración tiene tres partes: base de datos, archivos de Storage y claves de la aplicación. El orden importa.

Exporta la base incluyendo roles y el esquema de autenticación, que es donde viven los usuarios:

bash
pg_dump "postgresql://postgres:[email protected]:5432/postgres" \
  --schema=public --schema=auth --schema=storage \
  --no-owner --no-privileges \
  -f volcado.sql

Restaura en el nuevo servidor:

bash
docker compose exec -T db psql -U postgres -d postgres < volcado.sql

Los archivos de Storage se descargan aparte con la CLI de Supabase o con cualquier cliente S3 apuntando al endpoint del proyecto. No asumas que el volcado SQL los incluye: la base guarda los metadatos, no el contenido de los archivos.

Por último, en tu aplicación cambia la URL del proyecto y la clave anónima:

javascript
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(
  'https://api.ejemplo.com',
  process.env.SUPABASE_ANON_KEY
)

Verifica después de migrar: inicia sesión con un usuario existente, sube un archivo, escucha un cambio en tiempo real y comprueba que las políticas de seguridad por fila siguen bloqueando lo que deben. Una migración que "termina sin errores" pero deja la seguridad por fila desactivada expone toda la base a la clave anónima, que está en el navegador de cualquiera.

Backups: aquí no hay red de seguridad

Supabase Cloud hace copias automáticas; tu VPS no hace nada hasta que tú lo programes. Es la diferencia operativa más importante entre los dos modelos.

bash
docker compose exec -T db pg_dumpall -U postgres | gzip > /var/backups/supabase-$(date +%F).sql.gz
tar czf /var/backups/storage-$(date +%F).tar.gz ./volumes/storage

Programa ambos con cron, envíalos fuera del servidor y prueba la restauración en otro VPS. La guía de backups en VPS cubre la rotación y el traslado remoto.

Añade monitoreo del espacio en disco. PostgreSQL con el disco lleno deja de aceptar escrituras, y los servicios de análisis de Supabase generan volumen de registros que sorprende:

bash
df -h /
docker system df
docker compose exec db psql -U postgres -c "SELECT pg_size_pretty(pg_database_size('postgres'));"

Autoalojado frente a la nube: tabla honesta

FunciónSupabase autoalojadoSupabase Cloud
Coste mensualEl del VPSGratis limitado o desde 25 USD
Backups automáticosLos programas túIncluidos, con punto en el tiempo
Réplicas de lecturaNo, salvo que las montesDisponibles en planes superiores
Ramas de base de datosNo
ActualizacionesManualesGestionadas
Acceso directo a PostgreSQLTotal, con superusuarioLimitado
Extensiones de PostgresLas que instalesLista aprobada
SoporteComunidadSegún plan
Dónde viven los datosTu servidorInfraestructura de Supabase

Autoalojar Supabase es viable y no es complicado: clonar la rama fijada, cambiar todas las claves del .env, poner Nginx con TLS delante de Kong y configurar SMTP. Lo que hay que aceptar es la parte que la nube resolvía en silencio: los backups los programas tú, las actualizaciones las decides tú, y si PostgreSQL no arranca un domingo, el soporte eres tú. Con 8 GB de RAM, un volcado diario probado y monitoreo de disco, un Supabase propio sostiene una aplicación en producción sin sobresaltos.

Terranode ofrece VPS KVM con NVMe en Ecuador desde $2,99 al mes; para Supabase el punto de partida realista es el plan de 8 GB de RAM y 80 GB de disco por $18,50, que cubre con holgura los requisitos recomendados para auto-alojar la plataforma completa.

¿Listo para llevar tu sitio al siguiente nivel?

Hosting con LiteSpeed, NVMe y soporte 24/7 desde $3/mes.

Ver planes de hosting

Preguntas frecuentes