Logotipo de Bitdoze

Autoaloja Convex en 2026: Guía de Docker Compose y Dokploy

Aprende a autoalojar Convex en tu VPS con Docker Compose o Dokploy. Cubre SQLite, PostgreSQL, MySQL, proxy inverso, almacenamiento S3 y métricas de Prometheus.

Dragos

41 min de lectura

Autoaloja Convex en 2026: Guía de Docker Compose y Dokploy

Si estás construyendo aplicaciones en tiempo real con bases de datos, probablemente te has topado con Convex. Es una plataforma backend-as-a-service que combina una base de datos en tiempo real con funciones serverless. El nivel gratuito de la nube te da 0,5 GB de almacenamiento de base de datos y 1M de llamadas a funciones al mes, lo que funciona para proyectos pequeños. Autoalojarlo elimina esos límites y te da control sobre tus datos y tu infraestructura.

La vía autoalojada ahora es oficial. Convex liberó el código del backend en noviembre de 2025, y el repositorio (convex/convex-backend) ronda las 12.700 estrellas en GitHub con lanzamientos precompiled-* casi semanales. El paquete npm convex está en la versión 1.47.0 con alrededor de 1,1M de descargas semanales. Los mantenedores afirman que el repositorio público se sincroniza con su código interno en cuestión de días, así que no estás ejecutando un fork abandonado.

En esta guía te muestro cómo autoalojar Convex usando Dokploy (más sencillo) o Docker Compose (más control). SQLite cubre instalaciones pequeñas; PostgreSQL o MySQL cubre producción. Un VPS de 5-10 $ es suficiente para un despliegue en solitario.

¿Qué es Convex?

Convex es una plataforma de backend que combina bases de datos, servidores de API y capas de caché en un solo sistema. Gestiona la sincronización de datos en tiempo real, funciones serverless y caché mediante una API de TypeScript. La versión autoalojada es el mismo código que ejecuta la nube, con licencia FSL 1.1, que se convierte en Apache 2.0 completa dos años después de cada lanzamiento.

Características clave de Convex

  • Base de datos en tiempo real: Sincronización automática de datos entre todos los clientes con consultas reactivas
  • TypeScript primero: Seguridad de tipos de extremo a extremo, del backend al frontend
  • Funciones serverless: Escribe consultas, mutaciones y acciones en TypeScript sin gestionar servidores
  • Programación integrada: Trabajos cron y funciones programadas sin servicios externos
  • Almacenamiento de archivos: Subida y almacenamiento de archivos integrados con distribución CDN
  • Búsqueda de texto completo: Capacidades de búsqueda nativas sin Elasticsearch
  • Autenticación: Sistema de autenticación flexible compatible con varios proveedores
  • Transacciones atómicas: Garantías ACID para la consistencia de los datos
  • Viaje en el tiempo: Consulta datos históricos y depura con consultas retrospectivas
  • Búsqueda vectorial: Base de datos vectorial integrada para aplicaciones de IA

¿Por qué autoalojar Convex?

Ventajas del autoalojamiento:

  • Eres dueño de los datos y controlas dónde residen
  • Sin límites de ancho de banda ni de ejecución de funciones
  • Personaliza la infraestructura y el escalado
  • Menores costes a gran escala
  • Ejecútalo on-premises o en redes privadas

Los planes en la nube en 2026 son así: Free y Starter incluyen 1M de llamadas a funciones, 0,5 GB de almacenamiento de base de datos y 1 GB de almacenamiento de archivos, y después facturan los excedentes con pago por uso. Professional empieza en 25 $ por desarrollador al mes y añade 25M de llamadas a funciones, 50 GB de almacenamiento de base de datos, copias de seguridad diarias y dominios personalizados. Business y Enterprise empiezan en 2.500 $ al mes para SAML/SSO, SLA y despliegues dedicados.

Cuándo compensa autoalojar

La nube de pago empieza en 25 $/desarrollador/mes. Un VPS de 5-10 $ cubre un despliegue autoalojado en solitario. Autoaloja cuando llegues a los límites del nivel gratuito, necesites controlar la residencia de los datos o quieras una sola máquina de producción en lugar de una factura por asiento. Para ver cifras de una prueba de carga real, consulta nuestras benchmarks de Convex autoalojado frente a la nube.

Cómo funciona Convex autoalojado

Un despliegue autoalojado son tres servicios de Convex más tu frontend. El backend escucha en el puerto 3210 para la API y la sincronización de consultas. Las acciones HTTP van en el puerto 3211. El dashboard escucha en el 6791 y se comunica con el backend a través de una URL accesible desde el navegador. Los datos viven en un archivo SQLite dentro de un volumen de Docker o en una instancia externa de Postgres/MySQL. La CLI npx convex sube funciones y lee datos usando una clave de administrador.

Tu app / navegadorconsultas, mutaciones, acciones HTTPnpx convex CLIdeploy + export con clave adminConvex backend :3210CONVEX_CLOUD_ORIGINAcciones HTTP :3211CONVEX_SITE_ORIGINDashboard :6791NEXT_PUBLIC_DEPLOYMENT_URLAlmacenamientoVolumen SQLite, oPostgres / MySQLel navegador llega al dashboarddatos
Tres servicios de Convex y un backend de almacenamiento. Las variables de entorno deciden bajo qué hostname se publica cada puerto.

Requisitos previos

Necesitarás:

  • Un VPS o servidor: 2 GB de RAM mínimo, 2 núcleos de CPU (4 GB de RAM recomendados para PostgreSQL)
  • Un nombre de dominio: Tres hostnames es la configuración limpia (api, actions, dashboard bajo tu dominio)
  • Docker instalado: Docker y el plugin docker compose (Dokploy incluye Docker)
  • Conocimientos básicos de línea de comandos: Para ejecutar comandos
  • openssl: Para generar INSTANCE_SECRET
  • Node.js 18+ y npx: La CLI de Convex lo necesita para despliegues, exportaciones y el trabajo con claves de administrador
  • Registros DNS A: Apunta los hostnames al VPS antes del paso del proxy inverso
Prueba Hetzner Cloud ahora Prueba el VPS de Hostinger

Los precios de los VPS subieron en todos los proveedores en 2026. Si estás reconsiderando una máquina alquilada, mira qué cambió y cuándo gana un mini PC.

Recomendaciones de hosting

Para desarrollo, un VPS básico con 2 GB de RAM funciona bien con SQLite. Para producción, usa 4 GB de RAM con PostgreSQL alojado en la misma región. Hetzner, DigitalOcean y AWS funcionan igual de bien. Decide tus nombres de dominio ahora: cambiar CONVEX_CLOUD_ORIGIN o CONVEX_SITE_ORIGIN más tarde implica reiniciar el backend y volver a desplegar tus funciones.

Opción 1: Desplegar con Dokploy (el método más fácil)

Dokploy es una Plataforma como Servicio de código abierto para desplegar aplicaciones, e incluye una plantilla de Convex. Uso Dokploy por defecto para despliegues en un solo servidor porque gestiona Traefik, SSL y redespliegues sin herramientas adicionales. Si quieres la comparativa de las opciones PaaS, lee la comparación de Coolify vs Dokploy vs Kamal 2. Si aún no has configurado Dokploy, usa la guía de instalación de Dokploy.

Método A: Usar la plantilla integrada de Dokploy (recomendado)

Esta es la forma más rápida de desplegar Convex. La plantilla te deja funcionando en minutos, pero actualmente está desactualizada, así que editarás el archivo compose antes de desplegar. Si eres nuevo en las apps basadas en compose dentro de Dokploy, cómo desplegar una app Docker Compose en Dokploy cubre el flujo genérico.

Paso 1: Instala Dokploy (si aún no está instalado)

bash
curl -sSL https://dokploy.com/install.sh | sh

Accede a Dokploy en http://tu-ip-vps:3000 y completa la configuración.

Paso 2: Despliega desde la plantilla

  1. Inicia sesión en el dashboard de Dokploy
  2. Haz clic en «Create Project» y ponle nombre (por ejemplo, «Convex»)
  3. Haz clic en «Templates» en la barra lateral izquierda
  4. Busca «Convex» en la galería de plantillas
  5. Haz clic en «Deploy» en la plantilla de Convex

Paso 3: Sustituye el archivo Compose

La plantilla de Dokploy está desactualizada

El blueprint oficial todavía fija imágenes del antiguo namespace ghcr.io/get-convex, usa la variable eliminada ACTIONS_USER_TIMEOUT_SECS, arrastra una DATABASE_URL heredada y solo incluye SQLite. El namespace antiguo ahora rechaza las descargas anónimas. Abre la pestaña «Docker Compose» antes de desplegar y pega el compose corregido de abajo.

Este es el compose que yo ejecutaría desde la pestaña Docker Compose de Dokploy:

yaml
services:
  backend:
    image: ghcr.io/convex/convex-backend:latest   # pin backend+dashboard to the SAME SHA for prod
    volumes:
      - data:/convex/data
    environment:
      - INSTANCE_NAME=${INSTANCE_NAME:-convex-self-hosted}
      - INSTANCE_SECRET=${INSTANCE_SECRET}
      - CONVEX_CLOUD_ORIGIN=${CONVEX_CLOUD_ORIGIN:-http://127.0.0.1:3210}
      - CONVEX_SITE_ORIGIN=${CONVEX_SITE_ORIGIN:-http://127.0.0.1:3211}
      - POSTGRES_URL=${POSTGRES_URL:-}
      - DISABLE_BEACON=${DISABLE_BEACON:-true}
      - V8_ACTION_USER_TIMEOUT_SECS=${V8_ACTION_USER_TIMEOUT_SECS:-}
      - NODE_ACTION_USER_TIMEOUT_SECS=${NODE_ACTION_USER_TIMEOUT_SECS:-}
      - DISABLE_METRICS_ENDPOINT=${DISABLE_METRICS_ENDPOINT:-true}
      - DOCUMENT_RETENTION_DELAY=${DOCUMENT_RETENTION_DELAY:-172800}
      - RUST_LOG=${RUST_LOG:-info}
      - DO_NOT_REQUIRE_SSL=${DO_NOT_REQUIRE_SSL:-1}
    healthcheck:
      test: curl -f http://localhost:3210/version
      interval: 5s
      start_period: 5s

  dashboard:
    image: ghcr.io/convex/convex-dashboard:latest  # must match backend version
    environment:
      - NEXT_PUBLIC_DEPLOYMENT_URL=${NEXT_PUBLIC_DEPLOYMENT_URL:-http://127.0.0.1:3210}
      - NEXT_PUBLIC_LOAD_MONACO_INTERNALLY=${NEXT_PUBLIC_LOAD_MONACO_INTERNALLY:-}
    depends_on:
      backend:
        condition: service_healthy

Flexibilidad de la plantilla

La plantilla de Dokploy es un punto de partida. Edita la configuración de Docker Compose y las variables de entorno para que coincidan con este fragmento, y luego añade el servicio Postgres de la Opción 2 si quieres una base de datos de producción.

SQLite vs PostgreSQL vs MySQL

Deja POSTGRES_URL y MYSQL_URL vacías y Convex usará SQLite. Para producción, define POSTGRES_URL para PostgreSQL o MYSQL_URL para MySQL. El soporte de MySQL se añadió en febrero de 2025.

Configura las variables de entorno (Dokploy)

Ve a la pestaña «Environment» y añade estas variables.

Obligatorias:

  • INSTANCE_SECRET: Genérala con openssl rand -hex 32

INSTANCE_SECRET es tu credencial raíz

Las claves de administrador se derivan de INSTANCE_NAME + INSTANCE_SECRET. Si pierdes el secreto no podrás generar nuevas claves de administrador. Si lo rotas, todas las claves de administrador existentes se rompen. Guárdalo en tu gestor de contraseñas y en tus copias de seguridad.

URLs: elige una opción.

Opción A: Los dominios Traefik gratuitos de Dokploy (inicio rápido)

bash
NEXT_PUBLIC_DEPLOYMENT_URL=http://shhosted-convex-cf33fb-91-98-95-196.traefik.me
CONVEX_CLOUD_ORIGIN=http://shhosted-convex-cf33fb-91-98-95-196.traefik.me
CONVEX_SITE_ORIGIN=http://shhosted-convex-59a34c-91-98-95-196.traefik.me

CONVEX_SITE_ORIGIN es un hostname distinto de los otros dos. Debe llegar al puerto 3211 (acciones HTTP), no al 3210.

Opción B: Tu propio dominio (producción)

Configura primero los registros DNS A y después:

bash
CONVEX_CLOUD_ORIGIN=https://api.convex.yourdomain.com
CONVEX_SITE_ORIGIN=https://actions.convex.yourdomain.com
NEXT_PUBLIC_DEPLOYMENT_URL=https://api.convex.yourdomain.com

CONVEX_CLOUD_ORIGIN y NEXT_PUBLIC_DEPLOYMENT_URL apuntan al hostname que llega al 3210. CONVEX_SITE_ORIGIN apunta al hostname que llega al 3211. Si NEXT_PUBLIC_DEPLOYMENT_URL se queda en 127.0.0.1, el dashboard cargará en tu navegador pero todas las consultas se quedarán colgadas.

PostgreSQL (opcional, déjalo vacío para usar SQLite):

bash
DB_PASSWORD=your-strong-password
POSTGRES_URL=postgresql://postgres:your-strong-password@postgres:5432

Pasa POSTGRES_URL sin nombre de base de datos y sin parámetros de consulta. Convex nombra la base de datos según la instancia, mapeando - a _, así que la instancia por defecto convex-self-hosted usa la base de datos convex_self_hosted.

Despliega, genera la clave de administrador y verifica

  1. En la pestaña «Domains», añade tus hostnames. El Traefik de Dokploy emite los certificados SSL.
  2. Haz clic en «Deploy» y espera a que los servicios estén saludables.
  3. Abre la «Terminal» en el contenedor del backend y ejecuta:
bash
cd convex
./generate_admin_key.sh
  1. Guarda la clave de administrador de forma segura. Trátala como una contraseña root.

Verifica el despliegue antes de conectar cualquier app:

  • Dokploy muestra el servicio backend como saludable
  • curl http://localhost:3210/version desde el VPS devuelve un JSON con la versión
  • El dashboard carga en :6791 o en tu dominio del dashboard
  • La clave de administrador está guardada y empieza por convex-self-hosted| (o lo que hayas puesto en INSTANCE_NAME)

Si /version no responde, el backend no está levantado. Lee docker compose logs backend o el panel de logs de Dokploy antes de tocar nada más.

Opción 2: Desplegar solo con Docker Compose

Si prefieres desplegar sin Dokploy o quieres más control, usa Docker Compose directamente.

Paso 1: Prepara tu servidor

Actualiza el sistema e instala Docker. El instalador oficial incluye el plugin de Compose, así que no hay nada extra que instalar:

bash
# Update packages
sudo apt update && sudo apt upgrade -y

# Install Docker (includes the docker compose plugin)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Confirm compose is available
docker compose version

docker-compose (con guion) es la antigua herramienta v1 y está en fin de vida. Todo lo siguiente usa docker compose (con espacio).

Paso 2: Crea el directorio del proyecto

bash
mkdir -p ~/convex-backend
cd ~/convex-backend

Paso 3: Crea el archivo Docker Compose

Elige una de las dos variantes y guárdala como docker-compose.yml (o compose.yml).

SQLite (sencillo)

yaml
services:
  backend:
    image: ghcr.io/convex/convex-backend:latest
    stop_grace_period: 10s
    stop_signal: SIGINT
    ports:
      - "3210:3210"
      - "3211:3211"
    volumes:
      - data:/convex/data
    environment:
      - INSTANCE_NAME=${INSTANCE_NAME:-convex-self-hosted}
      - INSTANCE_SECRET=${INSTANCE_SECRET}
      - CONVEX_CLOUD_ORIGIN=${CONVEX_CLOUD_ORIGIN:-http://127.0.0.1:3210}
      - CONVEX_SITE_ORIGIN=${CONVEX_SITE_ORIGIN:-http://127.0.0.1:3211}
      - V8_ACTION_USER_TIMEOUT_SECS=${V8_ACTION_USER_TIMEOUT_SECS:-}
      - NODE_ACTION_USER_TIMEOUT_SECS=${NODE_ACTION_USER_TIMEOUT_SECS:-}
      - DISABLE_METRICS_ENDPOINT=${DISABLE_METRICS_ENDPOINT:-true}
      - DOCUMENT_RETENTION_DELAY=${DOCUMENT_RETENTION_DELAY:-172800}
      - RUST_LOG=${RUST_LOG:-info}
      - DISABLE_BEACON=${DISABLE_BEACON:-false}
    healthcheck:
      test: curl -f http://localhost:3210/version
      interval: 5s
      start_period: 10s

  dashboard:
    image: ghcr.io/convex/convex-dashboard:latest
    stop_grace_period: 10s
    stop_signal: SIGINT
    ports:
      - "6791:6791"
    environment:
      - NEXT_PUBLIC_DEPLOYMENT_URL=${NEXT_PUBLIC_DEPLOYMENT_URL:-http://127.0.0.1:3210}
      - NEXT_PUBLIC_LOAD_MONACO_INTERNALLY=${NEXT_PUBLIC_LOAD_MONACO_INTERNALLY:-}
    depends_on:
      backend:
        condition: service_healthy

volumes:
  data:

PostgreSQL (producción)

yaml
services:
  backend:
    image: ghcr.io/convex/convex-backend:latest
    stop_grace_period: 10s
    stop_signal: SIGINT
    ports:
      - "3210:3210"
      - "3211:3211"
    environment:
      - INSTANCE_NAME=${INSTANCE_NAME:-convex-self-hosted}
      - INSTANCE_SECRET=${INSTANCE_SECRET}
      - CONVEX_CLOUD_ORIGIN=${CONVEX_CLOUD_ORIGIN:-http://127.0.0.1:3210}
      - CONVEX_SITE_ORIGIN=${CONVEX_SITE_ORIGIN:-http://127.0.0.1:3211}
      - POSTGRES_URL=${POSTGRES_URL}
      - DO_NOT_REQUIRE_SSL=${DO_NOT_REQUIRE_SSL:-1}
      - V8_ACTION_USER_TIMEOUT_SECS=${V8_ACTION_USER_TIMEOUT_SECS:-}
      - NODE_ACTION_USER_TIMEOUT_SECS=${NODE_ACTION_USER_TIMEOUT_SECS:-}
      - DISABLE_METRICS_ENDPOINT=${DISABLE_METRICS_ENDPOINT:-true}
      - DOCUMENT_RETENTION_DELAY=${DOCUMENT_RETENTION_DELAY:-172800}
      - RUST_LOG=${RUST_LOG:-info}
      - DISABLE_BEACON=${DISABLE_BEACON:-false}
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      test: curl -f http://localhost:3210/version
      interval: 5s
      start_period: 10s

  dashboard:
    image: ghcr.io/convex/convex-dashboard:latest
    stop_grace_period: 10s
    stop_signal: SIGINT
    ports:
      - "6791:6791"
    environment:
      - NEXT_PUBLIC_DEPLOYMENT_URL=${NEXT_PUBLIC_DEPLOYMENT_URL:-http://127.0.0.1:3210}
      - NEXT_PUBLIC_LOAD_MONACO_INTERNALLY=${NEXT_PUBLIC_LOAD_MONACO_INTERNALLY:-}
    depends_on:
      backend:
        condition: service_healthy

  postgres:
    image: postgres:17-alpine
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=convex_self_hosted
    volumes:
      - postgres-data:/var/lib/postgresql/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

volumes:
  postgres-data:

Si el puerto 3210, 3211 o 6791 ya está ocupado en el host, compruébalo con ss -tlnp | grep 3210. Los puertos del lado del host se pueden cambiar con las variables de entorno PORT, SITE_PROXY_PORT y DASHBOARD_PORT en el backend y el dashboard.

Paso 4: Crea el archivo de entorno

bash
nano .env

Añade tu configuración:

bash
# Instance Configuration
INSTANCE_NAME=convex-self-hosted
INSTANCE_SECRET=<generate-with-openssl-rand-hex-32>

# Public URLs (update these for production)
CONVEX_CLOUD_ORIGIN=http://127.0.0.1:3210
CONVEX_SITE_ORIGIN=http://127.0.0.1:3211
NEXT_PUBLIC_DEPLOYMENT_URL=http://127.0.0.1:3210

# PostgreSQL (only if using the PostgreSQL variant)
DB_PASSWORD=<your-secure-db-password>
POSTGRES_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432
DO_NOT_REQUIRE_SSL=1

# Optional: Logging
RUST_LOG=info

# Optional: Disable telemetry beacon
DISABLE_BEACON=false

Genera el secreto:

bash
openssl rand -hex 32

DO_NOT_REQUIRE_SSL=1 es para configuraciones locales o con Postgres sin SSL. Mantén el SSL obligatorio (DO_NOT_REQUIRE_SSL=0) para Postgres gestionado a través de internet público.

Paso 5: Arranca Convex

bash
# Start services
docker compose up -d

# View logs
docker compose logs -f

# Check status
docker compose ps

Verifica de inmediato:

bash
curl http://localhost:3210/version

Busca una respuesta JSON con la versión del release. docker compose ps debería mostrar ambos servicios como healthy. Si el backend está atrapado en un bucle de reinicios, docker compose logs backend es lo primero que hay que leer. Causas habituales: un INSTANCE_SECRET ausente o mal formado, una URL de Postgres inalcanzable desde el contenedor, o un conflicto de puertos.

Paso 6: Configura el proxy inverso con Nginx

Para producción con dominios personalizados, pon Nginx delante de los tres puertos. Cada hostname corresponde exactamente a un puerto del backend, y cada variable de entorno apunta a un hostname.

api.yourdomain.comCONVEX_CLOUD_ORIGINNEXT_PUBLIC_DEPLOYMENT_URLactions.yourdomain.comCONVEX_SITE_ORIGINacciones HTTPdashboard.yourdomain.comacceso desde el navegadorsin variable de entorno, solo DNSNginx / TraefikTLS + upgrade WebSocketbackend :3210API + sincronizaciónactions :3211acciones HTTPdashboard :6791dashboard de Convex
Un hostname por puerto. Apunta cada variable de entorno al hostname, nunca a 127.0.0.1, una vez que tengas una URL pública.
bash
sudo apt install nginx certbot python3-certbot-nginx -y
sudo nano /etc/nginx/sites-available/convex

Pega tres bloques server:

nginx
# Backend API -> 3210
server {
    listen 80;
    server_name api.yourdomain.com;

    location / {
        proxy_pass http://localhost:3210;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        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;
    }
}

# HTTP actions -> 3211
server {
    listen 80;
    server_name actions.yourdomain.com;

    location / {
        proxy_pass http://localhost:3211;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        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;
    }
}

# Dashboard -> 6791
server {
    listen 80;
    server_name dashboard.yourdomain.com;

    location / {
        proxy_pass http://localhost:6791;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        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;
    }
}

Habilita el sitio y obtén los certificados para los tres hostnames:

bash
sudo ln -s /etc/nginx/sites-available/convex /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d api.yourdomain.com -d actions.yourdomain.com -d dashboard.yourdomain.com

Actualiza .env con las URLs públicas y recrea el stack:

bash
CONVEX_CLOUD_ORIGIN=https://api.yourdomain.com
CONVEX_SITE_ORIGIN=https://actions.yourdomain.com
NEXT_PUBLIC_DEPLOYMENT_URL=https://api.yourdomain.com
bash
docker compose up -d

Fallos típicos en este paso: el dashboard carga pero los datos nunca llegan, lo que casi siempre significa que NEXT_PUBLIC_DEPLOYMENT_URL sigue apuntando a 127.0.0.1 y el navegador no puede alcanzarlo. Acciones HTTP que devuelven 404 suele significar que falta el vhost del 3211 o que CONVEX_SITE_ORIGIN apunta al hostname del 3210.

Paso 7: Genera la clave de administrador

bash
# Access backend container
docker compose exec backend /bin/sh

# Navigate to convex directory and generate admin key
cd convex
./generate_admin_key.sh

# Exit container
exit

La clave de administrador da acceso total

El script deriva la clave de INSTANCE_NAME + INSTANCE_SECRET. Mismo secreto, misma familia de claves. La clave otorga acceso total a la API de administración, así que trátala como una contraseña root y consulta la sección de seguridad antes de pegarla en cualquier sitio.

Guarda la clave de administrador de forma segura. La necesitarás para tus proyectos.

Usa Convex en tus proyectos

Con tu backend de Convex autoalojado en marcha, conecta tus aplicaciones. Mantén la CLI al día: npm install convex@latest (1.47.0 a octubre de 2026). Las CLI antiguas fallan contra un backend autoalojado actual de formas confusas.

Configura el entorno de tu proyecto

Añade estas dos variables de entorno al archivo .env.local de tu aplicación (no lo subas a git):

bash
CONVEX_SELF_HOSTED_URL=https://api.convex.yourdomain.com
CONVEX_SELF_HOSTED_ADMIN_KEY=convex-self-hosted|<your-admin-key>

Sustituye la URL por la URL real de tu backend (el hostname que llega al 3210) y la clave de administrador por la que generaste antes. La CLI de Convex usa tu backend autoalojado cuando estas variables están definidas.

Prueba toda la cadena:

  • npx convex --version muestra una CLI reciente
  • CONVEX_SELF_HOSTED_URL incluye el esquema (https://) y la clave de administrador es la cadena completa
  • npx convex deploy sube tus funciones sin errores
  • El dashboard muestra las funciones desplegadas y los datos que escribiste

Si los comandos npx convex fallan, comprueba primero la versión de la CLI, luego confirma que la URL tiene esquema y que la clave no está truncada. Con Postgres en el backend, docker compose logs backend debería mostrar Connected to Postgres tras el arranque, y debes ejecutar npx convex deploy una vez después de cambiar de base de datos para que las funciones lleguen a la nueva.

¿Quieres construir algo sobre esto? Crea una app en tiempo real con Astro y Convex recorre la parte del frontend, y despliega Astro + Convex en Vercel para producción cubre la vía del frontend alojado.

Configuración avanzada

Usar PostgreSQL externo (Neon, Supabase, AWS RDS)

Para PostgreSQL gestionado:

  1. Crea una base de datos llamada convex_self_hosted
  2. Obtén la cadena de conexión (sin nombre de base de datos ni parámetros de consulta)
  3. Actualiza el entorno:
bash
POSTGRES_URL=postgresql://user:[email protected]:5432
DO_NOT_REQUIRE_SSL=0

Una URL de Postgres gestionado tiene esta pinta: postgresql://user:[email protected]:5432 para Neon o postgresql://user:[email protected]:5432 para RDS. No añadas /convex_self_hosted ni ?sslmode=.... Convex deriva el nombre de la base de datos de INSTANCE_NAME y abre su propia conexión.

Se requiere la misma región

Coloca tu backend de Convex en la misma región que tu base de datos PostgreSQL. La latencia entre regiones se refleja directamente en la latencia de las mutaciones.

El ángulo del coste: el nivel gratuito de Neon es suficiente para empezar, y empaquetar postgres:17-alpine en el mismo VPS no cuesta nada extra. Si empaquetas Postgres, las copias de seguridad son tu problema. Si quieres un contenedor Postgres separado que puedas inspeccionar, ejecuta PostgreSQL y pgAdmin en Docker.

Usar MySQL (y PlanetScale)

Convex soporta MySQL desde febrero de 2025. Define la variable de entorno MYSQL_URL:

bash
MYSQL_URL=mysql://user:[email protected]

La base de datos debe llamarse convex_self_hosted, la misma regla que con PostgreSQL. PlanetScale es el ejemplo documentado de MySQL gestionado; AWS RDS o cualquier servidor MySQL 8+ también funciona. Se aplica el mismo consejo de región: mantén la base de datos cerca del backend de Convex.

Monitorización con Prometheus

El backend autoalojado expone un endpoint de métricas compatible con Prometheus en /metrics. El compose oficial lo trae deshabilitado, así que define esto para exponerlo:

bash
DISABLE_METRICS_ENDPOINT=false

Verifica la recolección:

bash
curl http://localhost:3210/metrics | head

Si obtienes un 404, la variable sigue en true. El endpoint te da contadores de peticiones, histogramas de latencia y tasas de error para Grafana o cualquier stack compatible con Prometheus. Para monitorización a nivel de host en paralelo, monitoriza tu servidor con Beszel y Uptime Kuma.

Ajustar la concurrencia y los timeouts de las acciones

El backend expone variables de entorno para controlar cuántas consultas, mutaciones y acciones se ejecutan al mismo tiempo:

bash
APPLICATION_MAX_CONCURRENT_QUERIES=16
APPLICATION_MAX_CONCURRENT_MUTATIONS=16
APPLICATION_MAX_CONCURRENT_V8_ACTIONS=16
APPLICATION_MAX_CONCURRENT_NODE_ACTIONS=16

El valor por defecto es 16 para cada una, que coincide con el límite de consultas concurrentes del nivel gratuito de la nube. Auméntalos si tu servidor tiene CPU y memoria de sobra.

Los timeouts de las acciones se dividen por runtime:

bash
V8_ACTION_USER_TIMEOUT_SECS=1800    # V8 actions, default 1800 (30 min)
NODE_ACTION_USER_TIMEOUT_SECS=600   # Node actions, default 600 (10 min)
HTTP_SERVER_TIMEOUT_SECONDS=300     # HTTP server, default 300 (5 min)

Si tus acciones agotan el tiempo de espera, sube el parámetro correspondiente. No dejes la antigua ACTIONS_USER_TIMEOUT_SECS en tu compose. Fue eliminada y dividida en el par de arriba.

Configurar el almacenamiento S3

Para almacenamiento de archivos en producción, descarga los blobs a S3 en lugar del volumen local:

yaml
services:
  backend:
    environment:
      # ... other vars ...
      - AWS_REGION=us-east-1
      - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
      - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
      - AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}
      - S3_STORAGE_EXPORTS_BUCKET=convex-snapshot-exports
      - S3_STORAGE_SNAPSHOT_IMPORTS_BUCKET=convex-snapshot-imports
      - S3_STORAGE_MODULES_BUCKET=convex-modules
      - S3_STORAGE_FILES_BUCKET=convex-user-files
      - S3_STORAGE_SEARCH_BUCKET=convex-search-indexes

Crea los buckets en AWS S3 o usa almacenamiento compatible con S3 como Cloudflare R2:

bash
S3_ENDPOINT_URL=https://<account-id>.r2.cloudflarestorage.com
AWS_ACCESS_KEY_ID=<your-r2-access-key>
AWS_SECRET_ACCESS_KEY=<your-r2-secret-key>

Para MinIO, DigitalOcean Spaces y otros almacenes compatibles con S3, los parámetros de compatibilidad importan: AWS_S3_FORCE_PATH_STYLE=true para el direccionamiento path-style, AWS_S3_DISABLE_CHECKSUMS=true y AWS_S3_DISABLE_SSE=true para almacenes que rechazan las cabeceras checksum y SSE más nuevas.

Migración entre proveedores de almacenamiento

Si cambias de SQLite a PostgreSQL o modificas la configuración de S3:

bash
# Export data from old backend
npx convex export --path backup.zip

# Deploy new backend with different storage
# ...

# Import data to new backend
npx convex import --replace-all backup.zip

Las exportaciones son instantáneas de un momento dado, así que haz la exportación después de que pare el tráfico si necesitas hasta la última escritura.

Dominios personalizados para las acciones HTTP

Para servir acciones HTTP desde un dominio personalizado:

  1. Configura el DNS de actions.yourdomain.com y haz proxy al puerto 3211 (ver la configuración de Nginx de arriba)
  2. Configura el entorno del backend:
bash
CONVEX_SITE_ORIGIN=https://actions.yourdomain.com

CONVEX_SITE_ORIGIN debe ser la URL que llega al puerto 3211, no al 3210. Es la configuración errónea más común de esta sección.

  1. En tu frontend, sobrescribe la URL del sitio en tiempo de compilación si la generada es incorrecta:
bash
CONVEX_SITE_URL=https://actions.yourdomain.com

Notas sobre el dashboard y el beacon

Dos datos operativos menores que ahorran tickets de soporte:

  1. El editor Monaco del dashboard se carga desde una CDN por defecto. En una red restringida o aislada define NEXT_PUBLIC_LOAD_MONACO_INTERNALLY=true para que el dashboard funcione sin acceso saliente a la CDN.
  2. El beacon de telemetría es opcional. Define DISABLE_BEACON=true para apagarlo.

Qué envía el beacon

Con el beacon habilitado, el backend envía un identificador de despliegue aleatorio, la versión de la migración de la base de datos, la revisión de git y el tiempo de actividad. Nada de datos, consultas ni esquema. El proyecto es explícito sobre esto en la sección Disclaimers del repositorio, que es el tipo de transparencia que quiero antes de dejarlo encendido o apagarlo.

Referencia de variables de entorno clave

Variable Valor por defecto Qué hace
INSTANCE_NAME convex-self-hosted Identificador de instancia; también deriva el nombre de la base de datos
INSTANCE_SECRET (obligatoria) Credencial raíz para generar claves de administrador
CONVEX_CLOUD_ORIGIN http://127.0.0.1:3210 URL pública de la API del backend (puerto 3210)
CONVEX_SITE_ORIGIN http://127.0.0.1:3211 URL pública de las acciones HTTP (puerto 3211)
NEXT_PUBLIC_DEPLOYMENT_URL http://127.0.0.1:3210 URL que usa el navegador para llegar al backend
POSTGRES_URL (vacía = SQLite) Postgres externo, sin nombre de bd ni parámetros
MYSQL_URL (vacía) MySQL externo, la bd debe ser convex_self_hosted
DO_NOT_REQUIRE_SSL 1 en el compose oficial Pon 0 para exigir TLS a la base de datos
V8_ACTION_USER_TIMEOUT_SECS 1800 Timeout para acciones V8
NODE_ACTION_USER_TIMEOUT_SECS 600 Timeout para acciones Node
HTTP_SERVER_TIMEOUT_SECONDS 300 Timeout de peticiones del servidor HTTP
APPLICATION_MAX_CONCURRENT_QUERIES 16 Límite de consultas concurrentes
APPLICATION_MAX_CONCURRENT_MUTATIONS 16 Límite de mutaciones concurrentes
APPLICATION_MAX_CONCURRENT_V8_ACTIONS 16 Límite de acciones V8 concurrentes
APPLICATION_MAX_CONCURRENT_NODE_ACTIONS 16 Límite de acciones Node concurrentes
DISABLE_METRICS_ENDPOINT true Pon false para exponer /metrics
DISABLE_BEACON false en la mayoría de los compose Pon true para desactivar la telemetría
DOCUMENT_RETENTION_DELAY 172800 (2 días) en el compose oficial Cuánto tiempo se conservan las versiones antiguas de los documentos
PORT / SITE_PROXY_PORT / DASHBOARD_PORT 3210 / 3211 / 6791 Sustituciones de puertos del lado del host
NEXT_PUBLIC_LOAD_MONACO_INTERNALLY (vacía) Pon true para un dashboard sin acceso a CDN

Mantenimiento y copias de seguridad

Copias de seguridad periódicas

Para despliegues con Dokploy, configura copias de seguridad automatizadas desde la interfaz de Dokploy o sigue la guía de copias de seguridad de Dokploy.

Para Docker Compose con PostgreSQL:

bash
# Manual backup
docker compose exec postgres pg_dump -U postgres convex_self_hosted > backup-$(date +%Y%m%d).sql

# Restore backup
cat backup-20241124.sql | docker compose exec -T postgres psql -U postgres convex_self_hosted

Script de copia de seguridad automatizada (backup.sh):

bash
#!/bin/bash
BACKUP_DIR="/backups/convex"
DATE=$(date +%Y%m%d-%H%M)
mkdir -p $BACKUP_DIR

docker compose exec -T postgres pg_dump -U postgres convex_self_hosted | gzip > $BACKUP_DIR/convex-$DATE.sql.gz

# Keep only last 7 days
find $BACKUP_DIR -name "convex-*.sql.gz" -mtime +7 -delete

Dale permisos de ejecución y añádelo al crontab:

bash
chmod +x backup.sh
crontab -e
# Add: 0 2 * * * /path/to/backup.sh

La copia de seguridad a nivel de aplicación funciona tanto con SQLite como con Postgres y es lo que quieres para migraciones:

bash
npx convex export --path backup.zip
npx convex env list --include-values > .env.convex

Conserva los dos tipos. El volcado SQL sirve para restaurar a nivel de infraestructura en el mismo stack. backup.zip más .env.convex restaura en cualquier instancia, incluida una máquina SQLite sencilla o Convex Cloud. Sube ambos a S3 o R2 fuera del sitio (unos 1-5 $/mes) para que un VPS muerto no sea un proyecto muerto.

Actualizar Convex

No hagas simplemente pull y cruces los dedos. La vía oficial de actualización es primero la copia de seguridad.

Antes que nada:

bash
npx convex export --path backup.zip
npx convex env list --include-values > .env.convex

Fija ambas imágenes al mismo SHA

No se garantiza que versiones distintas de convex-backend y convex-dashboard sean compatibles. Las imágenes se etiquetan con latest y con SHAs de commit completos de 40 caracteres. Los releases se llaman precompiled-YYYY-MM-DD-<shortsha>, por ejemplo precompiled-2026-10-10-72ce13c en la página de releases. Para producción:

yaml
image: ghcr.io/convex/convex-backend:72ce13c...   # full commit SHA
image: ghcr.io/convex/convex-dashboard:72ce13c... # SAME SHA

Actualización en el lugar (caso normal):

bash
# Pin both images to the same new SHA, then
docker compose pull && docker compose up -d

# Watch migrations finish
docker compose logs -f backend
# wait for: Executing Migration N/N. MigrationComplete(N+1)

No cortes el tráfico ni des por terminada la actualización hasta ver la línea MigrationComplete. Si el backend está en medio de una migración, déjalo terminar.

Actualización por exportación/importación (saltos de versión mayores):

  1. Detén el tráfico externo
  2. npx convex export
  3. npx convex env list --include-values > .env.convex
  4. Actualiza las imágenes (ambas al mismo SHA)
  5. npx convex import --replace-all
  6. npx convex env set --force --from-file .env.convex
  7. Restaura el tráfico

Las exportaciones son de un momento dado. Tu exportación final debe ocurrir después de que cese la carga.

Rollback: restaura backup.zip con npx convex import --replace-all sobre las imágenes fijadas anteriormente. Con Postgres, restaurar el volcado SQL previo a la actualización también funciona. Si aún no se ejecutó ninguna migración, volver al SHA fijado anterior en el compose y ejecutar docker compose up -d es suficiente.

Vía Dokploy: redespliega desde la UI del servicio. Consulta cómo actualizar stacks de Docker Compose en Dokploy para los detalles de actualizaciones por etiqueta frente a SHA fijado.

Lista de verificación de la actualización:

  • backup.zip previo a la actualización exportado y verificado
  • .env.convex guardado
  • Ambas imágenes fijadas al mismo SHA nuevo
  • Línea MigrationComplete vista en el log tras el arranque
  • Prueba de humo superada (dashboard, una consulta, una mutación)

Borrar datos / reiniciar una instancia

Esto destruye datos

Haz primero una copia de seguridad. Comprueba dos veces que CONVEX_SELF_HOSTED_URL apunta al despliegue que quieres borrar, no a producción.

No existe intencionadamente un comando de reset destructivo. Borrar los datos significa importar una instantánea vacía en cada tabla:

bash
# List tables
npx convex data

# Clear one table
npx convex import --table $tableName --replace --format jsonLines /dev/null -y

Repite eso para los nombres de tabla que devuelve npx convex data. Para una reconstrucción completa, destruir el volumen o la base de datos Postgres y volver a ejecutar npx convex deploy suele ser más limpio que borrar tabla por tabla.

Buenas prácticas de seguridad

  • INSTANCE_SECRET es la credencial raíz: perderlo significa no poder crear nuevas claves de administrador; rotarlo invalida todas las claves de administrador existentes. Guárdalo en tu gestor de contraseñas y en tus copias de seguridad. Consulta secretos de Docker Compose y alternativas seguras para mejores patrones que un .env en texto plano
  • La clave de administrador es acceso total a la API de administración: trátala como una contraseña root, no la acotes, y nunca la incluyas en código del frontend
  • Solo HTTPS: TLS en todos los hostnames públicos
  • Cierra los puertos del backend: una vez que el proxy funciona, solo 80 y 443 deberían estar abiertos. Bloquea 3210, 3211 y 6791 en el firewall
  • Contraseñas de base de datos fuertes: contraseñas complejas para PostgreSQL y MySQL, incluso en una red Docker privada
  • Actualizaciones regulares: mantén Convex, Docker y los paquetes del sistema actualizados con el procedimiento de actualización con copia previa de arriba
  • Cifrado de copias de seguridad: cifra las copias de seguridad de la base de datos y las exportaciones en reposo, sobre todo si acaban en S3
  • Los archivos de entorno fuera de git: .env y .env.local nunca se suben al repositorio
  • Rota las claves de administrador de forma deliberada: solo cuando puedas actualizar el .env.local de cada app en la misma ventana
  • Aislamiento de red: usa redes de Docker para aislar los servicios de contenedores no relacionados en la máquina
  • Monitoriza logs y puertos: configura monitorización de logs y alertas sobre la superficie expuesta

Rotar INSTANCE_SECRET es una operación de mantenimiento, no una tarea casual. Todas las claves de administrador derivadas del secreto antiguo se rompen, así que regenera con generate_admin_key.sh y actualiza el .env.local de cada app en la misma ventana. Para la parte del firewall del host y la detección de intrusiones, protege tu VPS con CrowdSec.

Solución de problemas comunes

Síntoma Causa probable Solución
docker pull ghcr.io/get-convex/... denegado o no encontrado El namespace de imágenes se movió Usa ghcr.io/convex/convex-backend y ghcr.io/convex/convex-dashboard
El dashboard carga pero las consultas se cuelgan NEXT_PUBLIC_DEPLOYMENT_URL apunta a 127.0.0.1 Pon la URL que el navegador pueda alcanzar (tu hostname api.)
Bucle de reinicios del backend INSTANCE_SECRET incorrecto, Postgres inalcanzable o conflicto de puertos docker compose logs backend; comprueba ss -tlnp | grep 3210
Acciones HTTP 404 No hay vhost para el puerto 3211, o CONVEX_SITE_ORIGIN apunta al 3210 Añade el bloque server de actions. y apunta CONVEX_SITE_ORIGIN a él
No aparece Connected to Postgres en los logs Forma incorrecta de POSTGRES_URL, nombre de bd incorrecto o requisito de SSL Sin nombre de bd ni parámetros; bd llamada convex_self_hosted; DO_NOT_REQUIRE_SSL=1 para Postgres local sin SSL
Las acciones agotan el tiempo antes de tiempo Parámetros de timeout antiguos o por defecto Define V8_ACTION_USER_TIMEOUT_SECS, NODE_ACTION_USER_TIMEOUT_SECS, HTTP_SERVER_TIMEOUT_SECONDS
/metrics devuelve 404 El endpoint de métricas está deshabilitado por defecto Define DISABLE_METRICS_ENDPOINT=false
El editor del dashboard no carga sin conexión Monaco se carga desde una CDN Define NEXT_PUBLIC_LOAD_MONACO_INTERNALLY=true

Si nada de esto encaja, el canal #self-hosted del Discord de Convex está activo y merece la pena preguntar ahí.

Conclusión

Autoalojar Convex te da control sobre tu infraestructura de backend en tiempo real manteniendo la experiencia de desarrollador de Convex. Ya sea con Dokploy o con Docker Compose, puedes tener un despliegue de Convex listo para producción en una sesión. Convex se encarga de las consultas en tiempo real, las funciones serverless, el almacenamiento de archivos y la búsqueda. El autoalojamiento añade control de la infraestructura a esas funciones.

Convex liberó su backend en noviembre de 2025 y levantó una Serie B de 57M $ liderada por Insight Partners en agosto de 2026. El proyecto se desarrolla activamente, y la versión autoalojada sigue al código de la nube con pocos días de diferencia. Ese es el argumento de frescura del autoalojamiento: no estás apostando por un proyecto secundario.

Para aplicaciones pequeñas, SQLite funciona bien con recursos mínimos. Cuando necesites escalar, pasa a PostgreSQL o MySQL, fija los SHAs de tus imágenes y mantén las copias de seguridad fuera del sitio.

Próximos pasos

Saber más sobre Convex

¿Preguntas sobre autoalojar Convex? Deja un comentario abajo.

Preguntas frecuentes

¿Debería usar SQLite o PostgreSQL?

SQLite funciona bien para:

  • Desarrollo y pruebas
  • Aplicaciones pequeñas y medianas (menos de 10k peticiones/día)
  • Despliegues en un solo servidor
  • Prototipos

PostgreSQL es mejor cuando:

  • Tienes cargas de producción con mucho tráfico
  • Quieres funciones de base de datos gestionada y replicación
  • Usas servicios gestionados de bases de datos (Neon, Supabase, AWS RDS)

Empieza con SQLite y pasa a PostgreSQL cuando necesites más fiabilidad. El flujo de exportación/importación hace que ese cambio sea aburrido, que es lo que quieres.

¿Puedo migrar de Convex en la nube a autoalojado?

Sí. El proceso es exportar e importar:

  1. Exporta los datos de la nube: npx convex export --prod
  2. Configura el backend autoalojado
  3. Importa los datos: npx convex import --replace-all
  4. Actualiza las variables de entorno en tu frontend
  5. Vuelve a desplegar las funciones: npx convex deploy

El código de tu aplicación no cambia. Solo cambian la URL del backend y la clave de administrador.

¿Cuánto cuesta autoalojar Convex?

Costes mensuales (ejemplo):

  • VPS con 4 GB de RAM (clase Hetzner): 5-10 $/mes
  • PostgreSQL en Neon: nivel gratuito, o postgres:17-alpine empaquetado en la misma máquina por 0 $
  • Dominio: unos 1 $/mes
  • Almacenamiento S3 (opcional): unos 1-5 $/mes

Total: 10-30 $/mes todo incluido.

Compáralo con Convex Professional a 25 $ por desarrollador al mes. Para un operador en solitario, autoalojar gana en coste si tu tiempo es gratis. Para un equipo, el producto gestionado suele ser más barato que las horas de soporte. Las cifras de una prueba de carga real están en nuestras benchmarks de Convex autoalojado frente a la nube.

¿Puedo usar Convex autoalojado en producción?

Sí. Asegúrate de:

  • Usar PostgreSQL o MySQL en lugar de SQLite
  • Configurar copias de seguridad automatizadas (volcado SQL más npx convex export)
  • Configurar la monitorización
  • Usar SSL/TLS
  • Fijar las imágenes del backend y del dashboard al mismo SHA
  • Usar el procedimiento de actualización con copia previa de la sección Mantenimiento
  • Ejecutar en un entorno de alojamiento fiable

Las pautas de producción de este artículo cubren el resto.

¿Soporta Convex autoalojado todas las funciones de la nube?

Convex autoalojado soporta todas las funciones del nivel gratuito del producto en la nube: consultas y mutaciones en tiempo real, funciones serverless, almacenamiento de archivos, funciones programadas, búsqueda de texto completo, búsqueda vectorial y acciones HTTP. El producto en la nube está optimizado para escala. Tú te encargas de la gestión de la infraestructura: copias de seguridad, escalado y mantenimiento.

¿Cómo escalo Convex autoalojado?

Escala verticalmente:

  • Aumenta los recursos del VPS (CPU/RAM)
  • Pasa a una instancia de PostgreSQL gestionado más grande
  • Descarga los archivos a S3

No hay una historia oficial de múltiples instancias para el backend autoalojado. Es un único servicio con estado, así que no pongas varios backends detrás de un balanceador de carga. Ejecuta una máquina más grande y deja que Postgres haga el trabajo pesado. Si se te queda pequeño un nodo, el producto gestionado es el siguiente paso.

¿Puedo usar Convex Auth con autoalojado?

Convex Auth funciona con despliegues autoalojados. Sigue las instrucciones de configuración manual en la documentación de Convex Auth. La configuración automática de la CLI aún no soporta autoalojado.

¿Qué pasa si mi backend se cae?

Con una configuración adecuada:

  • Docker reinicia los contenedores caídos
  • Los datos de SQLite persisten en el volumen, los de Postgres en el suyo
  • Las suscripciones en tiempo real se reconectan automáticamente
  • Las operaciones recientes pueden necesitar reintento por parte de los clientes

Para alta disponibilidad:

  • Monitoriza con Beszel y Uptime Kuma
  • Mantén PostgreSQL en un servicio gestionado con replicación si lo necesitas
  • Mantén copias de seguridad automatizadas y una ruta de restauración documentada

Un solo VPS es un único punto de fallo. Presupuesta para eso en lugar de fingir lo contrario.