Skip to main content
50% de descuento todos los planes, tiempo limitado. Desde $2.48/mo
14 min restantes
Apps web y de negocio

Cómo autoalojar tu newsletter con Listmonk

C By Chike 14 min de lectura
Cómo autoalojar tu newsletter con Listmonk en un VPS: Docker Compose, relay SMTP y entregabilidad con SPF/DKIM/DMARC.

Al autoalojarlo, Listmonk corre en un VPS que ya estás pagando. El envío cuesta lo que tu relay SMTP cobre por cada mil correos. El número de suscriptores no cambia ninguna de esas dos cifras. Ese es el cambio estructural que hace que valga la pena el tiempo de configuración del autoalojamiento una vez que se te queda pequeño un plan gratuito gestionado.

Listmonk es un gestor de newsletters de código abierto, escrito en Go. Tienes suscriptores, listas y campañas sin límite por el coste de un VPS más una cuenta de relay SMTP. Una cosa debe quedar clara antes de tocar un solo comando: Listmonk se encarga de todo excepto del envío en sí. Que tu correo llegue a la bandeja de entrada o a la carpeta de spam lo determinan el relay SMTP que configures y los registros DNS que pongas en tu dominio de envío.

Lo que cubre esta guía

  • Desplegar Listmonk y PostgreSQL con Docker Compose tras un proxy inverso Nginx (o Caddy) con HTTPS
  • Elegir el relay SMTP adecuado para tu volumen y presupuesto (Amazon SES, Postmark, Brevo u otro)
  • Configurar SPF, DKIM y DMARC en tu dominio de envío
  • Evitar cuatro modos de fallo en producción que a menudo no dan errores claros
  • Tiempo estimado: 30 minutos si ya tienes un VPS y un dominio listos
  • Fuera del alcance: automatización de drip, correo transaccional, configuraciones multiinstancia (ver FAQ)

Cuándo Listmonk es la herramienta equivocada

Listmonk es la respuesta correcta para una situación concreta. Si tu situación es distinta, hay una respuesta mejor.

Volumen por debajo de unos 10K correos al mes. A esta escala, los planes gratuitos gestionados de Brevo o Mailchimp pueden salir más baratos en conjunto que un VPS más un relay SMTP. El autoalojamiento empieza a compensar cuando superas ese rango. Comprueba los números con tu recuento real de suscriptores y tu frecuencia de envío antes de desplegar.

Equipo no técnico. Mailchimp y Brevo tienen interfaces realmente mejores para quienes no trabajan en una terminal. Listmonk da por hecho que alguien del equipo sabe conectarse por SSH a un servidor, leer los logs de Docker e interpretar la propagación de DNS. Si esa persona no existe, los servicios gestionados son la elección correcta.

Necesitas flujos de automatización. Listmonk envía campañas. No admite secuencias de drip, correos disparados por comportamiento ni constructores visuales de flujos. Si necesitas eso, usa Mautic o conecta Listmonk con n8n para la capa de automatización.

Listas de suscriptores sensibles al GDPR. Si tus suscriptores están principalmente en la UE o tu lista está sujeta a las normas de residencia de datos del GDPR, ejecuta Listmonk en un centro de datos europeo. Ofrecemos ubicaciones en Fráncfort y Londres que cumplen los requisitos de residencia en la UE.

Lo que necesitas antes de empezar

Listmonk más PostgreSQL más una carga moderada de cola necesitan 2 GB de RAM como mínimo. 4 GB es el objetivo cómodo para producción.

Hardware. Para una lista personal por debajo de 50K correos al mes, basta con un VPS de 2 vCPU, 4 GB de RAM y 120 GB de almacenamiento NVMe. Las listas que crecen a 200K o más al mes necesitan 4 vCPU y 8 GB de RAM. Nosotros ejecutamos esta configuración de Compose en un VPS de 4 GB en Fráncfort. Elige una ubicación cercana a tus suscriptores si puedes. La latencia de envío importa poco; la del panel de administración sí importa.

Dominio. Un dominio apuntando a tu VPS mediante un registro A. Usa un subdominio para la interfaz de administración, por ejemplo mail.example.com. El dominio de envío y el subdominio de administración pueden ser el mismo dominio raíz.

Cuenta de relay SMTP. No crees una todavía. La elección del relay es la decisión de más peso de esta guía y depende de tu volumen. Salta a la sección «Elegir tu relay SMTP», escoge un proveedor y vuelve aquí con el host SMTP, el puerto, el usuario y la contraseña en mano.

Software en el VPS. Ubuntu 22.04 LTS o 24.04 LTS. Docker Engine 24.0 o superior con el plugin de Docker Compose. UFW o un cortafuegos equivalente con los puertos 22, 80 y 443 abiertos. Acceso SSH como usuario sudo sin privilegios de root.

Desplegar Listmonk con Docker Compose

Listmonk y PostgreSQL desplegados con Docker Compose en un VPS, tras un proxy inverso Nginx o Caddy que termina el HTTPS.

Crea un directorio para el despliegue y coloca dentro un archivo docker-compose.yml con dos servicios: postgres para la base de datos y listmonk para la aplicación. Ambos se reinician si fallan. Listmonk se enlaza a 127.0.0.1 para que el proxy inverso sea lo único que pueda alcanzarlo.

El archivo de Docker Compose

A continuación se muestra docker-compose.yml. Verifica las etiquetas exactas de las imágenes y los nombres de las variables de entorno contra los docs oficiales de instalación de Listmonk. Cambian con cada versión.

# docker-compose.yml
services:
  postgres:
    image: postgres:16-alpine
    container_name: listmonk-postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: listmonk
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: listmonk
    volumes:
      - listmonk-postgres:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U listmonk"]
      interval: 10s
      timeout: 5s
      retries: 6

  app:
    image: listmonk/listmonk:latest
    container_name: listmonk-app
    restart: unless-stopped
    # Bind to loopback only. The reverse proxy is the public entrypoint.
    ports:
      - "127.0.0.1:9000:9000"
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      LISTMONK_app__address: "0.0.0.0:9000"
      LISTMONK_db__host: postgres
      LISTMONK_db__port: 5432
      LISTMONK_db__user: listmonk
      LISTMONK_db__password: ${POSTGRES_PASSWORD}
      LISTMONK_db__database: listmonk

volumes:
  listmonk-postgres:

Crea un .env archivo con POSTGRES_PASSWORD= con un valor aleatorio largo. Luego arranca el stack y ejecuta la instalación única de la base de datos:

# Pull images and start the database first
docker compose up -d postgres

# Run the install step (creates schema and the first admin user)
docker compose run --rm app ./listmonk --install --idempotent --yes

# Start the application
docker compose up -d

El --install El comando pide un correo y una contraseña de administrador. Guárdalos. Verifica que ambos contenedores estén corriendo:

docker compose ps

Salida esperada: dos servicios listados, ambos con estado Up. La fila de postgres debería mostrar (healthy).

El 127.0.0.1:9000 El enlace a esa dirección es deliberado. Listmonk no tiene limitador de tasa de autenticación integrado ni lista de IP permitidas. Exponer el puerto 9000 a la internet pública significa que cualquiera en el planeta puede atacar tu login de administración. El proxy inverso es lo que hace que ese login sea accesible solo por HTTPS.

Proxy inverso Nginx y SSL

Instala Nginx y Certbot desde los repositorios de Ubuntu. Crea una configuración de sitio en /etc/nginx/sites-available/listmonk con las cabeceras de proxy que Listmonk necesita para generar enlaces de campaña correctos:

# /etc/nginx/sites-available/listmonk
server {
    listen 80;
    server_name mail.example.com;

    location / {
        proxy_pass http://127.0.0.1:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Listmonk streams campaign progress over WebSocket
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Crea un enlace simbólico en sites-enabled, prueba la configuración, recarga Nginx y luego emite un certificado:

sudo ln -s /etc/nginx/sites-available/listmonk /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d mail.example.com

Certbot reescribe el bloque server para que escuche en el 443 con el nuevo certificado y añade una redirección de HTTP a HTTPS. Verifica:

curl -I https://mail.example.com

Salida esperada: HTTP/2 200 con una cabecera strict-transport-security válida. Si obtienes un bucle de redirección, comprueba que la cabecera X-Forwarded-Proto esté puesta en la configuración de Nginx de arriba. Nueve de cada diez veces, el bucle es esa cabecera.

Si Listmonk es lo único en este VPS, usa Caddy en su lugar. El Caddyfile son tres líneas y gestiona la renovación de certificados sin necesidad de un cron:

mail.example.com {
    reverse_proxy 127.0.0.1:9000
}

Arreglar la cabecera Message-ID

Por defecto, Listmonk usa el hostname del sistema en la cabecera Message-ID saliente. Si el hostname de tu VPS es localhost o cualquier cosa que no sea un FQDN válido, Listmonk envía Message-ID: <[email protected]>. Los filtros de spam de Gmail y Outlook lo marcan al instante. Esto está documentado en el hilo 15410 del foro de Cloudron.

El arreglo es una sola línea en el config.tomlde Listmonk. Para una instalación nueva, genera el archivo con docker compose run --rm app ./listmonk --new-config. Luego pon:

[app]
hostname = "mail.example.com"

Reinicia el contenedor de la aplicación tras editarlo:

docker compose restart app

Hazlo antes de enviar una sola campaña. Una lista contaminada con Message-ID de tipo localhost.localdomain es más difícil de recuperar que una que empezó limpia.

Consejo Pro

Si prefieres saltarte la configuración con Compose, echa un vistazo a nuestro VPS Listmonk de un clic para desplegar Listmonk en unos minutos con un solo clic. La instancia viene preconfigurada con PostgreSQL. Aun así tienes que configurar tu relay SMTP y añadir tus registros DNS. Esos pasos no son opcionales sea cual sea la forma en que despliegues.

Elegir tu relay SMTP

Elegir un relay SMTP para Listmonk: Amazon SES, Postmark, Brevo y Mailgun comparados por estructura de coste, webhooks de rebote y mejor encaje.

Todo el envío pasa por un relay que tú configures. La reputación de IP del relay, sus límites de tasa y su gestión de rebotes son lo que determina si tu correo llega a la bandeja de entrada o a la carpeta de spam.

Aquí tienes la comparación funcional. Los precios y los límites del plan gratuito cambian. Verifica cada uno en la página oficial de precios del proveedor antes de comprometerte.

ProveedorEstructura de costeWebhooks de reboteIdeal para
Amazon SESPor correo, muy bajo a gran volumenSí, vía SNSCoste a gran volumen; ya estás en AWS
PostmarkCuota mensual base más coste por correoSí, nativoEntregabilidad primero; reputación transaccional
BrevoPlan gratuito para volumen bajo, planes de pago por encimaVolumen bajo con ruta de ampliación
MailgunPrecio por correoSin endpoint de webhook nativo; usa la API genérica de rebotes si hace falta.Familiar para desarrolladores

Eso fue solo un vistazo breve a cada relay SMTP. Ahora veremos cada uno en profundidad.

SES es la opción más barata a gran volumen y la más comentada en la comunidad de Listmonk. La configuración tiene más pasos que Postmark o Brevo, pero la diferencia de coste por correo es lo bastante grande a cualquier volumen real como para justificar el trabajo.

Configúralo en tres etapas. Primero, crea un usuario IAM con la política AmazonSESFullAccess (o una política personalizada más estricta solo con ses:SendRawEmail y ses:GetSendQuota). Segundo, verifica tu dominio de envío en la consola de SES. SES te guía por los CNAME de DKIM que hay que añadir. Tercero, genera credenciales SMTP desde el panel de ajustes SMTP de SES. Estas no son tus claves de acceso de AWS; SES genera un usuario y una contraseña SMTP específicos y separados cuando haces clic en «Create SMTP credentials».

En el panel de administración de Listmonk, en Settings → SMTP, añade un servidor nuevo con:

  • Anfitrión: email-smtp.<region>.amazonaws.com (usa la región de SES en la que verificaste el dominio)
  • Puerto: 587
  • Protocolo de autenticación: LOGIN
  • TLS: STARTTLS
  • Usuario y contraseña: las credenciales SMTP que generó SES

SES exige STARTTLS en el puerto 587. Si dejas TLS en none o eliges el puerto 465, Listmonk se conecta, SES devuelve 530 Must issue a STARTTLS command first, y la prueba de credenciales SMTP en el panel de administración puede seguir mostrando éxito. Envía un correo de prueba real a una bandeja personal que controles antes de lanzar cualquier campaña.

Las cuentas nuevas de SES empiezan en modo sandbox. En sandbox solo puedes enviar a direcciones de correo verificadas, lo cual no sirve para una lista de suscriptores. Abre un ticket de soporte desde la consola de SES para solicitar acceso a producción. La aprobación suele tardar un día laborable.

Postmark (alternativa centrada en la entregabilidad)

Postmark cuesta más por correo que SES, pero tiene soporte nativo de webhooks de rebote y fama de altas tasas de llegada a la bandeja de entrada con políticas de remitente estrictas. Merece la pena si tus newsletters son críticas para el negocio o no quieres gestionar la aprobación de sandbox a producción de SES.

La configuración en Listmonk tiene la misma forma que la de SES: host, puerto 587, STARTTLS, credenciales del panel de tokens de API del servidor de Postmark. Verifica tu dominio de envío en la configuración de firma de Postmark, añade los registros DKIM que genera Postmark, y ya estás listo para enviar.

Elige Postmark cuando la entregabilidad importe más que el coste por correo. Elige SES cuando el volumen importe más que la asistencia de la mano.

Una advertencia sobre la prueba de credenciales SMTP. La prueba de conexión en el panel de administración de Listmonk siempre informa de éxito, incluso con credenciales inválidas. Esto está documentado en unas cuantas incidencias de GitHub. No te fíes de ella. Tras configurar cualquier relay, envía una campaña a un único suscriptor de prueba y confirma la recepción en la bandeja de destino antes de enviar a toda tu lista.

Evita Mailersend para el envío masivo de campañas. Su límite de 5 correos por conexión produce errores 421 Service not available que Listmonk registra como enviados aunque la entrega haya fallado. La campaña parece exitosa en Listmonk y descarta la mayoría de sus mensajes sin avisar.

Conseguir que el correo llegue de verdad: SPF, DKIM y DMARC

Registros DNS SPF, DKIM y DMARC en el dominio de envío que permiten a los servidores de correo receptores verificar el correo de Listmonk y mantenerlo fuera del spam.

Son tres registros DNS en tu dominio de envío que indican a los servidores de correo receptores que tu dominio autorizó a este relay a enviar en tu nombre. Sáltate cualquiera de ellos y una parte significativa de tus envíos acabará en spam a gran escala, por muy limpios que sean tu relay o tu texto. Añádelos en tu proveedor de DNS antes de enviar la primera campaña.

Registro SPF

SPF autoriza a IPs o servicios de envío concretos a enviar correo por tu dominio. Añade un único registro TXT en la raíz de tu dominio de envío con el include de tu relay. Para SES el registro tiene este aspecto:

v=spf1 include:amazonses.com ~all

Para Postmark, sustituye el include por include:spf.mtasv.net. Consulta siempre la documentación oficial de SPF de tu relay para conocer el valor exacto del include. Cambia según el proveedor y a veces según la región.

Un dominio solo puede tener un registro SPF. Si ya tienes uno para otro servicio (Google Workspace, Microsoft 365), fusiona el include en el registro existente en lugar de añadir un segundo.

DKIM

DKIM adjunta una firma criptográfica a los correos salientes que los servidores receptores verifican contra una clave pública en tu DNS. Tu relay genera el par de claves. Tú añades la clave pública como un registro TXT en un subdominio selector (por ejemplo, sel1._domainkey.example.com) con el valor exacto que te da el relay.

Listmonk no se encarga de la firma DKIM. Lo hace el relay. No hay configuración DKIM específica de Listmonk. Sigue el asistente de configuración de DKIM de tu relay, añade los registros que te dé y espera a la propagación de DNS (normalmente menos de 30 minutos; a veces unas horas).

DMARC

DMARC indica a los servidores receptores qué hacer con el correo que falla las comprobaciones de SPF o DKIM. Empieza en modo de monitorización con p=none para poder ver los fallos en los informes agregados sin afectar a la entregabilidad mientras corriges las configuraciones erróneas. Añade un registro TXT en _dmarc.example.com:

v=DMARC1; p=none; rua=mailto:[email protected]

Tras dos o tres semanas de informes limpios, endurece la política a p=quarantine or p=reject. No te saltes la fase de monitorización. Un error tipográfico en tu include de SPF combinado con p=reject el primer día borrará tu propio correo legítimo sin ninguna señal de que algo fue mal.

La cabecera List-Unsubscribe (RFC 8058) la genera Listmonk automáticamente. Confirma que está activada en Settings → General. Gmail y Apple Mail muestran esta cabecera como una opción de baja con un solo clic, lo que protege la reputación del remitente.

Lo que de verdad se rompe en producción

Cuatro modos de fallo que no aparecen hasta que envías tu primera campaña real. Cázalos antes de que lo hagan tus suscriptores.

Problema 1: la tasa de rebote no coincide con la cifra de tu relay. Listmonk procesa los rebotes leyendo una dirección de correo de rebote designada por POP3 y borrando cada mensaje que lee. Eso incluye respuestas de vacaciones, acuses de recibo y avisos de ausencia, todos clasificados como rebotes. Tu relay solo cuenta los fallos de entrega genuinos devueltos por los servidores de correo de los destinatarios. Si SES informa de un 0,6% y Listmonk informa de un 4%, esta es la diferencia. El arreglo es configurar callbacks de webhook de rebote en lugar de POP3. Para SES, usa SNS para entregar las notificaciones de rebote al endpoint de webhook de Listmonk. Para Postmark, apunta su webhook nativo al mismo endpoint. Los rebotes por webhook son precisos; los rebotes por POP3 inflan las cifras.

Problema 2: la prueba de credenciales SMTP dice éxito cuando está mal. Como se señaló en la sección del relay, la prueba de conexión siempre informa de éxito independientemente de la validez de las credenciales. No te fíes de ella. Envía siempre un correo de prueba real tras configurar o cambiar cualquier ajuste SMTP.

Problema 3: una campaña se detiene a mitad de envío sin error. Listmonk marca las campañas como Finished incluso cuando solo el 60% de los suscriptores recibió el correo. Los envíos restantes fueron rechazados por el relay o limitados en la capa de red del VPS, y Listmonk no muestra ninguno de los dos como un error a nivel de campaña (hilo 13165 del foro de Cloudron). Si una campaña muestra menos envíos que suscriptores, abre el panel de tu relay para la ventana de tiempo del envío y compara el recuento aceptado del relay con el de Listmonk. La verdad está en el relay.

Problema 4: nadie está haciendo copia de seguridad de PostgreSQL. El volumen de Compose conserva los datos entre reinicios. No protege contra un fallo del host, un docker volume rm accidental o actualizaciones corruptas. Añade un pg_dump diario:

0 2 * * * docker exec listmonk-postgres pg_dump -U listmonk listmonk > /backups/listmonk-$(date +\%Y\%m\%d).sql

Ejecuta la línea una vez a mano primero. Verifica que el archivo de salida no esté vacío antes de fiarte de la entrada de cron. Un script de copia de seguridad que escribe un archivo de cero bytes sin lanzar un error es peor que no tener copia, porque dejas de pensar en ello.

Antes de fiarte de nada de esto en producción, envía una campaña de prueba a un suscriptor y confirma la recepción en la bandeja de destino. Si ese único correo llega limpio, los siguientes diez mil también lo harán.

Preguntas frecuentes

¿Por qué mis tasas de rebote en Listmonk son más altas que las que informa Amazon SES?

El procesamiento de rebotes por POP3 de Listmonk infla los recuentos al leer respuestas de ausencia y autorrespuestas de vacaciones como rebotes. Configura los callbacks de webhook SNS de SES para obtener recuentos precisos.

¿Listmonk admite correos transaccionales?

Listmonk es una herramienta de newsletters y campañas de difusión. No gestiona de forma nativa el correo transaccional (restablecimientos de contraseña, confirmaciones de pedido, correos disparados uno a uno). Para correo transaccional desde el mismo dominio de envío, configura por separado el endpoint transaccional de tu relay o usa una herramienta dedicada como Postal o la API transaccional de Postmark junto a Listmonk.

¿Cómo importo mis suscriptores de Mailchimp a Listmonk?

Exporta tu lista de Mailchimp como CSV desde Audience → Export Audience. En Listmonk, ve a Subscribers → Import y sube el CSV. Asigna las columnas de correo y nombre cuando se te pida. Listmonk acepta exportaciones CSV estándar de Mailchimp, ConvertKit y la mayoría de plataformas de newsletter sin conversión de formato.

¿Qué pasa cuando alguien se da de baja de una campaña de Listmonk?

Listmonk añade un enlace de baja a cada correo de campaña por defecto. Cuando un suscriptor hace clic en él, se le añade a la lista de bloqueo y se le elimina de todas las campañas futuras. La cabecera List-Unsubscribe (RFC 8058) se incluye automáticamente, así que los clientes de correo que admiten la baja con un solo clic (Gmail, Apple Mail) la muestran de forma nativa. El registro del suscriptor permanece en la base de datos con fines de auditoría, pero no se le enviarán más campañas.

Compartir

Más del blog

Sigue leyendo.

¿Listo para desplegar? Desde $2,48/mes.

Cloud independiente desde 2008. AMD EPYC, NVMe, 40 Gbps. Reembolso en 14 días.