Por qué autoalojar Directus en un VPS
Directus se conecta a su base de datos existente (PostgreSQL, MySQL, SQLite, MariaDB) sin imponer su propio esquema: introspecciona sus tablas y genera la API y la interfaz de administración por encima. Al autoalojarlo en un VPS, evita las tarifas por usuario de la oferta Cloud oficial y mantiene sus contenidos, sus medios y su base SQL en su propia infraestructura. Es una decisión estructurante para las agencias que entregan varios sitios: un único Directus puede servir de trastienda a varios front-ends (Nuxt, Next, móvil). El control de la base, de las extensiones y de los webhooks le permite integrar Directus en cualquier pipeline de datos sin depender de un proveedor externo, sin que ningún servicio de terceros se interponga entre sus front-ends y sus datos.
Las ventajas concretas del self-hosting de Directus
- API REST y GraphQL generadas automáticamente a partir de su esquema SQL, sin escribir código.
- Interfaz de administración no-code para modelar el contenido y gestionar los roles y los permisos granulares.
- Compatible con una base SQL existente: puede exponerla sin migrarla ni desnaturalizarla.
- Gestión de medios, transformaciones de imágenes al vuelo y almacenamiento local o S3, a su elección.
- Flows y webhooks integrados para automatizar procesos (notificaciones, sincronizaciones).
- Mutualización: un solo VPS con Directus puede alimentar varios sitios y aplicaciones front-end.
Requisitos de hardware y software
Directus es una aplicación Node.js que se apoya en una base de datos externa. Cuente con 2 GB de RAM como mínimo para ejecutar cómodamente Directus y PostgreSQL en el mismo VPS; se recomiendan 4 GB en producción, con transformaciones de imágenes y varios administradores simultáneos. Uno o dos vCPU bastan para empezar. Prevea una caché Redis (opcional, pero aconsejable para las sesiones y el rate limiting) y un volumen de 30 a 60 GB SSD según su biblioteca de medios. Necesitará Docker y Docker Compose, un dominio que apunte al VPS y una clave secreta robusta para SECRET y el hash de los tokens. Postgres sigue siendo la base recomendada para las funcionalidades avanzadas.
Desplegar Directus paso a paso
Aprovisionar el VPS y Docker
Tras conectarse por SSH, instale Docker y Docker Compose. Cree un registro DNS A para
cms.mondomaine.comhacia la IP del VPS. Abra únicamente los puertos 80 y 443 en el firewall (ufw allow 80,443/tcp).Definir el stack en docker-compose.yml
Declare tres servicios:
database(imagenpostgres:16con un volumen persistente),cache(redis) ydirectus(directus/directus). Conecte Directus a Postgres mediante las variablesDB_CLIENT=pg,DB_HOST=database,DB_DATABASE,DB_USER,DB_PASSWORD.Configurar las variables de entorno
Rellene
KEYySECRETcon cadenas aleatorias (openssl rand -hex 32), definaADMIN_EMAILyADMIN_PASSWORDpara la primera cuenta, yPUBLIC_URL=https://cms.mondomaine.compara que los enlaces y las subidas sean correctos.Arrancar e inicializar la base de datos
Ejecute
docker compose up -d. En el primer arranque, Directus crea automáticamente las tablas del sistema y la cuenta de administrador. Siga la inicialización condocker compose logs -f directus.Conectar el reverse proxy y el TLS
Coloque Caddy o Traefik delante de Directus para gestionar Let's Encrypt. Con Traefik, añada las etiquetas de enrutado en el servicio
directusy el certresolver ACME. Compruebe quePUBLIC_URLcoincide exactamente con el dominio HTTPS para evitar problemas de CORS y de subidas.Proteger y respaldar
Restrinja los orígenes CORS a los dominios de sus front-ends, desactive el registro público si no le sirve y, después, programe un
pg_dumpdiario más una copia de la carpetauploadshacia un almacenamiento remoto.
Para servir las imágenes con buen rendimiento, active el almacenamiento de los medios en un bucket compatible con S3 en lugar del disco local, y ajuste ASSETS_CACHE_TTL: esta variable fija la duración de la caché en el navegador (el valor max-age de la cabecera Cache-Control, 30 días por defecto); no almacena las transformaciones en caché en el servidor. Coloque un CDN delante de Directus para descargar al VPS de las peticiones de medios. Después, acote las transformaciones al vuelo: ASSETS_TRANSFORM_MAX_OPERATIONS limita el número de operaciones por petición (5 por defecto, sin contar los preajustes guardados), ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION el tamaño en píxeles (6000 por defecto) y ASSETS_TRANSFORM_MAX_CONCURRENT el número de transformaciones simultáneas (25 por defecto).
Servir archivos desde S3: qué cambia para la memoria
Cuando el almacenamiento de medios apunta a un bucket compatible con S3, Directus no redirige al visitante al bucket: la petición /assets/ID_ARCHIVO pasa por el proceso Node, que lee el objeto en el proveedor y lo retransmite al cliente en flujo. El controlador se configura con variables: STORAGE_LOCATIONS=s3, después STORAGE_S3_DRIVER=s3, STORAGE_S3_KEY, STORAGE_S3_SECRET, STORAGE_S3_BUCKET, STORAGE_S3_REGION y, para un almacenamiento compatible como MinIO, STORAGE_S3_ENDPOINT con STORAGE_S3_FORCE_PATH_STYLE=true. En la práctica, la memoria del contenedor depende del número de descargas simultáneas y de la velocidad de cada cliente, no solo del tamaño de la base. Es en este camino donde algunos usuarios señalan un consumo que no vuelve a bajar, sobre todo con vídeos o archivos voluminosos.
Solución de problemas: la memoria sube hasta que el contenedor se detiene
El síntoma se describe en el ticket 26206 del repositorio directus/directus, abierto en noviembre de 2025 sobre una instancia Docker autoalojada con la versión 11.13.2 y PostgreSQL 16: la memoria del pod aumenta de forma constante hasta el límite fijado y después el pod es detenido y se reinicia. La pendiente es menor por la noche y los fines de semana, lo que apunta al tráfico de archivos y no a una fuga en reposo. En el momento de redactar (finales de octubre de 2026), el ticket sigue abierto, etiquetado como Bug, Performance y AWS S3. Ningún miembro del equipo de Directus ha confirmado allí una causa: todo lo que sigue son hipótesis de participantes, no un diagnóstico del mantenimiento.
Lo que señalan los participantes del ticket
- Archivos pesados — el problema se reproduce con un script de carga k6 sobre vídeos de 36 a 86 MB y sobre doce archivos de unos 500 MB; la petición pasa por
/assets. - Varios almacenamientos — se citan AWS S3 y MinIO, además de otro servicio compatible con S3 en un proveedor de aplicaciones.
- Crecimiento lento con imágenes — un participante pasa de unos 200 MB tras un redespliegue a 1 GB en pocos días; otro ve pods que suben de 1,3 GB a más de 2 GB en casi dos semanas.
- Hipótesis de los flujos sin cerrar — una corrección limpia los flujos cuando un cliente se desconecta durante una descarga; un colaborador la sitúa en la 11.17.2 y un participante observa una mejora sin que desaparezca el crecimiento.
- Hipótesis de la suma de verificación — en octubre de 2026, un participante atribuye el problema a la validación de la suma de verificación de las respuestas del SDK de AWS S3: el flujo de validación (
ChecksumStream, paquete@smithy/util-stream) ignoraría la contrapresión. Su banco de pruebas: límite de 1 GiB y objeto de 150 MB; un cliente lento hace pasar la memoria externa de 8 a 160 MB, tres clientes provocan la parada en 15 segundos y los archivos subidos en multipart no lo desencadenan. Precisa que eso no explica el crecimiento lento durante varios días sin descargas grandes. - Informe sobre la versión 12 — otro participante indica que subir a la versión 12 resolvió el problema en su caso, aunque el ticket sigue abierto.
Diagnosticar sin adivinar
Confirmar la parada por falta de memoria
Busque la huella del kernel con
dmesg -T | grep -i "out of memory", sigadocker events --filter event=oomo lea el campoOOMKilleddedocker inspect. Una parada de este tipo no deja ningún mensaje de error de Directus: el contenedor simplemente se reinicia.Fijar un límite de memoria explícito
En el archivo Compose, dé al servicio
directusun límite (mem_limitodeploy.resources.limits.memory) inferior a la RAM libre del VPS, conrestart: unless-stopped. Sin límite, el kernel del host elige por sí mismo qué proceso matar, a veces PostgreSQL en lugar de Directus.Medir la curva
Registre
docker stats --no-streamcada minuto en un archivo, junto con el número de peticiones/assetsen curso. Anote el valor tras el reinicio, la meseta y si la curva sigue el tráfico o sube en reposo. Un límite de heap de Node (--max-old-space-size) no acota la memoria fuera del heap, la de los búferes, que es la zona señalada por la hipótesis de la suma de verificación.Reproducir con un cliente lento
En un entorno de pruebas, nunca en producción, descargue un archivo grande con
curl --limit-rate 200k -o /dev/null https://cms.mondomaine.com/assets/ID_ARCHIVOdesde varios terminales y observedocker stats. Un script k6 hace lo mismo de forma más reproducible.Capturar dos perfiles de heap
Añada
NODE_OPTIONS=--heap-prof --heap-prof-dir=/directus/profilesal entorno del servicio, con una carpeta montada como volumen. Node solo escribe el perfil cuando el proceso termina limpiamente: detenga el contenedor condocker compose stop directusuna primera vez justo después del arranque (referencia) y una segunda cuando la memoria se haya hinchado. Una parada por falta de memoria mata el proceso sin escribir ningún perfil.
Soluciones provisionales señaladas, ninguna confirmada por el equipo de Directus
Ninguna de estas pistas ha recibido validación oficial en el ticket. Pruébelas en un entorno de preproducción, mida antes y después, y no las presente como correcciones.
Pistas señaladas para el problema de memoria
Desplace la tabla
| Pista | Origen del informe | Estado y reservas |
|---|---|---|
| `AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED` | Un participante, en octubre de 2026, con un banco de pruebas | No confirmada por el equipo. Según la documentación de AWS, la validación de la suma de verificación de las descargas solo se realiza si quien llama la activa explícitamente: se pierde esa comprobación de integridad. |
| Subir a la versión 12 | Un participante dice que resolvió el problema; otro sitúa una corrección a partir de la 12.3.1 | No confirmada. Las notas de la 12.3.1 solo mencionan dependencias de controladores de almacenamiento actualizadas. Cambio de versión mayor: lea las notas y haga una copia antes. |
| Versión 11.17.2 o posterior | Un colaborador la recomienda por la limpieza de los flujos de clientes desconectados | La corrección está fusionada y cierra otro ticket (26991); en el ticket 26206, un participante describe una mejora pero un crecimiento que persiste. |
| Redespliegue programado con cron | Un participante, de forma provisional | Oculta el síntoma sin corregir nada y corta las descargas en curso. |
| Límite de memoria y reinicio automático | Recomendación de explotación de esta guía | Limita los daños: el contenedor se reinicia limpiamente en lugar de arrastrar al host. No trata la causa. |
Qué recopilar para un informe de error útil
El equipo pidió perfiles de heap: sin ellos, el ticket no puede avanzar. Antes de comentar o de abrir un ticket nuevo, reúna los elementos siguientes.
El expediente que adjuntar
- Versión exacta — la etiqueta de la imagen de Directus (no
latest) y la fecha del último reinicio. - Almacenamiento — controlador, proveedor (AWS, MinIO, otro) y región, sin la clave ni el secreto, más el valor de
AWS_RESPONSE_CHECKSUM_VALIDATIONsi está definido. - Límites — memoria del contenedor, RAM del host y política de reinicio.
- Carga — número y tamaño de los archivos servidos, descargas simultáneas, presencia de un CDN o de un proxy delante de Directus, clientes lentos o desconectados.
- Curva de memoria — memoria total del contenedor (no solo del proceso) durante varios días, con el tráfico
/assetsal lado. - Dos perfiles de heap — referencia y estado hinchado. El colaborador que los pide precisa que solo contienen trazas de pila y tamaños de asignación muestreados, no el contenido de los archivos ni los secretos.
- Modo de subida de los archivos — de una vez o en multipart, ya que un participante afirma que estos últimos no desencadenan el caso.
Antes de subir a la versión 12, lea las notas de la 12.3.0: corrige conexiones de almacenamiento que se fugaban cuando se cancelaba una petición de asset o fallaba una transformación, pero también cambia el comportamiento de exists(), que ahora lanza un error en lugar de devolver falso. Con S3, un objeto ausente puede entonces producir una respuesta 403 en lugar de 404 si las credenciales no permiten listar el bucket: conceda s3:ListBucket. Haga una copia de la base y de los archivos y pruebe la subida en una copia antes de tocar la producción.
Despliegue de Directus en un clic en ServOrbit
Directus está disponible directamente desde el Marketplace de ServOrbit. Seleccione la aplicación al pedir su VPS: Docker viene preinstalado, el contenedor Directus arranca automáticamente y sus credenciales de administrador ([email protected] más contraseña generada) se muestran en su área de cliente. Acceda al panel de administración mediante un túnel SSH o vinculando un dominio desde su panel de control — sin instalar Docker ni editar un archivo Compose a mano.