Autoalojar Memos para tomar notas
Sigue esto en tu propio servidor. Empieza gratis, sin tarjeta
La mayoría de las apps de notas que valen la pena terminan pidiéndote una suscripción mensual para mantener accesibles tus propias notas, o encierran tus datos en un formato que solo su app puede leer. Memos es una pequeña alternativa de código abierto: un único binario en Go con una base de datos SQLite integrada, pensado para notas rápidas, listas y una base de conocimiento personal, que puedes ejecutar en un servidor que tú controlas. Al final de esta guía tendrás tu propia instancia de Memos corriendo en un servidor de $6/mes, accesible por HTTPS en tu propio dominio, con una rutina de respaldo y un camino de actualización que no te tomará por sorpresa.
Lo que necesitas
- Un servidor. El Basic Droplet de DigitalOcean a $6.00/mes da 1 vCPU, 1 GB de RAM y 25 GB de SSD, lo cual es más que suficiente para ejecutar Memos junto a un proxy inverso en una sola máquina. Memos es un binario en Go ligero respaldado por SQLite, no una pila de servicios, así que esto es más margen del que realmente necesita. Cualquier VPS Ubuntu 24.04 de otro proveedor funciona de la misma manera.
- Un nombre de dominio (o un subdominio de uno que ya tengas), con acceso a su configuración DNS.
- Docker y el plugin de Docker Compose instalados en el servidor (cubierto en el Paso 2).
- Una terminal y acceso SSH al servidor.
Paso 1: crear el servidor y apuntar un dominio hacia él
Levanta un droplet Ubuntu 24.04 en el plan Basic de $6/mes de DigitalOcean (1 vCPU, 1 GB de RAM, 25 GB de SSD). Anota su dirección IP pública.
En la configuración DNS de tu dominio, agrega un registro A que apunte un subdominio, por ejemplo memos.tudominio.com, hacia esa IP:
Type: A
Name: memos
Value: <la IP de tu servidor>
TTL: 300
La propagación de DNS puede tardar desde unos minutos hasta algunas horas. Deberías ver que dig memos.tudominio.com +short devuelve la IP de tu servidor antes de continuar, ya que los siguientes pasos dependen de eso.
Paso 2: instalar Docker
Conéctate por SSH al servidor e instala Docker Engine junto con el plugin de Compose:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
Cierra sesión y vuelve a entrar para que el cambio de grupo tenga efecto, luego verifica que ambas piezas estén presentes:
docker --version
docker compose version
Deberías ver una versión de Docker y una versión de Compose impresas, sin errores de “command not found”.
Paso 3: organizar el directorio del proyecto
Memos no necesita una clave de cifrado ni secretos generados de antemano, a diferencia de otras apps autoalojadas. Lo único que vale la pena mantener fuera del archivo compose es el dominio, para que Caddy pueda tomarlo:
mkdir -p ~/memos && cd ~/memos
Crea .env con tu dominio:
# .env
DOMAIN=memos.tudominio.com
Esa es toda la historia de secretos para esta configuración.
Paso 4: escribir el archivo Docker Compose
Memos viene con una base de datos SQLite integrada por defecto, que es la forma documentada y soportada de ejecutarlo para uso personal o de un equipo pequeño, no un modo de respaldo que se supone debas superar. No hay un contenedor de base de datos separado que ejecutar ni mantener sincronizado aquí.
Crea docker-compose.yml:
services:
memos:
image: neosmemo/memos:0.31.0
restart: unless-stopped
volumes:
- memos_data:/var/opt/memos
networks:
- memos-net
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
environment:
- DOMAIN=${DOMAIN}
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
depends_on:
- memos
networks:
- memos-net
networks:
memos-net:
volumes:
memos_data:
caddy_data:
caddy_config:
Algunas decisiones que vale la pena explicar:
- La imagen está fijada a
neosmemo/memos:0.31.0en lugar de la etiqueta flotantestable. Memos etiqueta sus versiones comoYY.MM.N(las versiones candidatas comoYY.MM.N-rc.K), ystablesiempre apunta a la más reciente de esas versiones, lo cual es conveniente pero significa que un simpledocker compose pullpodría moverte a otra versión sin que tú lo hayas elegido.0.31.0es la versión exacta a la que apuntastablehoy; fijarla significa que actualizas de forma deliberada, según tu propio calendario, cubierto en el Paso 8. /var/opt/memoses la única ruta dentro del contenedor donde Memos guarda todo: su base de datos SQLite y cualquier archivo que hayas subido a través de ella. Un único volumen nombrado montado ahí es toda la historia de datos de esta app, lo cual también explica por qué el paso de respaldo más adelante es tan corto.- Solo Caddy publica puertos hacia el host. Memos en sí solo es accesible en la red interna de Docker, nunca directamente desde internet.
Valida que el archivo se analice correctamente antes de continuar:
docker compose config
Esto debería imprimir la configuración completamente resuelta sin errores.
Paso 5: escribir el Caddyfile e iniciar todo
Caddy gestiona el certificado TLS de Let’s Encrypt automáticamente, siempre que el DNS ya apunte al servidor y los puertos 80 y 443 sean accesibles desde internet. Crea Caddyfile en el mismo directorio:
{$DOMAIN} {
reverse_proxy memos:5230
}
Inicia la pila:
docker compose up -d
Observa cómo arranca y verifica que Caddy realmente obtuvo un certificado:
docker compose logs -f caddy
Deberías ver una línea que mencione un certificado obtenido para tu dominio, y luego visitar https://memos.tudominio.com en un navegador debería cargar Memos con un candado válido, sin advertencia de certificado.
Paso 6: configuración del primer arranque
Memos no te pide registrarte en ningún lado ni ingresar una clave de licencia. La primera vez que visitas tu instancia, se muestra un formulario para crear directamente la primera cuenta, y esa cuenta se convierte en el host de la instancia, con derechos de administrador sobre ella. Créala ahora, con una contraseña real, ya que cualquiera que llegue a la instancia antes que tú podría reclamar esa primera cuenta en tu lugar.
Paso 7: respaldar el volumen de datos
Todo lo que Memos guarda, su base de datos y cualquier archivo subido, vive bajo la única ruta /var/opt/memos dentro del contenedor, que corresponde al volumen nombrado memos_data. Respaldar ese único volumen es toda la historia de respaldo para esta app:
docker run --rm -v memos_memos_data:/data -v $(pwd):/backup alpine \
tar czf /backup/memos-data-backup-$(date +%F).tar.gz -C /data .
Pon eso en una tarea cron y copia el resultado a algún lugar que no sea este servidor, un bucket de almacenamiento de objetos, otra máquina, cualquier lugar que no sea este droplet. Un respaldo que vive únicamente en el servidor que respalda no sobrevive al modo de falla que realmente destruye un servidor.
Paso 8: actualizar Memos
Verifica la versión que estás ejecutando actualmente, lee las notas de versión de Memos para todo lo que haya entre esa versión y la que vas a usar, luego cambia la etiqueta en docker-compose.yml una vez que hayas decidido avanzar, por ejemplo:
image: neosmemo/memos:<new-version>
Descarga y reinicia solo ese servicio:
docker compose pull memos
docker compose up -d memos
Revisa los registros para confirmar un arranque limpio:
docker compose logs -f memos
Deberías ver que Memos arranca sin errores, y que tus notas existentes siguen ahí cuando vuelves a iniciar sesión. Tu respaldo del volumen del Paso 7 es el camino de regreso si algo se ve mal.
El atajo: hacerlo con Railyard
Todo lo anterior, el contenedor único de Memos con un volumen de datos persistente y HTTPS ya configurado, también está disponible como plantilla de un clic:
https://app.railyard.run/deploy?template=memos
Esta es la misma forma de un solo contenedor que la configuración manual de esta guía: sin complemento de Postgres, sin servicio de base de datos separado, el propio motor SQLite integrado de Memos haciendo el mismo trabajo que aquí. El volumen persistente y el HTTPS ya están configurados para ti.
Si prefieres partir de Railyard en general antes de decidirte por Memos en particular, la guía de inicio rápido cubre lo básico, y bases de datos y respaldos explica cómo funcionan los respaldos en todas las plantillas, no solo esta. Botón de despliegue cubre el formato del enlace ?template= en sí, por si quieres incrustar uno en otro lugar.
El plan gratuito de Railyard cubre un servidor más un servidor de base de datos y 3 apps, sin tarjeta requerida. El plan Pro cuesta $19/mes por equipo, y el plan Team $49/mes por equipo, para límites más altos y más colaboradores.
Solución de problemas
Caddy nunca obtiene un certificado, o el navegador muestra una advertencia de certificado. Casi siempre es el DNS, no Caddy. Ejecuta dig memos.tudominio.com +short desde tu propia máquina y confirma que devuelve la IP del servidor, no una antigua, y no nada. Let’s Encrypt también necesita que el puerto 80 sea accesible desde internet para la validación inicial, así que verifica que el firewall o el grupo de seguridad de tu proveedor de nube permita tráfico entrante en 80 y 443, no solo en 443.
docker compose up falla con “port is already allocated.” Algo más en la máquina ya está vinculado al puerto 80 o 443, comúnmente una instalación por defecto de Nginx o Apache que viene con algunas imágenes base. Encuéntrala con sudo ss -tlnp | grep -E ':80|:443' y detén ese servicio.
Las notas parecen desaparecer después de un reinicio. Esto suele significar que se montó un directorio del host en lugar de un volumen nombrado de Docker para /var/opt/memos, y algo sobre esa ruta, los permisos, o un contenedor distinto reutilizando esa ruta, dejó los datos en otro lugar del que crees. Los volúmenes nombrados, como se usan en el archivo compose de arriba, evitan esto porque Docker los gestiona de forma consistente sin importar lo que haya en el sistema de archivos del host.
El contenedor arranca y luego se cierra de inmediato. Revisa docker compose logs memos para ver primero el error real. Un montaje incorrecto o faltante para /var/opt/memos, o un volumen con problemas de permisos por un cambio manual anterior, es la causa habitual. Recrear el volumen limpiamente y restaurar desde un respaldo si tienes datos reales ahí es la solución más rápida.
Preguntas frecuentes
¿Necesito Postgres o MySQL en lugar de SQLite para un equipo más grande? No. El motor SQLite integrado de Memos es la opción documentada por defecto y es la que usa esta guía. Está pensado para uso personal o un equipo pequeño, y nada en esta configuración cambia si tu equipo crece dentro de ese rango. Si estás ejecutando algo lo suficientemente grande como para que el modelo de escritura única de SQLite se convierta en un cuello de botella real, eso es una escala de despliegue distinta a la que cubre esta guía.
¿Puedo ejecutar esto sin un dominio, solo con la IP del servidor? El HTTPS automático de Caddy necesita un nombre de dominio real; Let’s Encrypt no emite certificados para direcciones IP sin más. Puedes llegar a Memos por HTTP simple en una IP para pruebas rápidas apuntando un navegador directamente al puerto 5230 del servidor, pero no te apoyes en eso para nada que pienses seguir usando.
¿Cuánto cuesta realmente ejecutar esto? El servidor cuesta $6/mes. Memos en sí es software libre y de código abierto, así que pagas por la máquina que lo ejecuta, nada más.
¿Qué exactamente se respalda en ese único volumen? Todo. La base de datos SQLite de Memos, que contiene cada nota, etiqueta y configuración, junto con cualquier archivo subido a través de la app, vive bajo /var/opt/memos. No hay un segundo almacén de datos que recordar, lo cual explica por completo por qué el Paso 7 es tan corto.
¿La plantilla de Railyard tiene la misma arquitectura que esta configuración manual? Sí. Ambas ejecutan un único contenedor de Memos con su propia base de datos SQLite integrada, sin complemento de Postgres o MySQL, y ambas conservan ese único volumen. La plantilla de Railyard usa la etiqueta flotante stable en lugar de una versión fijada, ya que un despliegue gestionado se encarga del camino de actualización por ti.
Ambos caminos te dan lo mismo al final: una app de notas sin suscripción asociada, tus datos en un solo lugar que controlas, y una factura de servidor que no cambia sin importar cuántas notas escribas.
Por qué eligen Railyard para esto
- Tu propia cuenta en la nube. Despliega en DigitalOcean, Hetzner, Vultr, AWS, OVHcloud, o cualquier servidor Linux por SSH, facturado directamente por tu proveedor, sin márgenes adicionales.
- Un precio fijo por equipo. El plan Free es gratis para siempre: un servidor más un servidor de base de datos, tres apps, sin tarjeta. Pro cuesta $19 al mes por hasta cinco servidores y apps ilimitadas. Team cuesta $49 al mes con servidores ilimitados. Sin cargos por app, por despliegue, por asiento ni por gigabyte.
- Plantillas de un clic. Despliega apps de código abierto, como bases de datos, analítica y herramientas de desarrollo, en tu propio servidor con un clic.
- Bases de datos administradas. Postgres, MySQL y Redis, con copias de seguridad programadas y verificadas por restauración, y recuperación a un punto en el tiempo.
- Despliegue con git push. Despliega desde GitHub, GitLab o la CLI, con HTTPS automático y lanzamientos sin tiempo de inactividad.