Cómo autoalojar tu newsletter con Notifuse (guía 2026)
Autoaloja Notifuse v40 en un VPS con Docker Compose o Dokploy: configuración de SECRET_KEY, la nueva licencia BSL, copias de seguridad, actualizaciones seguras y soluciones a fallos reales.
Actualizado Publicado 69 min de lectura

Notifuse ha cambiado lo suficiente en el último año como para que los pasos de la primera versión de esta guía ya no produzcan una instalación funcional. La versión actual es v40.0, publicada el 5 de septiembre de 2026. Dos cosas se movieron: la aplicación ahora toma un único SECRET_KEY en lugar de un par de claves PASETO, y el archivo Docker Compose incluido sirve la consola en el puerto 8081, no en el 8080. Si copiaste el archivo compose antiguo y obtuviste un contenedor que arrancaba bien pero nunca respondía, esa es la razón.
Esta es la guía corregida, escrita para el operador en solitario con un VPS y entre 2.000 y 50.000 suscriptores que quiere newsletter y correo transaccional sin pagar por cada correo. Cubre tres vías de despliegue, cómo verificar que cada una funciona de verdad, la operación del día a día, las copias de seguridad, actualizaciones que no te dejarán en un callejón sin salida y los fallos con los que te vas a encontrar.
Una precisión honesta antes de cualquier comando: Notifuse es la capa de aplicación, no un servicio de envío. Tú alojas la app y la base de datos. La entregabilidad la sigues alquilando a un proveedor de correo. Presupuesta ambas cosas.
Qué es Notifuse (y qué no es)
El README de Docker Hub lo dice claramente: Notifuse es la capa de aplicación, no un servicio de envío. Guarda contactos, eventos y analítica en una base de datos Postgres que tú controlas. El correo sale por tu cuenta de Amazon SES, Mailgun, Postmark, SendGrid, SparkPost, Mailjet o SMTP genérico, a lo que ese proveedor cobre por mensaje.
Esa división es la clave. Te llevas la parte cara (almacenamiento de contactos, segmentación, automatización, gestión de bajas) por el precio de un VPS pequeño, y pagas tarifas de producto básico por la parte que de verdad cuesta dinero. Amazon SES ronda los 0,10 $ por cada 1.000 correos. Mailchimp cobra por contacto, incluidos los inactivos.
Está construido en Go con una consola en React, y depende de una sola cosa: PostgreSQL 17 o superior. Sin Redis, sin ClickHouse, sin Elasticsearch, sin flota de workers. Eso importa más que la lista de funciones cuando eres la única persona de guardia, porque cada servicio extra es otro contenedor en tu presupuesto de memoria y otra cosa que puede morir a las 2 de la madrugada.
A septiembre de 2026 la imagen tiene más de 100.000 pulls y el repo unas 2,2 mil estrellas. No es un proyecto enorme, pero se publica activamente. Ya verás por qué eso corta en ambos sentidos en la sección de la licencia.
Lo que 'autoalojado' significa aquí de verdad
Alojas la app y la base de datos. La entregabilidad la sigues alquilando a un ESP. Presupuesta ambas cosas: un VPS y un proveedor SMTP/API. Si omites el ESP, tienes una base de datos de contactos muy bonita que no puede enviar nada.
Qué ha cambiado desde la primera versión de esta guía
Reescribí esto en lugar de parchearlo, porque seis de los pasos antiguos eran incorrectos. Aquí va el registro de cambios con fechas, para que los lectores que vuelven vean qué se movió:
- Licencia (v40.0, sep. 2026): v40.0 y posteriores se publican bajo la Business Source License 1.1, que pasa a AGPL-3.0-or-later cuatro años después del lanzamiento de cada versión. v39.x y anteriores siguen siendo AGPL-3.0 de forma permanente. Cinco funciones requieren una clave de licencia.
SECRET_KEYsustituyó a las claves PASETO: el antiguo parPASETO_PRIVATE_KEY/PASETO_PUBLIC_KEYy el generador de paseto.notifuse.com ya no existen. Ahora generas una única clave conopenssl rand -base64 32.- Puerto 8081: el archivo compose incluido sirve la consola en el 8081. La imagen independiente sigue usando el 8080. Confundirlos es el reporte más común de «arrancó pero la página no carga».
- La instalación ahora es
git clone+docker compose up -d: el archivo incluido compila desde el Dockerfile del repo e incluye Postgres. El archivo de 60 líneas hecho a mano de la guía antigua es ahora una variante opcional. - Automatizaciones visuales: un constructor de flujos con 10 tipos de nodo (
delay,email,branch,filter,add_to_list,remove_from_list,ab_test,webhook,list_status_branch). - Analítica web integrada sin cookies: el conjunto de funciones de Staminads se fusionó, corriendo sobre el mismo Postgres. Sin cookies, sin un segundo motor de base de datos.
- CMS de blog alojado, gestor de archivos S3, centro de preferencias, puente SMTP, inicio de sesión único OIDC: todo añadido desde el post original, todo en el mismo contenedor.
- Asistente de IA con tu propia clave: Anthropic, OpenAI o Gemini. El coste cae en tu factura de API, no en la de Notifuse.
- Zapier y claves de API con alcance limitado (v39.0): las claves de API ahora pueden limitarse a recursos concretos en lugar de dar acceso completo al espacio de trabajo.
- El guardián de migraciones (v39.0): Notifuse se niega a arrancar cuando su base de datos fue migrada por una versión más reciente, y nombra ambas versiones. Buena red de seguridad, y cambia cómo haces rollback. Ver la sección de actualizaciones.
¿Actualizas desde la versión de 2025 de esta guía?
Dos correcciones importan más que el resto. Usa SECRET_KEY, no claves PASETO. Y revisa tu puerto: 8081 para el compose incluido, 8080 para la imagen independiente. Todo lo demás del archivo compose antiguo sigue funcionando, pero no arrancará limpio sin esas dos correcciones.
Las funciones que de verdad importan para un operador en solitario
La versión antigua de este post enumeraba nueve funciones y no te decía nada. Aquí va la versión corta.
Marketing por email
- Constructor MJML de arrastrar y soltar con Liquid. Variables como
{{ contact.first_name }}y campos personalizados, con vista previa en tiempo real. Es la mayor mejora práctica frente a la edición en HTML puro de Listmonk. - Difusiones con segmentos, tests A/B y etiquetado UTM. Segmenta por campos, eventos personalizados o puntuaciones RFM, y luego haz A/B con el asunto, el contenido o la hora de envío.
- Perfiles de contacto con una línea de tiempo completa. Cada envío, apertura, clic, cambio de lista y evento de webhook en una sola vista. Esto es lo que abres cuando alguien dice que nunca recibió tu correo.
- Segmentación sin SQL. Reglas dinámicas con fechas relativas, comportamiento anidado y grupos RFM.
- Espacios de trabajo multi-inquilino con aislamiento de base de datos por espacio de trabajo. Una sola instancia sirve de verdad a varias marcas o clientes.
- Centro de preferencias y doble opt-in. Los suscriptores gestionan sus propias suscripciones y tú conservas un registro de consentimiento.
Automatizaciones y extras
- Constructor visual de flujos. Un disparador en la raíz, 10 tipos de nodo. La inscripción es
onceoevery_time, conexit_on_replyopcional. Borrador, activa o en pausa; una automatización en pausa retiene sus inscripciones en lugar de descartarlas. - API transaccional más un puente SMTP. Envía desde tu app por REST, o deja que un SaaS antiguo que solo habla SMTP retransmita por Notifuse sin cambios de código.
- Analítica propia sin cookies. Un script de unos 21 KB servido por tu propia instancia en
/na.js, que guarda las sesiones junto a tus contactos. Tablas particionadas por mes, así que expirar datos viejos es unDROP TABLE. - Gestor de archivos compatible con S3. Las imágenes de correo viven en tu bucket, servidas por CDN, en lugar de inflar el contenedor.
- Asistente de IA con tu propia clave de proveedor. El gasto en tokens es tuyo.
- Webhooks salientes firmados y, desde v39.0, claves de API con alcance limitado.
Si quieres una superficie menor y sin preguntas de licencia, Keila es la opción más ligera: Elixir, Docker, un Postgres, sin particionado de base de datos por espacio de trabajo.
La realidad de la licencia (lee esto antes de comprometerte)
Este es el cambio que más afecta a si deberías empezar.
Lo que aplica ahora: Notifuse v40.0 y todas las versiones posteriores se publican bajo la Business Source License 1.1. Cada versión pasa a AGPL-3.0-or-later cuatro años después de su publicación. v39.x y todas las anteriores siguen siendo AGPL-3.0 de forma permanente; el cambio no es retroactivo y no puede hacerse retroactivo. El SDK de analítica web sigue siendo AGPL en todas las versiones.
Lo que aún puedes hacer sin pagar: ejecutar Notifuse en producción, para un negocio, a cualquier escala. Leer, modificar y redistribuir el código fuente. Alojarlo para otras personas y cobrarles por ello, algo que la Additional Use Grant permite explícitamente.
Las cinco funciones que requieren una clave de licencia:
| Función | Autoalojado gratis (sin clave) | Con clave de licencia |
|---|---|---|
| Espacios de trabajo | Hasta 3, todos se conservan | Del 4.º espacio en adelante |
| Permisos de equipo | Solo acceso completo | Permisos restringidos / por recurso |
| Tenants de Amazon SES | Los tenants existentes siguen enviando | Aprovisionar un tenant SES nuevo |
| Traducciones de plantillas | Las traducciones guardadas siguen enviándose | Añadir un idioma, editar uno |
| Inicio de sesión único (OIDC) | Acceso mediante código de inicio de sesión | Botón SSO disponible |
Las cuatro primeras se niegan en el momento en que creas o cambias algo y responden 402, nombrando la función que falta. La quinta es más silenciosa: el botón SSO deja de ofrecerse, el log de arranque dice sso_gated=true y todo el mundo entra con un código de acceso. Instalar una clave recupera el botón sin reiniciar.
Lo que conserva una instalación sin licencia: todo. Sin bloqueo por telemetría, sin activación, sin cuenta, sin phone-home; la verificación de la clave es offline contra una firma compilada en el binario. Ningún espacio de trabajo, contacto, clave o ajuste se borra, se oculta o pasa a solo lectura. La consola nunca cae en un modo restringido. Los permisos ya concedidos siguen aplicándose exactamente como se concedieron. Los tenants SES ya aprovisionados siguen enviando. La vía de envío no contiene ninguna comprobación de licencia, así que las difusiones programadas, las automatizaciones y los webhooks siguen funcionando tras expirar una clave. Una invitación emitida con licencia sigue aceptándose después.
Instala una clave pegándola en Settings → Licence como root, o definiendo NOTIFUSE_LICENSE_KEY (la variable de entorno gana, y mientras esté definida la consola se niega a guardar un valor competidor). Una clave cubre un despliegue, es decir, una base de datos Postgres por muchos contenedores de API que ejecutes. Una clave vencida sigue otorgando durante 30 días más.
Si actualizas a v40.0+
No pierdes nada de lo que ya tienes. Una instalación con más de tres espacios de trabajo los conserva todos; simplemente no puede crear un cuarto sin una clave. Nada de lo que ya está en un conjunto de permisos restringido se amplía a acceso completo.
Sentry, HashiCorp, CockroachDB y Grafana hicieron el mismo movimiento en el momento en que su proyecto se convirtió en algo que la gente ejecuta en producción. Para un equipo pequeño el impacto práctico suele ser cero: la mayoría de operadores en solitario nunca crean un cuarto espacio de trabajo ni tocan las traducciones de plantillas ni el aislamiento de tenants SES. Si necesitas SSO o un cuarto espacio, ponle precio a la licencia frente a una alternativa gestionada y trátala como una partida más. No es una cuestión moral.
Notifuse frente a Listmonk, Keila y el SaaS que estás dejando
| Opción | Qué obtienes | Qué te cuesta |
|---|---|---|
| Notifuse (autoalojado) | Constructor MJML, automatizaciones, segmentación, analítica web, aislamiento de BD por espacio de trabajo | Tu VPS, cuenta ESP, copias de seguridad y reputación DNS |
| Listmonk | Herramienta más pequeña y afilada. Sin constructor visual. Sin ningún concepto de clave de licencia | Plantillas en HTML puro |
| Keila (Elixir, Docker) | Simple, limpia, API transaccional, soporte MJML | Menos automatizaciones y analítica; la superficie más pequeña |
| Sendy | Barato, maduro, formularios de captura de correo | Licencia de pago por adelantado, interfaz anticuada, sin MJML |
| Notifuse Cloud | El mismo software, gestionado: copias diarias con PITR, actualizaciones sin caída, monitorización, SSL | Desde 16 $/mes, escalando con contactos activos |
| Mailchimp / ConvertKit / Klaviyo | Nada que operar | Precio por contacto, tus datos en su base de datos, sin elección de ESP |
Frente al SaaS: dejas de pagar por contacto, tus datos se quedan donde están y puedes apuntar la vía de envío al proveedor más barato del año. También heredas todos los problemas de entregabilidad que Mailchimp absorbía por ti.
Frente a Listmonk: Notifuse gana en el constructor visual, el multi-inquilino nativo, las automatizaciones y la analítica web integrada. Listmonk gana en tamaño y en tener cero maquinaria de claves de licencia. Si la sección anterior te dejó mal sabor, es una razón legítima para elegir Listmonk o Keila.
Frente a Keila: la respuesta correcta más pequeña si quieres una newsletter y nada más. Un Postgres, sin proliferación de bases de datos por espacio de trabajo. Mira la guía de newsletter autoalojada con Keila para esa vía.
Si prefieres no gestionar ningún servidor, EmailOctopus es una opción barata de email marketing alojado y MailerLite es una sólida plataforma alojada de newsletter. Ninguna supera al autoalojamiento para alguien con 20.000 suscriptores y un VPS ya pagado. Son la respuesta correcta para quien no quiere ser dueño de un pg_dump.
La recomendación corta
Autoaloja Notifuse si quieres los datos y vas a hacerte cargo de las copias de seguridad y el DNS. Elige Listmonk o Keila si la licencia te molesta. Paga por Cloud si tu tiempo vale más de 16-39 $/mes. ¿Eliges primero un PaaS? Empieza con Dokploy vs Coolify vs Kamal 2.
Requisitos previos
Todo lo de abajo tiene que existir antes del paso uno. Equivocarse en esta lista es cómo una instalación de 30 minutos se convierte en una tarde entera.
- Un servidor: 2 vCPU / 2 GB de RAM / 40 GB de SSD es el mínimo para una lista pequeña. Sube a 4 GB para la analítica web integrada o varios espacios de trabajo. La imagen ocupa unos 63 MB; lo que crece es Postgres y las bases de datos por espacio de trabajo.
- Cualquier Linux con Docker Engine y Compose v2. Funcionan tanto amd64 como arm64; la imagen es multi-arch, así que un Hetzner CAX o un Oracle Ampere valen.
- Un dominio y un subdominio como
newsletter.yourdomain.com, además de poder añadir un registro A y luego registros TXT SPF/DKIM/DMARC. - Un endpoint HTTPS público. No es opcional. Los enlaces de seguimiento, las URL de baja y los webhooks salientes apuntan a tu instancia.
- Una cuenta SMTP o ESP: SES, Mailgun, Postmark, SendGrid, SparkPost, Mailjet o SMTP genérico. Necesaria para el correo del sistema (enlaces de acceso, invitaciones, restablecimientos de contraseña) antes de enviar una campaña.
- PostgreSQL 17 o superior si no usas el compose incluido, con permisos CREATE DATABASE en el usuario de BD, porque Notifuse crea una base de datos por espacio de trabajo.
- Puertos: 8080 (independiente) u 8081 (compose incluido), 443 para el proxy, opcionalmente 587/465 para el puente SMTP. Muchos proveedores de VPS bloquean el puerto 25 saliente por defecto.
Un VPS europeo de 5-8 €/mes con 2 vCPU y 2 GB es suficiente. Hetzner Cloud es mi opción por defecto, y vale la pena revisar los planes actuales de Hetzner antes de pedirlo. Hostinger es la alternativa económica. ¿Comparando proveedores? Mira DigitalOcean vs Vultr vs Hetzner. En hosts ARM, instala primero Docker y Compose en Ubuntu ARM.
Prueba Hetzner Cloud Prueba el VPS de HostingerLos precios de los VPS subieron en todos los proveedores en 2026 — si estás replanteándote una máquina alquilada, mira qué cambió y cuándo gana un mini PC.
Empieza con un nivel gratuito de SMTP para probar
El nivel gratuito de Brevo basta para demostrar que la fontanería funciona. Pásate a Amazon SES (~0,10 $/1.000 correos) o a un relay barato cuando haya una lista real encima. Mira la reseña de Mail.Baby para pago por uso, o monta un relay SMTP con ZeptoMail si quieres un solo host haciendo ambos trabajos.
¿Qué vía de despliegue elegir?
Tres vías, una decisión.
| Vía | Úsala cuando | Ojo con |
|---|---|---|
Compose incluido (git clone + up -d) |
Quieres tenerlo funcionando esta misma noche en un VPS. Incluye Postgres 17, sirve en :8081 | El puerto es 8081, no 8080. Fija la etiqueta de la imagen |
| Plantilla de Dokploy | Ya usas Dokploy y quieres SSL, DNS y una GUI | Las variables de entorno de la plantilla pueden ir por detrás de la documentación oficial |
| Imagen independiente + tu propio Postgres | Producción, la vía recomendada por el proveedor, el máximo control | El usuario de BD necesita CREATE DATABASE; DB_HOST es el host de Postgres, no localhost |
Una restricción de diseño que interiorizar ya: Notifuse está diseñado para funcionar como una sola instancia. No pongas dos réplicas de la app detrás de un balanceador de carga contra un mismo Postgres. Obtendrás entregas de webhook duplicadas y, desde v39.0, una negativa a arrancar en cuanto una réplica migre el esquema y la otra se reinicie. Escala la máquina, no el número de réplicas.
Opción 1: Docker Compose incluido (la vía más rápida)
Este es el inicio rápido oficial. Clona el repo, compila la imagen desde el Dockerfile incluido y arranca Postgres junto a ella.
1. Instala Docker Engine y Compose v2
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.shVerifica:
docker --version && docker compose versionQuieres Compose v2 (docker compose, con espacio). Si docker compose version da error, tienes el binario antiguo de v1 y todos los comandos de abajo fallarán. Instala el paquete del plugin para tu distro y vuelve a comprobar.
2. Clona y arranca el stack
git clone https://github.com/notifuse/notifuse.git
cd notifuse
docker compose up -dLa primera ejecución compila en local, así que dale unos minutos. La consola está en el puerto 8081:
docker compose ps
curl -I http://localhost:8081curl debería devolver una respuesta HTTP, ya sea un 200 o una redirección a la página de acceso. Si no devuelve nada, revisa docker compose logs -f api. La causa habitual es que Postgres aún no está healthy en una máquina de 2 GB.
Esta vía también vale para producción
La documentación la llama vía de evaluación, pero no hay nada malo en usarla en producción en un solo VPS si fijas image: notifuse/notifuse:v40.0 y haces copias de seguridad. Lo que no deberías hacer es usar latest y esperar que un pull nocturno transcurra sin incidentes.
3. Crea tu .env antes del primer arranque
Crea un .env junto a compose.yaml:
SECRET_KEY="$(openssl rand -base64 32)"
DB_PASSWORD="pick-something-long"
ROOT_EMAIL="[email protected]"
API_ENDPOINT="https://newsletter.yourdomain.com"Ejecuta tú mismo openssl rand -base64 32 y pega la salida entre comillas. Si el stack ya está arriba, otro docker compose up -d recoge el archivo. Las variables de entorno siempre prevalecen sobre lo que el asistente guardó en la base de datos, lo cual es una función hasta que es una sorpresa.
¿Un # en tu contraseña? Entrecomíllala.
En un archivo .env, un # sin comillas inicia un comentario. DB_PASSWORD=mypass#word123 se interpreta como mypass, y pasarás una hora convencido de que tus credenciales de Postgres están mal. Entrecomilla siempre:
DB_PASSWORD="mypass#word123"
SECRET_KEY="abc123#xyz789"Esto solo afecta a los archivos .env. Los valores definidos en tu shell, en Compose o en el almacén de secretos de una plataforma no tienen el problema.
Nunca cambies SECRET_KEY tras el primer arranque
SECRET_KEY cifra todos los secretos de integración del espacio de trabajo: claves API del ESP, contraseñas SMTP, todo. Cambiarla no rota nada, los destruye permanentemente. Guarda el valor en tu gestor de contraseñas en el momento en que lo crees.
4. Completa el asistente de configuración
Abre http://<ip-del-servidor>:8081 y recorre el asistente:
- Correo del administrador root: la cuenta que puede crear espacios de trabajo y entrar en System Settings.
- Endpoint de la API: la URL pública completa,
https://newsletter.yourdomain.com, no la IP. - Configuración SMTP: para el correo del sistema. Hazlo ahora aunque no vayas a enviar campañas en un mes. Sin ella no puedes recibir un correo de acceso ni de restablecimiento de contraseña.
- Contraseña de administrador, o continuar con códigos de acceso.
Varios administradores root
ROOT_EMAIL acepta una lista separada por comas o punto y coma, y se crea una cuenta por cada dirección al arrancar. La comparación distingue mayúsculas, así que [email protected] y [email protected] son dos personas distintas.
5. Ponlo detrás de TLS
La app escucha en HTTP plano en el 8081. Termina TLS con tu proxy y reenvía hacia ella.
Caddy es el que menos trabajo da. Un archivo en /etc/caddy/Caddyfile:
newsletter.yourdomain.com {
reverse_proxy 127.0.0.1:8081
}Luego sudo systemctl reload caddy. Caddy obtiene y renueva el certificado de Let’s Encrypt por sí solo. Para las etiquetas de Traefik dentro de Docker, mira Traefik como proxy inverso en Docker.
Si prefieres seguir con Nginx, la configuración antigua sigue funcionando. Cambia proxy_pass http://localhost:8080; por proxy_pass http://localhost:8081;. Ese descuido de una línea es el 502 más común de este artículo.
6. Verifica que realmente está arriba
docker compose ps
docker compose logs -f api
curl -I https://newsletter.yourdomain.comCómo se ve lo correcto: ambos contenedores Up, el log mostrando la migración de la base de datos completando sin errores, y un 200 sobre un certificado válido sin la bandera -k. Luego carga la página de acceso y ejecuta el correo de prueba del asistente. La lista completa de verificación está más abajo.
No subas .env al repo
.env guarda la contraseña de tu base de datos y la clave que cifra cada credencial de integración. Mantenlo fuera de git. Secretos en Docker Compose: qué funciona y qué no cubre las opciones con honestidad.
Opción 2: Despliega con Dokploy
Dokploy es un PaaS autoalojado que te da una GUI, SSL automático y una plantilla de Notifuse. Si ya lo usas, esta es la vía más rápida.
1. Instala Dokploy
curl -sSL https://dokploy.com/install.sh | shEl recorrido completo está en la guía de instalación de Dokploy.
2. Despliega la plantilla
- Entra en Dokploy y crea un proyecto nuevo.
- Abre Templates, busca Notifuse.
- Rellena el formulario: tu subdominio, host/puerto/usuario/contraseña SMTP, correo de administrador.
- Pulsa Deploy.
Dokploy aprovisiona PostgreSQL 17, cablea la red y emite un certificado de Let’s Encrypt.
3. DNS
Añade un registro A que apunte tu subdominio a la IP del VPS:
| Tipo | Nombre | Valor |
|---|---|---|
| A | newsletter |
la IP de tu VPS |
4. Verifica
Abre tu dominio e inicia sesión. Si la página da 502, Dokploy está proxyando al puerto equivocado. Si TLS falla, el registro aún no se ha propagado o Let’s Encrypt ya te aplicó rate-limit por intentos anteriores. Revisa los logs de Dokploy antes de reintentar.
Deriva de la plantilla
Las plantillas van por detrás de la documentación oficial. Si la plantilla de Notifuse todavía pide claves PASETO, es anterior a v40. Usa la vía manual de Compose en lugar de pelear con ella, o sobrescribe con SECRET_KEY en el panel de variables de entorno. Fija la etiqueta de la imagen (notifuse/notifuse:v40.0) en lugar de dejar latest, para que un redespliegue no pueda saltar una versión mayor. Gestionar apps compose en Dokploy se cubre en desplegar una app Docker Compose en Dokploy.
Opción 3: Contenedor independiente con tu propio PostgreSQL (producción)
La vía de producción del proveedor: la imagen publicada contra tu propio Postgres 17. Te da la historia de actualizaciones más limpia y control sobre dónde viven los datos.
La versión rápida de Docker Hub:
docker run -d --name notifuse \
-p 8080:8080 \
-e DB_HOST=your-postgres-host \
-e DB_PORT=5432 \
-e DB_USER=postgres \
-e DB_PASSWORD=your-password \
-e SECRET_KEY="$(openssl rand -base64 32)" \
notifuse/notifuse:latestPara cualquier cosa que vayas a ejecutar de verdad, mantenlo en Compose. Esta es la variante «trae tu propio Postgres», corregida para v40. La versión anterior de esta guía incluía PASETO_PRIVATE_KEY aquí, que ya no existe:
services:
notifuse:
image: notifuse/notifuse:v40.0
ports:
- '8080:8080'
environment:
DB_HOST: postgres
DB_PORT: '5432'
DB_USER: postgres
DB_PASSWORD: ${DB_PASSWORD}
SECRET_KEY: ${SECRET_KEY}
API_ENDPOINT: https://newsletter.yourdomain.com
ROOT_EMAIL: [email protected]
ENVIRONMENT: production
TELEMETRY: 'false'
CHECK_FOR_UPDATES: 'false'
volumes:
- ./data:/app/data
depends_on:
postgres:
condition: service_healthy
restart: unless-stopped
postgres:
image: postgres:17-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: postgres
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:Dos detalles hacen que esto funcione, y ambos son fáciles de meter mal:
DB_HOST: postgres, nolocalhost. Dentro de un contenedor,localhostes el contenedor. Usa el nombre del servicio, o un hostname externo si Postgres vive en otro sitio.- El usuario de BD necesita permiso para crear bases de datos. Notifuse crea una base de datos por espacio de trabajo más su propia
notifuse_system. Un usuario limitado a una sola base de datos falla al crear el espacio de trabajo con un error de permisos.
Fija tu versión
Usa notifuse/notifuse:v40.0, o la vXX.Y que hayas probado, no latest. Un docker compose pull desatendido contra latest puede saltar una versión mayor, ejecutar una migración de esquema y dejarte sin más camino de vuelta que restaurar un volcado. Ejecutar varias bases de datos PostgreSQL desde un solo servicio Docker cubre la mecánica.
Las variables de entorno que de verdad importan
El asistente cubre mucho, pero las instalaciones de producción deberían poner los valores sensibles en variables de entorno, porque las variables de entorno siempre prevalecen sobre lo guardado en la base de datos.
Obligatorias:
| Variable | Notas |
|---|---|
DB_HOST |
Host de Postgres. Nombre del servicio dentro de Compose |
DB_PORT |
5432 por defecto |
DB_USER |
Necesita permisos CREATE DATABASE |
DB_PASSWORD |
Entrecomíllala si contiene # |
SECRET_KEY |
openssl rand -base64 32. Inmutable tras el primer arranque |
Defínelas en producción:
| Variable | Notas |
|---|---|
ROOT_EMAIL |
Administrador root, o una lista separada por comas/punto y coma. Distingue mayúsculas |
API_ENDPOINT |
URL pública, usada para enlaces de seguimiento y URL de baja |
SMTP_HOST / SMTP_PORT / SMTP_USERNAME / SMTP_PASSWORD |
Correo del sistema. 587 STARTTLS, 465 TLS implícito |
SMTP_FROM_EMAIL / SMTP_FROM_NAME |
Lo que ven los destinatarios en el campo From |
SMTP_EHLO_HOSTNAME |
Para servidores SMTP que rechazan EHLO localhost |
ENVIRONMENT |
production |
TELEMETRY / CHECK_FOR_UPDATES |
Ambas por defecto en true. Ponlas en false si el phone-home saliente es una cuestión de política |
LOG_LEVEL |
info por defecto, debug cuando persigues algo |
Ajuste, conviene conocerlas antes de escalar:
| Variable | Por defecto | Por qué importa |
|---|---|---|
DB_MAX_CONNECTIONS |
100 |
Total entre todas las bases de datos |
DB_MAX_CONNECTIONS_PER_DB |
3 |
Por espacio de trabajo. Diez espacios son 30 conexiones como mínimo |
DB_CONNECTION_MAX_LIFETIME / _IDLE_TIME |
10m / 5m |
Reciclaje de conexiones |
DB_PREFIX |
notifuse |
Prefijo de tablas y base de los nombres de tus bases de datos |
TASK_SCHEDULER_ENABLED / _INTERVAL / _MAX_TASKS |
true / 30 / 10 |
Planificador de difusiones y automatizaciones. Déjalo activado |
Solo si las necesitas: SMTP_BRIDGE_*, OIDC_*, TRACING_*, NOTIFUSE_LICENSE_KEY, BROADCAST_DATA_FEED_ALLOW_PRIVATE_HOSTS.
BROADCAST_DATA_FEED_ALLOW_PRIVATE_HOSTS desactiva la protección SSRF
Poner esto en true permite a los feeds de datos de difusiones consultar direcciones privadas, de loopback y link-local. Existe para despliegues que deliberadamente traen un feed desde dentro de su propia red. Si tus feeds vienen de internet pública, déjalo en el false por defecto.
La telemetría viene activada por defecto
TELEMETRY=true y CHECK_FOR_UPDATES=true son los valores de fábrica. Con la telemetría activada, los campos reportados incluyen versión, nivel de licencia, si OIDC está habilitado, si hay RBAC personalizado en uso y si hay tenants SES configurados. Nunca una clave, una organización, un emisor o un nombre de tenant. Pon ambas en false si no quieres que eso salga de tu red.
Conecta tu proveedor de envío (y no hundas tu entregabilidad)
Hay dos vías de correo separadas en Notifuse, y confundirlas es la razón por la que la gente no puede entrar.
- Correo del sistema: enlaces de acceso, invitaciones, restablecimientos de contraseña. Se envía por la configuración SMTP del asistente. Obligatorio desde el día uno.
- Correo de campañas y transaccional: se envía por el ESP que conectas a un espacio de trabajo en sus integraciones.
Para Amazon SES, crea credenciales SMTP en la sección SMTP settings del panel de SES. No son claves de acceso IAM, y debes solicitar el acceso de producción antes de enviar a direcciones arbitrarias. Luego añade el proveedor en tu espacio de trabajo, pega las credenciales y envía una prueba.
Meter el correo en las bandejas de entrada es ahora tu trabajo:
- SPF, DKIM y DMARC en registros TXT del dominio desde el que envías. Omite DKIM y Gmail y Microsoft te castigarán en un día.
- Una dirección From coherente. Envía desde
[email protected], no desde una dirección de gmail.com en nombre de yourdomain.com. - Una rampa de calentamiento. Pasar de cero a 20.000 envíos en una noche en un dominio nuevo es cómo se fabrica un problema de reputación.
- Gestión de rebotes y quejas. SES suspende cuentas por una tasa de quejas lo bastante mala, y ningún ajuste a nivel de app arregla eso.
El puente SMTP es una función distinta. Permite a apps que solo hablan SMTP (Supabase Auth, Firebase, Auth0, scripts de cron) retransmitir por Notifuse para que obtengan tus plantillas MJML en lugar de su texto plano por defecto. Desactivado por defecto. Actívalo con SMTP_BRIDGE_ENABLED=true y elige una postura TLS:
SMTP_BRIDGE_TLS |
Puerto | Significado |
|---|---|---|
starttls |
587 | Escucha en plano, el cliente debe hacer STARTTLS antes de AUTH. Automático cuando hay certificados |
implicit |
465 | TLS desde el primer byte, para clientes sin STARTTLS |
off |
cualquiera | Sin TLS. Solo detrás de un proxy que termine TLS en una red de confianza |
En ENVIRONMENT=production el puente se niega a arrancar sin TLS salvo que pongas explícitamente SMTP_BRIDGE_TLS=off. Suministrar certificados significa codificar en base64 fullchain.pem y privkey.pem en SMTP_BRIDGE_TLS_CERT_BASE64 y SMTP_BRIDGE_TLS_KEY_BASE64, y tras cada renovación de certbot hay que recodificar y actualizar las variables de entorno.
La entregabilidad es ahora tu trabajo
Salir de Mailchimp también pone el trabajo de reputación DNS sobre tu mesa. Reserva una hora para SPF/DKIM/DMARC y unas semanas de vigilar tasas de rebotes y quejas. Si prefieres no hacerlo, Postfix con un relay SMTP externo es una vía razonable para el correo del sistema mientras arreglas el lado de campañas.
Verifica la instalación de punta a punta
Instalar no es lo mismo que funcionar. Ejecuta esto antes de apuntar una lista real hacia ella.
- Contenedores sanos:
docker compose psmuestra todo Up sin bucles de reinicio. Un contenedor reiniciándose cada 30 segundos es casi siempre un problema de conexión a la BD. - Migración completada:
docker compose logs -f apimuestra la migración del esquema terminando limpia. Errores aquí significan un Postgres incompatible o un usuario sin los grants adecuados. - HTTPS válido:
curl -I https://newsletter.yourdomain.comdevuelve 200 sin-k. Si necesitas-k, los enlaces de seguimiento se romperán en los clientes de correo. - El acceso de administrador funciona como cuenta root, y System Settings carga.
- La difusión de prueba llega: envíatela, ábrela, haz clic en un enlace, y confirma que la apertura y el clic se registraron en el informe de campaña. Prueba la vía del ESP y las redirecciones de seguimiento a la vez.
- La llamada transaccional devuelve 2xx. Mira la advertencia de abajo antes de copiar el endpoint.
- El webhook saliente dispara. Un webhook silencioso suele ser firewall o egreso DNS, no un bug.
- El correo de restablecimiento de contraseña llega. Esto prueba el SMTP del sistema, una vía completamente separada del ESP de campañas. Sáltalo y descubrirás que está roto cuando estés bloqueado fuera.
- El enlace de baja resuelve en tu dominio público, no en
localhost. Si apunta a localhost,API_ENDPOINTestá mal y estás incumpliendo.
Verifica la ruta de la API antes de lanzarla
La versión anterior de esta guía usaba POST /api/v1/send. El ejemplo publicado por el proveedor usa en cambio el estilo punteado <recurso>.<acción>. Lo que sigue es lo que el proveedor documenta públicamente, pero las claves del body y las rutas dependen de la versión. Abre la referencia de API de tu instancia (o Settings → Integrations → API) y confirma antes de cablearlo en una aplicación. No lo pegues en producción solo por mi palabra:
curl -X POST https://newsletter.yourdomain.com/api/transactional.send \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"workspace_id": "your-workspace",
"notification": {
"id": "welcome-email",
"contact": { "email": "[email protected]" },
"data": { "first_name": "Dragos" }
}
}'Dos detalles relacionados: desde v39.0 el envío transaccional requiere una clave de API con Transactional write, y los destinatarios fallidos de una difusión se conservan siete días con un botón Reintentar (broadcasts.retryFailed) en lugar de descartarse en silencio.
Si falla una comprobación de puerto, verifica desde fuera de la máquina con un chequeo TCP de verdad en lugar de ping: comprueba puertos remotos con nc.
Operarla en el día a día
Contactos y campañas
- Primero los espacios de trabajo. Todo vive dentro de uno, con su propia base de datos, integraciones y dominio. Tres sin clave de licencia; el cuarto necesita una.
- Contactos y listas. Importa por CSV o API, añade campos personalizados, construye segmentos sobre campos, eventos personalizados o puntuaciones RFM. Activa el doble opt-in para cualquier cosa que no sea una dirección tecleada a mano.
- Plantillas y difusiones. Construye en el editor MJML con variables Liquid, guarda como plantilla, programa contra un segmento. Haz A/B con el asunto, el contenido o la hora de envío, y deja que el etiquetado UTM gestione la atribución.
- Centro de preferencias y centro de notificaciones. Los suscriptores gestionan sus propias suscripciones, que es la pieza que hace soportable el papeleo del GDPR.
Automatizaciones y API
- Las automatizaciones son grafos, no listas. Un disparador en la raíz, nodos para
delay,email,branch,filter,add_to_list,remove_from_list,ab_test,webhookylist_status_branch. - Borrador, activa o en pausa. Pausar retiene las inscripciones en lugar de descartarlas. Cada inscripción registra su propio estado (
active,completed,exited,failed) más un historial por nodo. - Claves de API con alcance. Desde v39.0 puedes limitar una clave a recursos concretos. Dos trampas: el envío transaccional necesita Transactional write, y Contacts write es también lo que permite borrar contactos.
- Puente SMTP para apps antiguas. Apunta un SaaS que solo habla SMTP a tu puente y obtiene tus plantillas sin un cambio de código.
- Auth root programática para CI. Un usuario root puede autenticarse con una firma HMAC-SHA256 contra
POST /api/user.rootSigninen lugar de un código de acceso. Las marcas de tiempo deben estar a menos de 60 segundos de la hora del servidor, con límite de 5 intentos cada 5 minutos.
Analítica y extras
- Analítica web. Actívala por espacio de trabajo y pega el snippet
/na.jsen tu sitio. Sin cookies, de primera parte, mismo Postgres, con 40 reglas de atribución de canales por defecto que puedes editar y rellenar retroactivamente. - Retención por borrado de partición. Las sesiones caen en tablas mensuales como
web_sessions_y2026m08. Expirar datos viejos es unDROP TABLEsobre la partición que ya no quieres, y el disco vuelve inmediatamente. - GeoLite2 para datos geográficos. Suelta tu propio
GeoLite2-City.mmdben el directoriodata/montado (tiene precedencia) o apuntaGEOIP_DB_PATHa él. - Gestor de archivos S3 para imágenes y adjuntos de correo.
- Asistente de IA. Funciona con tu propia clave de Anthropic, OpenAI o Gemini, así que el uso cae en tu factura de API.
- Blog alojado. Con plantillas Liquid, en dominios personalizados que posee tu espacio de trabajo.
Si el lado de la analítica te molesta, desactívala por espacio de trabajo o mantén la analítica del sitio separada. Umami autoalojado y Plausible cumplen ambos sin analítica en tu stack de correo.
Lo que cuesta de verdad con 10.000 suscriptores (septiembre de 2026)
Asume 10.000 contactos, cuatro envíos al mes (40.000 correos) y Amazon SES a unos 0,10 $ por 1.000 correos. Orden de magnitud, no un presupuesto.
| Configuración | Mensual | Qué estás pagando |
|---|---|---|
| Autoalojado | 5-8 € de VPS + ~1-2 $ de SES + ~0-1 $ de almacenamiento | Una máquina de 2 vCPU / 2 GB, 40k correos, un bucket de objetos. Más tu tiempo |
| Notifuse Cloud | 16 $ / 39 $ / 99 $ / 249 $ | Lite / Starter / Pro / Business. Correos ilimitados, BYO-ESP |
| SaaS tipo Mailchimp | unas 10 veces la factura autoalojada a este tamaño | Precio por contacto, contactos inactivos incluidos |
Niveles de Cloud a septiembre de 2026: Lite 16 $/mes (2.500 contactos activos, 1 espacio de trabajo, 3 miembros de equipo), Starter 39 $/mes (10.000 activos, 5 espacios), Pro 99 $/mes (25.000 activos, 10 espacios, 10 miembros), Business 249 $/mes (50.000 activos, 20 espacios, 25 miembros). Cada plan incluye todas las funciones y correos ilimitados; los planes difieren solo en escala y retención de datos.
El modelo de facturación importa: Cloud cobra por contactos activos, definidos como cualquier contacto único con al menos un evento en los últimos 30 días (un correo enviado, un cambio de lista, una ejecución de automatización, un evento personalizado). Los contactos inactivos no cuentan. Mailchimp y Klaviyo facturan por la dirección haya abierto algo alguna vez o no. El autoalojamiento no tiene tarifa por contacto ni por correo, y por eso es barato con 10k y sigue siendo barato con 100k.
El coste oculto
Tu tiempo, SPF/DKIM/DMARC y las copias de seguridad son la verdadera partida. Si tu tarifa por hora es alta y tu lista es pequeña, Cloud a 16-39 $/mes es genuinamente más barato. Dos horas de resolución de problemas cuestan más que un año del plan Lite. La misma lógica si la alternativa que realmente comprarías es EmailOctopus sin nada que mantener.
Copias de seguridad, actualizaciones y subidas de versión que no te romperán
Esta sección decide si autoalojar fue una buena idea. Lee las tres partes antes de tocar una actualización.
Respalda lo que no puedes recrear
Notifuse crea una base de datos por espacio de trabajo más su propia base de datos del sistema, así que un único pg_dump de notifuse_system no es una copia de seguridad. Si seguiste el consejo del artículo antiguo al pie de la letra, has estado respaldando configuración y perdiendo contactos.
Este bucle vuelca todo. Ejecútalo desde el directorio del proyecto:
#!/usr/bin/env bash
# Back up every Notifuse database plus the ./data mount.
set -euo pipefail
STAMP=$(date +%F-%H%M)
OUT="/srv/backups/notifuse/$STAMP"
mkdir -p "$OUT"
DBS=$(docker compose exec -T postgres psql -U postgres -Atc \
"SELECT datname FROM pg_database
WHERE datname LIKE 'notifuse%' AND datistemplate = false;")
for db in $DBS; do
docker compose exec -T postgres pg_dump -U postgres -Fc "$db" > "$OUT/$db.dump"
done
tar czf "$OUT/data-dir.tar.gz" -C "$HOME/notifuse/data" .
echo "backed up: $DBS"El bind mount ./data guarda la base de datos GeoLite2 y cualquier recurso montado localmente, por eso va en el mismo archivo. Luego copia el directorio fuera del sitio. Bunny Storage para copias offsite e imágenes de correo cubre ambos trabajos a la vez. Una copia en el mismo disco que la base de datos es un duplicado, no un respaldo. Para versiones guiadas por configuración, copias de seguridad de Dokploy con Cloudflare R2 y copias basadas en Restic son ambas sólidas.
Haz el ensayo de restauración. Es la única prueba de que la copia funciona:
docker compose exec -T postgres createdb -U postgres notifuse_restore_test
docker compose exec -T postgres pg_restore -U postgres -d notifuse_restore_test < /srv/backups/notifuse/2026-09-14-0300/notifuse_system.dump
docker compose exec -T postgres psql -U postgres -d notifuse_restore_test -c "SELECT count(*) FROM contacts;"
docker compose exec -T postgres dropdb -U postgres notifuse_restore_testSi el conteo coincide con tu lista de contactos, tienes una vía de restauración. Si pg_restore da error por un rol o una extensión que falta, mejor ahora que durante un incidente.
Respalda antes de cada actualización — no solo de las que te asustan
Incluso una versión patch puede ejecutar una migración de esquema. Vuelca primero, actualiza después, conserva el volcado un par de semanas. El coste son unos minutos de disco; la alternativa es un postmortem de pérdida de datos.
Actualiza la app
- Fija la etiqueta de la imagen en el archivo compose (
notifuse/notifuse:v40.0). - Ejecuta la copia de seguridad de arriba.
- Lee las notas de la versión objetivo, prestando atención a los cambios de licencia y funciones.
- Descarga y reinicia:
docker compose pull
docker compose up -dEn Dokploy, Redeploy hace lo mismo, y actualizar el stack en Dokploy cubre la vía por GUI. El caso genérico es actualizar un contenedor con Docker Compose.
Luego verifica: docker compose ps, migración terminada en los logs, inicia sesión, envíate un correo de prueba. Un pull exitoso no prueba nada por sí solo.
Las trampas de actualizar (lee antes de hacer pull)
No existe la down-migration. La app migra el esquema hacia adelante y nada lo mueve hacia atrás.
Desde v39.0, Notifuse se niega a arrancar cuando su base de datos fue migrada por una versión más reciente. El log de arranque nombra ambas versiones y las dos salidas: desplegar una versión al menos tan nueva como la base de datos, o restaurar una base de datos con un sello no superior. Dos consecuencias:
- Un despliegue rolling tiene que reemplazar todas las réplicas antes de que la primera migre, porque una réplica más vieja reiniciándose después nunca volverá a levantar. Otra razón para no ejecutar varias réplicas de la app.
- Volver a una imagen anterior requiere una base de datos de antes de la actualización. Para la app, restaura el volcado previo a la actualización, luego arranca la imagen más vieja.
Actualizar el propio Postgres es un proyecto aparte. El compose incluido se queda deliberadamente en Postgres 17, porque pasar a 18 necesita pg_upgrade y la 18 cambió el diseño de su directorio de datos. Eso es un problema de Postgres, no de Notifuse, y merece su propia ventana de mantenimiento.
Una clave de licencia expirada o eliminada no detiene el envío. Pone en gris las cinco funciones limitadas y deja la vía de envío intacta.
No existe la down-migration
Vuelve atrás la imagen sin restaurar la base de datos y la app se negará a arrancar, por diseño. La base de datos es la fuente de verdad, no el contenedor. Restaura primero los datos, luego la imagen.
Resolución de problemas: los fallos con los que de verdad te vas a encontrar
Los dos errores destructivos
Cambiar SECRET_KEY tras el primer arranque destruye permanentemente todas las credenciales de integración guardadas. Actualizar sin un volcado reciente te deja sin camino de rollback, porque no hay down-migration. Ambos se evitan en menos de un minuto de trabajo.
| Síntoma | Causa | Solución |
|---|---|---|
| El contenedor sale, los logs muestran conexión a BD rechazada | DB_HOST=localhost en lugar del nombre del servicio Postgres, o Postgres aún no está healthy |
Pon DB_HOST al nombre del servicio o hostname real, y mantén depends_on: condition: service_healthy |
| La creación del espacio de trabajo falla, permiso denegado | El usuario de BD no puede hacer CREATE DATABASE |
Concede CREATEDB; Notifuse necesita una base de datos por espacio de trabajo |
| Credenciales SMTP «incorrectas» pero son correctas | Un # en la contraseña fue truncado por el parseo del .env |
Entrecomilla el valor: SMTP_PASSWORD="pa#ss" |
| El correo de restablecimiento de contraseña nunca llega | SMTP del sistema sin configurar o mal configurado; una vía distinta del ESP de campañas | Configura SMTP_* y prueba un restablecimiento real |
| Puerto ya asignado en 8080/8081 | Otra cosa posee el puerto | Revisa ss -ltnp y re-mapea. El compose incluido usa 8081 |
| El puente SMTP no arranca en producción | El puente rechaza el arranque sin TLS | Proporciona los valores base64 de cert/clave, o pon SMTP_BRIDGE_TLS=off detrás de un proxy que termine TLS |
| «database has been migrated by a newer build» | Volviste atrás la imagen pero no la base de datos | Restaura el volcado previo a la actualización, luego arranca la imagen más vieja |
| 502 desde el proxy inverso | Puerto upstream equivocado, o la app ligada a 127.0.0.1 en el contenedor |
Apunta el proxy a 8081 (incluido) u 8080 (independiente), liga en 0.0.0.0 |
Errores de permisos en el ./data montado |
Desajuste de UID/GID en el bind mount | Iguala la propiedad con el usuario del contenedor, o usa un volumen con nombre |
| Respuestas 402 que nombran una función | Una función limitada por licencia | 4.º espacio de trabajo, permisos restringidos, nuevo tenant SES, autoría de traducciones, o SSO |
| Las campañas se envían pero caen en spam | Faltan SPF/DKIM/DMARC, o no hubo calentamiento | Arregla primero los registros DNS, el calentamiento después |
Si un puerto parece abierto en local pero no es alcanzable desde fuera, comprueba si Docker está saltándose las reglas de tu firewall: Docker se salta UFW explica el comportamiento de iptables y la solución.
Endurecimiento y notas de producción
Lista corta, y todo lo que hay en ella sostiene peso.
- Nunca expongas Postgres. Nada de
5432en la lista blanca de tu firewall, nada de mapeo de puertos al host. La app es el único cliente. - Firewall, y luego la advertencia de Docker. UFW o firewalld más la conciencia de que Docker escribe sus propias reglas de iptables. Mira el análisis del informe BSI de Hetzner y Docker se salta el firewall.
- Los secretos fuera del repo. Mantén
.envfuera de git; usa secretos de Docker o el almacén de tu plataforma.SECRET_KEYse escribe una sola vez. - Límites de recursos. Acota
mem_limity CPU para que una difusión desbocada no pueda agotar la memoria de la máquina. Recuerda queDB_MAX_CONNECTIONSes 100 en total yDB_MAX_CONNECTIONS_PER_DBes 3; haz esa aritmética antes de crear diez espacios de trabajo. - Monitorización. Un chequeo de uptime en el endpoint público más métricas de contenedores. Beszel y Uptime Kuma cubren ambos, y la monitorización de recursos Docker responde al «por qué está lleno el disco».
- Fail2ban o CrowdSec delante del proxy: asegurar un VPS con CrowdSec.
- Actualizaciones. Fija etiquetas, vigila los releases de GitHub, suscríbete a las notificaciones de versiones para que un parche de seguridad no se pase tres semanas sin leer.
- Privacidad.
TELEMETRY=falseyCHECK_FOR_UPDATES=falsesi la política lo exige. La retención de datos es decisión tuya, y el truco del borrado de particiones hace barato aplicarla.
Cuándo autoalojar Notifuse es una mala decisión
Tres casos en los que te diría que no te molestes.
Tu lista es diminuta y no crece. Por debajo de unos pocos cientos de suscriptores, un nivel gratuito alojado es menos trabajo que cualquier opción autoalojada, y el precio por contacto aún no ha empezado a morder. Usa un plan gratis y revisa esto dentro de un año.
No tienes apetito por DNS, entregabilidad ni pg_dump. Notifuse Cloud ejecuta el mismo software desde 16 $/mes. Si prefieres no ser dueño de una rutina de copias de Postgres ni depurar registros DKIM, pagar a alguien es racional, no una capitulación. Autoalojar solo es más barato si tu tiempo es gratis.
Necesitas un cuarto espacio de trabajo o SSO y no vas a comprar una clave. Entonces elige Keila o Listmonk, ninguno de los cuales tiene concepto de clave de licencia. Ejecutar software cuyos términos de licencia resentías es una mala base para un proceso de negocio.
Si caes en el primer o segundo saco, MailerLite es una sólida plataforma alojada de newsletter y Sender tiene un plan gratis para siempre que vale la pena valorar contra tu tamaño de lista.
Sigue siendo la opción más barata si tienes el tiempo
Para un operador en solitario con una lista real, desde 5.000 suscriptores en adelante, autoalojar sigue siendo la respuesta correcta más barata, normalmente por un orden de magnitud. Esta sección existe para que nadie empiece en el sitio equivocado y abandone dos semanas después con el correo en la carpeta de spam de todo el mundo.
Preguntas frecuentes
¿Notifuse sigue siendo gratis?
Sí, autoalojarlo es gratis. v40.0 y posteriores se publican bajo la Business Source License 1.1, que pasa a AGPL-3.0-or-later cuatro años después del lanzamiento de cada versión. v39.x y anteriores siguen siendo AGPL-3.0 de forma permanente. Puedes ejecutarlo en producción, para un negocio, a cualquier escala, y alojarlo para otras personas y cobrarles. Cinco funciones necesitan una clave de licencia; la vía de envío nunca.
¿Qué necesita exactamente una clave de licencia?
Cinco cosas: crear un cuarto espacio de trabajo, otorgar permisos que no sean acceso completo, aprovisionar un nuevo tenant de Amazon SES, añadir o editar una traducción de plantilla, y el inicio de sesión único. Las cuatro primeras responden HTTP 402 nombrando la función que falta. SSO es más silencioso: el botón deja de ofrecerse y el log de arranque dice sso_gated=true. Nada de lo que ya tienes te es quitado.
¿Puedo migrar desde Mailchimp?
Sí. Exporta los contactos como CSV, impórtalos en un espacio de trabajo, mapea tus campos personalizados. El coste real son las plantillas: hay que reconstruirlas en el editor MJML, y una exportación de Mailchimp no trae reglas de segmentación ni lógica de automatización. Reserva unas horas para una lista real.
¿Puedo migrar desde Listmonk?
Los contactos pasan como CSV. No hay un importador oficial de Listmonk al que pueda señalarte, así que espera importar contactos por CSV y reconstruir plantillas y listas a mano. Keila es la tercera opción en esa clase de tamaño si estás comparando proyectos.
¿Hay límite de envío?
Notifuse no impone ninguno. Tu límite es lo que permita tu cuenta ESP: cuotas de envío de SES, límites de tasa de Mailgun, el plan de tu proveedor. A unos 0,10 $ por 1.000 correos en Amazon SES, el volumen rara vez es la parte cara de este stack.
¿Necesito un desarrollador?
La instalación necesita soltura básica con Linux y Docker: SSH, un archivo compose, registros DNS, un proxy inverso. El uso diario (campañas, segmentos, automatizaciones) es apuntar y hacer clic. El trabajo continuo con sabor a desarrollador son las copias de seguridad y las actualizaciones, y este artículo te da scripts para ambas.
¿Puede enviar correo transaccional?
Sí, de dos maneras: una API REST para envíos disparados por la app, y un puente SMTP para que una app existente que solo habla SMTP retransmita por Notifuse sin cambios de código. Ambas necesitan una clave de API correctamente limitada o un permiso otorgado, y el puente necesita TLS en producción.
¿Necesita Redis, ClickHouse o Elasticsearch?
No. Una base de datos Postgres 17, más una base de datos por espacio de trabajo. Esa es la lista completa de dependencias, y por eso corre cómodo en un VPS de 2 GB y por eso no hay ningún servicio extra que monitorizar.
¿Funciona en ARM (Hetzner CAX, Oracle Ampere)?
Sí. La imagen publicada es multi-arch, linux/amd64 y linux/arm64. En una máquina ARM nueva, instala Docker y Compose primero: Docker en Ubuntu ARM.
¿Cómo actualizo de forma segura?
Respalda cada base de datos de cada espacio de trabajo y el mount ./data, lee las notas de la versión, fija la etiqueta de la imagen, luego docker compose pull && docker compose up -d (o Redeploy en Dokploy). Después verifica que la migración completó y envía un correo de prueba. No hay down-migration, así que el único camino de rollback es restaurar el volcado previo a la actualización.
Puntos clave
- Notifuse v40 es la capa de aplicación, no un servicio de envío. Trae tu propio ESP y presupuesta un VPS más ese proveedor.
- La licencia cambió en septiembre de 2026. v40.0+ es BSL 1.1, pasando a AGPL cuatro años después de cada versión; v39.x y anteriores siguen siendo AGPL permanentemente. Cinco funciones necesitan una clave.
- La instalación es un clone y un comando compose, consola en el puerto 8081, un
SECRET_KEYdeopenssl rand -base64 32que nunca vuelves a cambiar. - Respalda cada base de datos de cada espacio de trabajo. Un único volcado de
notifuse_systemno es una copia de seguridad, y no hay down-migration que te salve. - 10k suscriptores cuestan dólares de un solo dígito al mes más tu tiempo. Cloud empieza en 16 $/mes si prefieres no ser dueño de la operación.
- Verifica antes de confiar: difusión de prueba, llamada transaccional, webhook, restablecimiento de contraseña, enlace de baja. Una instalación que responde por HTTPS casi no ha probado nada.
¿Quieres verlo antes de instalar? La demo en vivo del proveedor ejecuta la consola completa, y la documentación de autoalojamiento es la fuente primaria de cada variable de entorno aquí. ¿Aún decidiendo la plataforma? Empieza con la guía de instalación de Dokploy; se paga sola la segunda vez que despliegas algo.


