Fredy Acuna
  • Posts
  • Projects
  • Contact
LinkedInXGitHubMedium

© 2026 Fredhii. All rights reserved.

Back to posts
Cómo Instalar Engram Cloud en Dokploy (Memoria Persistente para Tus Agentes de IA)

Cómo Instalar Engram Cloud en Dokploy (Memoria Persistente para Tus Agentes de IA)

Fredy Acuna / May 4, 2026 / 12 min read

Self-Hostea Tu Propia Memoria Persistente para Agentes de IA

Engram es un sistema de memoria persistente para agentes de IA que se conectan vía MCP (Claude Code, Cursor, Codex, etc.). Localmente guarda todo en SQLite, y opcionalmente podés sincronizar tu memoria con un servidor cloud para acceder a ella desde cualquier maquina o compartirla entre proyectos.

En esta guía vamos a montar Engram Cloud en tu propio VPS usando Dokploy, con autenticación real (no modo inseguro), HTTPS automático y dashboard web. Esta guía nace de hacerlo en producción y resolver TODOS los errores que aparecieron en el camino.


Lo Que Vas a Aprender

  • Desplegar Engram Cloud usando la imagen oficial de GHCR (sin buildear nada)
  • Configurar autenticación con bearer token + JWT secret
  • Aislar postgres dentro del compose (sin exponerlo al host)
  • Conectar tu dominio con HTTPS automático vía Traefik
  • Acceder al dashboard web para navegar tu memoria
  • Enrolar proyectos desde tu cliente local
  • Resolver los 5 errores comunes (sí, los vas a tener — yo los tuve todos)

Requisitos Previos

Antes de empezar, asegurate de tener:

  • Una instancia de Dokploy funcionando (revisá Cómo Instalar Coolify si necesitás algo similar para arrancar)
  • Un dominio o subdominio listo para apuntar (ej. engram.tudominio.com)
  • Acceso SSH al VPS (recomendado para diagnosticar problemas)
  • Tu cuenta de Dokploy conectada a GitHub (vamos a usar deploy desde repo)

Entendiendo Engram

Engram es un binario Go agnóstico al agente. Tiene varios modos:

  • CLI/TUI local: guarda memoria en ~/.engram/ (SQLite)
  • MCP server: expone tools (mem_save, mem_search, etc.) a tu agente de IA
  • Cloud server: replica la memoria local a un postgres remoto, con dashboard web

Lo importante: el SQLite local es siempre la fuente de verdad. Cloud actúa como índice replicado, NO como almacenamiento primario. Si tu cloud se cae, seguís trabajando localmente sin perder nada.

El Modelo de Proyectos

Cada proyecto en Engram es un namespace totalmente aislado. Si trabajás en 10 proyectos, cada uno tiene su propia memoria, sus propias observations, sus propias sessions. No comparten nada.

El nombre del proyecto se resuelve desde el cwd del MCP server, no desde lo que el LLM diga. Si abrís Claude Code en ~/projects/foo, ese es el proyecto foo. Si abrís en ~/projects/bar, es bar. Memoria separada.


Paso 1: Crear el Repo de Despliegue

En vez de meter el docker-compose.yml directo en Dokploy, vamos a hacer un repo privado en GitHub que contenga la configuración. Dokploy lo va a clonar y deployar.

Crea un directorio nuevo:

mkdir engram-deploy && cd engram-deploy

Crea el docker-compose.yml:

services:
  postgres:
    image: postgres:16-alpine
    container_name: engram-cloud-postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
      interval: 5s
      timeout: 3s
      retries: 10
    volumes:
      - engram-cloud-pg:/var/lib/postgresql/data

  cloud:
    image: ghcr.io/gentleman-programming/engram:${ENGRAM_VERSION}
    container_name: engram-cloud
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      ENGRAM_DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable
      ENGRAM_JWT_SECRET: ${ENGRAM_JWT_SECRET}
      ENGRAM_CLOUD_TOKEN: ${ENGRAM_CLOUD_TOKEN}
      ENGRAM_CLOUD_INSECURE_NO_AUTH: '0'
      ENGRAM_CLOUD_ALLOWED_PROJECTS: ${ENGRAM_CLOUD_ALLOWED_PROJECTS}
      ENGRAM_CLOUD_HOST: 0.0.0.0
      ENGRAM_PORT: '18080'
    expose:
      - '18080'
    command: ['cloud', 'serve']

volumes:
  engram-cloud-pg:

Y un .gitignore para no commitear secretos:

.env
.env.local
*.local

Decisiones del compose explicadas:

  • Imagen oficial pre-publicada: ghcr.io/gentleman-programming/engram ya viene con el comando cloud serve como CMD por defecto. No buildeamos nada — Dokploy hace docker pull y arranca en segundos.
  • Versión pineada en ENGRAM_VERSION: nunca uses latest en producción. Si bumpeás manualmente, sabés exactamente qué cambia.
  • Postgres NO expuesto al host: sacamos el ports: mapping del compose original. La base solo es accesible desde la red interna del compose. Más seguro.
  • expose: 18080 (sin host port): dejamos que Traefik (que viene con Dokploy) agarre el servicio por la red interna y le pegue HTTPS. No exponemos puertos públicos directamente al VPS.
  • ENGRAM_CLOUD_INSECURE_NO_AUTH: '0': el compose oficial viene en '1' para desarrollo local. Asegurate de que esté en '0' para producción.

Pushea el repo a GitHub (privado):

git init -b main
git add -A
git commit -m "feat: initial engram cloud deploy compose"
gh repo create <tu-usuario>/engram-deploy --private --source=. --push

Paso 2: Generar los Secretos

Engram Cloud necesita tres secretos distintos. Cada uno con su rol:

VariableRolQuién lo ve
POSTGRES_PASSWORDPassword del usuario postgresSolo el server
ENGRAM_JWT_SECRETClave HMAC para firmar tokens internosSolo el server
ENGRAM_CLOUD_TOKENBearer token compartido (cliente lo manda en headers)Server Y cliente

Importante: cada uno tiene que tener un valor distinto. Reusar el mismo secreto para dos cosas distintas es una práctica horrible.

Generación

# POSTGRES_PASSWORD — DEBE ser URL-safe (va dentro de una URL postgres://)
openssl rand -hex 32

# ENGRAM_JWT_SECRET — solo va en env vars, base64 OK
openssl rand -base64 48

# ENGRAM_CLOUD_TOKEN — solo va en headers, base64 OK
openssl rand -base64 48

¿Por qué hex para postgres?

El password se inserta dentro de ENGRAM_DATABASE_URL. Si tiene caracteres reservados de URL (:, /, @, ?, #, +), rompe el parser y vas a ver errores cripticos como invalid port que NO tienen nada que ver con el puerto real. Hex ([0-9a-f]) es totalmente URL-safe y evita ese problema desde el inicio.


Paso 3: Crear el Servicio en Dokploy

  1. Andá a tu panel de Dokploy → Create Service → Docker Compose
  2. Nombrá el servicio (ej. engram-cloud)
  3. En Source: Git
  4. Pegá la URL de tu repo privado
  5. Branch: main
  6. Compose path: docker-compose.yml

Paso 4: Configurar las Variables de Entorno

En la pestaña Environment de tu servicio, pegá esto reemplazando los <...> con los valores que generaste:

ENGRAM_VERSION=v1.15.7
POSTGRES_USER=engram
POSTGRES_DB=engram_cloud
POSTGRES_PASSWORD=<output de openssl rand -hex 32>
ENGRAM_JWT_SECRET=<output de openssl rand -base64 48>
ENGRAM_CLOUD_TOKEN=<output de openssl rand -base64 48>
ENGRAM_CLOUD_ALLOWED_PROJECTS=personal

Sobre ENGRAM_CLOUD_ALLOWED_PROJECTS: esto es una whitelist a nivel server de qué proyectos puede aceptar el cloud. Empezá con personal o el nombre del proyecto donde vas a usar Engram. Si después querés agregar más, los sumás separados por coma y hacés redeploy:

ENGRAM_CLOUD_ALLOWED_PROJECTS=personal,blog,trabajo,experimentos

Importante: el "redeploy" en Dokploy con imagen publicada NO es buildeo + downtime largo. Solo hace docker pull (que ya está cached) y restartea el container con las env vars nuevas. 2 a 5 segundos de downtime, durante los cuales tu cliente sigue funcionando con el SQLite local sin perder nada. El sync se reanuda automáticamente cuando vuelve.


Paso 5: Configurar el Dominio

En la pestaña Domains de tu servicio:

  1. Add Domain
  2. Service Name: cloud
  3. Host: engram.tudominio.com
  4. Container Port: 18080
  5. Path: /
  6. HTTPS: habilitado (Traefik + Let's Encrypt automático)
  7. Save

Antes del deploy: asegurate de que el DNS de engram.tudominio.com ya esté apuntando a la IP de tu VPS. Si Let's Encrypt no puede validar el dominio, el deploy va a salir pero sin TLS.


Paso 6: Deploy y Verificación

Dale Deploy. En menos de un minuto deberías ver:

  • Container engram-cloud-postgres: Up (healthy)
  • Container engram-cloud: Up

Mirá los logs del container engram-cloud. Si arranca limpio vas a ver algo tipo:

cloud serve listening on 0.0.0.0:18080

Abrí https://engram.tudominio.com/dashboard/login en el browser. Pegá tu ENGRAM_CLOUD_TOKEN. Login. Listo, estás dentro del dashboard.


Paso 7: Configurar el Cliente Local

Ahora hay que apuntar tu cliente Engram local al server.

Verificá la versión del binario

engram version

Necesitás mínimo v1.15.x (las versiones anteriores no tienen comandos cloud). Si te dice engram dev o engram vdev, es una development build sin features de cloud. Reinstalá con un tag específico:

go install github.com/Gentleman-Programming/engram/cmd/engram@v1.15.7

El detalle clave: el @v1.15.7 es OBLIGATORIO. Sin tag, Go te buildea desde main como dev build sin versión. Con tag te genera el binario con la versión correcta.

Verificá que ahora sí salga la versión:

engram version
# debe decir: engram 1.15.7

engram --help | grep cloud
# debe listar el subcomando 'cloud'

Setear el token en tu shell

Agregá a tu ~/.bashrc o ~/.zshrc (lo que uses — verificalo con echo $SHELL):

export ENGRAM_CLOUD_TOKEN='<el mismo token que pusiste en Dokploy>'

Recargá la shell (source ~/.bashrc o nueva terminal).

Apuntar el cliente al server

engram cloud config --server https://engram.tudominio.com
engram cloud status

Deberías ver:

Cloud status: configured (target=cloud)
Server: https://engram.tudominio.com
Auth status: ready (token provided via runtime cloud config)
Sync readiness: ready for explicit --project sync (project must be enrolled)

Si dice Auth status: token not configured, el shell no está leyendo la env var. Verificá echo "${ENGRAM_CLOUD_TOKEN:0:6}..." (debe imprimir los primeros 6 chars).


Paso 8: Enrolar tu Primer Proyecto

cd ~/path/al/proyecto-que-querés-sincronizar
engram cloud enroll personal       # solo la primera vez
engram sync --cloud --project personal

Recargá el dashboard en https://engram.tudominio.com/dashboard. Los 0 / 0 / 0 ahora muestran números reales: el proyecto, vos como contributor, y el total de chunks sincronizados.


El Dashboard Web

Engram Cloud trae un dashboard completo. Sin necesidad de admin token, vas a poder ver:

PathPara qué sirve
/dashboardLanding
/dashboard/statsMétricas generales
/dashboard/activityActividad reciente
/dashboard/projectsLista de tus proyectos
/dashboard/projects/{name}Detalle de un proyecto: observations, sessions, prompts
/dashboard/browser/observationsNavegador de TODAS tus observations
/dashboard/browser/sessionsNavegador de sesiones
/dashboard/browser/promptsHistorial de prompts
/dashboard/contributorsQuién contribuyó qué (útil para equipos)

Si querés features admin (pausar/reanudar sync por proyecto, audit log), generá otro token con openssl rand -base64 48 y agregá ENGRAM_CLOUD_ADMIN=<token> como env var en Dokploy. Después accedés vía /dashboard/admin/*.


Solución de Problemas (Los 5 Errores Reales)

Estos son los errores que te vas a topar en el orden exacto que aparecen. Yo los tuve todos.

1. cloud auth token is required: set ENGRAM_CLOUD_TOKEN

Causa: te falta ENGRAM_CLOUD_TOKEN en las env vars del server. El compose oficial trae ENGRAM_CLOUD_INSECURE_NO_AUTH=1 por defecto (modo dev sin auth) — al pasar a producción tenés que agregar el token.

Fix: agregar ENGRAM_CLOUD_TOKEN en Environment de Dokploy y redeploy.

2. cannot parse ... invalid port ":XXXXX" after host

Causa: tu POSTGRES_PASSWORD tiene caracteres reservados de URL (:, /, +, @). El parser de la URL postgres se confunde y cree que parte del password es un puerto.

Fix: regenerar el password con openssl rand -hex 32 (alfabeto [0-9a-f], totalmente URL-safe).

3. password authentication failed for user "engram" (después de cambiar el password)

Causa: cambiaste POSTGRES_PASSWORD en Dokploy pero el volumen postgres ya estaba inicializado con el password anterior. La imagen oficial de postgres solo aplica POSTGRES_PASSWORD la PRIMERA vez que crea el data dir. Cambiar el env var después no actualiza al usuario existente.

Fix: borrar el volumen postgres y redeploy. Como el cloud nunca llegó a guardar datos tuyos, no perdés nada.

4. volume is in use al intentar docker volume rm

Causa: hiciste "Stop" en Dokploy, pero "Stop" solo detiene los containers, no los elimina. Containers stopped siguen reteniendo referencias a sus volúmenes.

Fix:

# Encontrar el container parado
docker ps -a | grep engram

# Eliminarlo (no solo stoppear)
docker rm <container-id>

# Ahora sí
docker volume rm <nombre-real-del-volumen>

Nota: el nombre real del volumen incluye un prefijo de Dokploy. Hacé docker volume ls | grep engram para ver el nombre exacto, algo tipo <projectid>_engram-cloud-pg.

Si te resulta más simple: borrar la app entera en Dokploy y recrearla. Limpia todo de un saque.

5. engram dev (cliente sin comandos cloud)

Causa: instalaste el binario con go install ...@latest o sin tag. Eso te buildea desde main como development build, que NO incluye los comandos cloud si tu Go cache tomó un commit anterior al feature.

Fix:

go install github.com/Gentleman-Programming/engram/cmd/engram@v1.15.7
goenv rehash   # solo si usás goenv
engram version  # debe decir 1.15.7, NO dev

Bonus: el shell equivocado

Si seteaste ENGRAM_CLOUD_TOKEN en ~/.zshrc pero engram cloud status sigue diciendo token not configured, verificá tu shell:

echo $SHELL

Si dice /bin/bash, .zshrc nunca se carga. Tenés que poner el export en ~/.bashrc.


Consideraciones de Seguridad

Para despliegues serios:

  1. Token rotation: si sospechás que el ENGRAM_CLOUD_TOKEN se filtró, regenerá ambos (server y client) y redeployá. Cualquiera con ese token tiene acceso de lectura/escritura a TODOS los proyectos whitelisted.
  2. Backups del volumen postgres: si es realmente importante, configurá backups del volumen engram-cloud-pg (Dokploy tiene integración con S3-compatible storage).
  3. HTTPS obligatorio: nunca uses HTTP en producción. El bearer token va en cada request — sin TLS, lo está sniffeando todo el mundo.
  4. ENGRAM_CLOUD_ALLOWED_PROJECTS como defensa adicional: incluso si te leakean el token, solo los proyectos en la whitelist pueden ser sincronizados. Mantené la lista corta y específica.
  5. No commitees secretos: el .gitignore con .env es obligatorio. Los secretos viven solo en Dokploy → Environment.

Conclusión

Ahora tenés tu propia infraestructura de memoria persistente para agentes de IA corriendo en tu VPS:

  • Imagen oficial publicada (sin builds custom)
  • HTTPS automático vía Traefik
  • Auth con bearer token + JWT
  • Postgres aislado en red interna
  • Dashboard web completo
  • Compatible con Claude Code, Cursor, OpenCode, Gemini CLI, Codex y cualquier cliente MCP

Y lo más importante: tu memoria es tuya. No depende de un servicio cloud externo. Si Engram desaparece mañana, vos seguís teniendo todo localmente en SQLite y un postgres replica en tu VPS.


Recursos Relacionados

  • Engram en GitHub
  • Documentación oficial de Engram Cloud
  • Documentación de Dokploy
  • Cómo Instalar Gemma en Dokploy
  • Self-Host Obsidian Sync con Live Sync y Traefik

Subscribe to my newsletter

Get updates on my work and projects.

We care about your data. Read our privacy policy.