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.tomldel contenedor. - Sitúa un reverse proxy con TLS delante (ver Nginx más abajo).
- Expón solo el puerto del proxy; mantén
:9000privado 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_connectionsy añade pgBouncer si tu app o el proveedor SMTP dispara conexiones cortas y frecuentes. - Tuning inicial: genera parámetros con
pgtunesegún RAM/CPU/IO; vigilashared_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.
- Docker:
- Esquema de DB
- Ejecuta
./listmonk --upgrade. Es idempotente: puedes relanzarlo sin efectos secundarios. - Siempre haz backup de Postgres antes de tocar el esquema.
- Ejecuta
- 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)
- DNS y TLS listos (
mail.example.com). curl -LOdeldocker-compose.ymloficial.- Edita credenciales y SMTP en
config.toml(monta volumen). docker compose up -d.- Reverse proxy con Nginx/Traefik; cierra
:9000al exterior. - Crea el admin en el primer acceso; configura listas y plantillas.
- 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