listmonk para sysadmins: despliegue, operación y buenas prácticas de un gestor de newsletters self-hosted y de alto rendimiento

listmonk es un gestor de newsletters y listas de correo auto-alojado, escrito en Go, con PostgreSQL como base de datos y empaquetado en un único binario. Es rápido, sencillo de operar y trae un panel web moderno para campañas, listas y suscriptores. Para equipos de sistemas es especialmente atractivo: menos piezas, más control y coste predecible frente a SaaS.

Este artículo resume cómo ponerlo en producción, cómo mantenerlo, y qué decisiones de arquitectura conviene tomar alrededor (reverse proxy, backups, upgrades, seguridad, escalabilidad).


1) Modelo de arquitectura

  • Aplicación: binario listmonk (API + UI). Stateless por diseño: puedes ejecutar más réplicas detrás de un balanceador si lo necesitas.
  • Datos: PostgreSQL es el único estado duro (suscriptores, listas, campañas, logs).
  • SMTP: listmonk envía correo a través de tu MTA o proveedor SMTP (configúralo en config.toml).
  • Infra recomendada: reverse proxy TLS (Nginx/Traefik), almacenamiento persistente para Postgres, monitoring y backups.

Licencia: AGPLv3. Tenlo en cuenta si vas a redistribuir modificaciones.


2) Quick start con Docker (recomendado)

El proyecto publica una imagen oficial y un docker-compose.yml de ejemplo:

# 1) Trae el compose oficial
curl -LO https://raw.githubusercontent.com/knadh/listmonk/master/docker-compose.yml

# 2) Levanta los servicios
docker compose up -d

# 3) Accede al panel
open http://localhost:9000
Lenguaje del código: PHP (php)

Consejos de producción

  • Declara volúmenes para persistir PostgreSQL y (si lo personalizas) la carpeta de config.toml del contenedor.
  • Sitúa un reverse proxy con TLS delante (ver Nginx más abajo).
  • Expón solo el puerto del proxy; mantén :9000 privado en la red de containers.
  • Revisa y ajusta los recursos del contenedor (memoria/CPU, ulimits).
  • Para upgrades: docker compose pull && docker compose up -d + listmonk --upgrade (ver §6).

3) Instalación nativa (binario + systemd)

Cuando prefieras no usar Docker:

# 1) Descarga el release para tu arquitectura
# https://github.com/knadh/listmonk/releases
tar -xzf listmonk_<ver>_linux_amd64.tar.gz -C /opt/listmonk/

# 2) Genera configuración
cd /opt/listmonk
./listmonk --new-config        # crea config.toml -> edítalo (DB, SMTP, base_url, etc.)

# 3) Inicializa (o actualiza) el esquema de PostgreSQL
./listmonk --install           # o --upgrade

# 4) Arranca
./listmonk
# Panel: http://localhost:9000
Lenguaje del código: PHP (php)

Unit de systemd (ejemplo mínimo):

[Unit]
Description=listmonk newsletter service
After=network-online.target postgresql.service
Wants=network-online.target

[Service]
User=listmonk
Group=listmonk
WorkingDirectory=/opt/listmonk
ExecStart=/opt/listmonk/listmonk --config /etc/listmonk/config.toml
Restart=on-failure
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
Lenguaje del código: JavaScript (javascript)

4) Reverse proxy y TLS (Nginx)

server {
  listen 80;
  server_name mail.example.com;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  server_name mail.example.com;

  ssl_certificate     /etc/letsencrypt/live/mail.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/mail.example.com/privkey.pem;

  location / {
    proxy_set_header Host              $host;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_pass http://127.0.0.1:9000;
    proxy_read_timeout  120s;
  }
}
Lenguaje del código: PHP (php)

Ajusta base_url en config.toml a https://mail.example.com.


5) PostgreSQL: preparación y tuning básico

listmonk realiza inserciones y selects intensivos (suscriptores, envíos, eventos). Asegúrate de que la base está sana:

  • Versiones: usa PostgreSQL 14+ (o la que recomiende tu distribución).
  • Conexiones: limita max_connections y añade pgBouncer si tu app o el proveedor SMTP dispara conexiones cortas y frecuentes.
  • Tuning inicial: genera parámetros con pgtune según RAM/CPU/IO; vigila shared_buffers, work_mem, max_wal_size, checkpoint_timeout.
  • Mantenimiento: habilita autovacuum, métricas y alerts de bloat/lag.

6) Ciclo de actualización seguro

  • Aplicación
    • Docker: docker compose pull && docker compose up -d.
    • Binario: sustituye el ejecutable por el nuevo release.
  • Esquema de DB
    • Ejecuta ./listmonk --upgrade. Es idempotente: puedes relanzarlo sin efectos secundarios.
    • Siempre haz backup de Postgres antes de tocar el esquema.
  • Rollback
    • Conserva el binario anterior.
    • Si el upgrade de DB incluyó migraciones, confirma en release notes si existe down migration (en general no). Ante fallos, restaura el backup.

7) Backups y restauración

Ejemplo con PostgreSQL (off-host)

# Backup (binario comprimido)
PGHOST=db.internal PGUSER=listmonk PGPASSWORD=*** \
  pg_dump -Fc -d listmonk > /backups/listmonk_$(date +%F).dump

# Restore
createdb -U postgres listmonk_restore
pg_restore -U postgres -d listmonk_restore /backups/listmonk_2025-11-01.dump
Lenguaje del código: PHP (php)

Automatiza con systemd timers o tu herramienta de backup corporativa; replica los ficheros a almacenamiento externo y prueba la restauración periódicamente.


8) Entregabilidad: DNS y SMTP

Aunque listmonk es el gestor, la entrega depende del MTA/proveedor:

  • Configura SPF, DKIM y DMARC para tu dominio.
  • Usa SMTP de un proveedor con buena reputación (o tu propio Postfix/Exim si gestionas la IP).
  • Controla rate limits del proveedor (throttling) y ajusta la concurrencia de envío acorde.
  • Revisa los bounces y que tu política de listas respete opt-in y bajas (unsubscribe claro).

La configuración SMTP y opciones de la app se gestionan en config.toml. Consulta la documentación de listmonk para los campos exactos y soporte de proveedores.


9) Operación diaria y observabilidad

  • Logs: centraliza stdout/stderr (journald, Loki/ELK).
  • Métricas: monitoriza PostgreSQL (Prometheus + postgres_exporter) y el reverse proxy.
  • Alertas: uptime del panel :9000, colas de envío (si aplica), latencias, errores 5xx/4xx, disk usage del clúster.
  • Capacity planning: vigila CPU/RAM del binario y del DB, IOPS y tamaño de tablas (suscriptores/eventos crecen).

10) Escalabilidad

  • Aplicación: al ser un binario stateless, puedes correr N instancias detrás de un LB (Nginx/HAProxy/Traefik) para aumentar concurrencia o aislar tareas de envío del panel.
  • Base de datos: escalar verticalmente y optimizar; para cargas de lectura pesadas, añade réplicas read-only. Sharding solo si se justifica: incrementa la complejidad de operaciones (borrados, reportes, joins).
  • Colas/Jobs: si programáis envíos masivos, calendariza fuera de horas pico y respeta límites del MTA.

11) Seguridad

  • TLS obligatorio en el proxy; HSTS si aplica.
  • Acceso al panel: restringe por VPN/IP allowlist si el riesgo lo amerita.
  • Credenciales: variables de entorno o secret stores; sin secretos en repos.
  • PostgreSQL: usuarios con mínimos privilegios; cifrado en tránsito (hostssl) y backups cifrados.
  • Actualizaciones: sigue de cerca releases de listmonk y parches de Go/PostgreSQL.

12) Procedimiento de clean install resumido (Docker)

  1. DNS y TLS listos (mail.example.com).
  2. curl -LO del docker-compose.yml oficial.
  3. Edita credenciales y SMTP en config.toml (monta volumen).
  4. docker compose up -d.
  5. Reverse proxy con Nginx/Traefik; cierra :9000 al exterior.
  6. Crea el admin en el primer acceso; configura listas y plantillas.
  7. Backups + monitoring desde el día 0.

FAQ de operación

¿Puedo migrar a otro host sin perder datos?
Sí. listmonk es stateless; migra PostgreSQL y el config.toml. Si usas Docker, mueve también los volúmenes. Actualiza base_url si cambia el FQDN.

¿Cómo actualizo el esquema sin “ventana” larga?
Prepara un snapshot/backup; descarga el nuevo binario/imagen; ejecuta --upgrade (es idempotente). Programa una breve ventana y valida smoke tests.

¿Qué pasa si envío millones de correos?
La app está pensada para alto rendimiento, pero el límite real suele ser el MTA/SMTP y la DB. Usa rate-limits del proveedor, escala la app horizontalmente y dimensiona PostgreSQL (I/O, WAL, checkpoint).

¿Puedo ponerlo detrás de un SSO corporativo?
Ponlo tras tu reverse proxy con OIDC/SAML si tu organización lo exige (por ejemplo, oauth2-proxy delante de :9000). Mantén usuarios locales como break-glass.


Conclusión

Escalar y operar un gestor de correo propio no tiene por qué ser un dolor. listmonk reduce el problema a un binario + PostgreSQL, con buen rendimiento y una superficie operativa sencilla. Como en cualquier sistema de producción, el éxito está en los básicos: TLS, backups, monitoreo, upgrades probados, y una arquitectura que puedas explicar en una pizarra. Empieza pequeño, mide, y añade complejidad solo cuando los números lo pidan.

fuente: Listmonk

Suscríbete al boletín SysAdmin

Este es tu recurso para las últimas noticias y consejos sobre administración de sistemas, Linux, Windows, cloud computing, seguridad de la nube, etc. Lo enviamos 2 días a la semana.

¡Apúntate a nuestro newsletter!


– patrocinadores –

Noticias destacadas

– patrocinadores –

¡SUSCRÍBETE AL BOLETÍN
DE LOS SYSADMINS!

Scroll al inicio
×