bolt Valebyte VPS desde $4/mes — NVMe, despliegue en 60s.

Obtener VPS arrow_forward
eco Principiante Tutorial/Cómo hacer

Despliegue de Listmon

calendar_month Jun 26, 2026 schedule 22 min de lectura visibility 16 vistas
Развёртывание Listmonk на VPS: Управление рассылками с Docker, PostgreSQL и Caddy
info

¿Necesitas un servidor para esta guía? Ofrecemos servidores dedicados y VPS en más de 50 países con configuración instantánea.

¿Necesitas un VPS para esta guía?

Explore otras opciones de servidores dedicados en

Despliegue de Listmonk en un VPS: Gestión de envíos de correo con Docker, PostgreSQL y Caddy

TL;DR

En esta guía detallada, configuraremos paso a paso Listmonk, una potente plataforma de código abierto para envíos de correo electrónico, en su propio servidor VPS. Utilizando Docker para la contenerización, PostgreSQL para la base de datos y Caddy como proxy inverso con HTTPS automático, obtendrá una solución totalmente controlada, escalable y segura para gestionar suscriptores y enviar campañas, evitando la dependencia de servicios de terceros y sus limitaciones.

  • Configuración de Listmonk, PostgreSQL y Caddy utilizando Docker Compose para facilitar el despliegue y la gestión.
  • Obtención y renovación automática de certificados SSL con Caddy.
  • Garantía de seguridad básica del servidor (SSH, firewall, Fail2ban).
  • Recomendaciones para elegir la configuración óptima del VPS y estrategias de copia de seguridad.
  • Comandos prácticos y archivos de configuración para cada etapa de la instalación.
  • Sección detallada sobre la resolución de problemas comunes y respuestas a preguntas frecuentes.

Qué configuramos y por qué

Схема: Что мы настраиваем и зачем
Diagrama: Qué configuramos y por qué

En esta guía nos centraremos en el despliegue de Listmonk, una plataforma moderna, de alto rendimiento y multifuncional para la gestión de envíos de correo electrónico. Listmonk es una excelente alternativa a las soluciones comerciales SaaS, como Mailchimp o SendGrid, ofreciendo control total sobre sus datos y envíos sin una tarifa mensual por el número de suscriptores o correos enviados (solo paga por el servicio SMTP y el VPS).

Qué obtendrá el lector al final:

  • Un sistema completamente funcional para crear y enviar campañas de correo electrónico.
  • La capacidad de importar y gestionar listas de suscriptores.
  • Herramientas para la segmentación de la audiencia y la personalización de correos.
  • Análisis detallado de aperturas, clics y bajas.
  • Una solución robusta que funciona en contenedores Docker, con una base de datos PostgreSQL y un proxy inverso Caddy que proporciona HTTPS automático.
  • Su propio servidor de envíos de correo, que puede escalar y personalizar según sus necesidades únicas, sin preocuparse por las políticas de uso de servicios de terceros.

Qué alternativas existen y por qué autoalojado en un VPS:

Existen numerosas soluciones de marketing por correo electrónico en el mercado. Se pueden dividir en dos categorías principales:

  • Servicios gestionados en la nube (SaaS): Mailchimp, SendGrid, Brevo (Sendinblue), MailerLite, Constant Contact.
    • Ventajas: Facilidad de uso, no se requiere experiencia técnica, infraestructura lista.
    • Desventajas: Alto costo con el crecimiento de la base de suscriptores, dependencia de la política del servicio (bloqueos de cuentas, restricciones de contenido), falta de control total sobre los datos, imposibilidad de personalización profunda.
  • Soluciones autoalojadas: Listmonk, Mautic, Ghost (con integración de envíos), Postfix/Dovecot (para el servidor de correo).
    • Ventajas: Control total sobre los datos y la infraestructura, sin restricciones en el número de suscriptores, flexibilidad en la configuración e integración, costo potencialmente más bajo a largo plazo, mayor privacidad.
    • Desventajas: Se requiere experiencia técnica para la instalación y el mantenimiento, la responsabilidad de la seguridad y el funcionamiento recae en usted.

La elección de una solución autoalojada en un VPS, como Listmonk, es ideal para desarrolladores, startups, pequeñas y medianas empresas, así como para cualquiera que valore la independencia, el control y la confidencialidad. Esto permite crear un potente sistema de envíos de correo que se adaptará completamente a sus requisitos y crecerá con su proyecto.

Qué configuración de VPS se necesita para esta tarea

Схема: Какой VPS-конфиг нужен под эту задачу
Diagrama: Qué configuración de VPS se necesita para esta tarea

La elección de una configuración de VPS adecuada es crucial para el funcionamiento estable y eficiente de Listmonk. Aunque Listmonk es bastante ligero, PostgreSQL puede ser exigente en cuanto a recursos con grandes volúmenes de datos y alta carga. Caddy y Docker por sí mismos consumen recursos mínimos, pero deben tenerse en cuenta.

Requisitos mínimos:

  • CPU: 2 vCPU. Uno para Listmonk, uno para PostgreSQL y el resto del sistema.
  • RAM: 4 GB. PostgreSQL prefiere RAM para el almacenamiento en caché, y Listmonk funcionará de manera más cómoda.
  • Disco: 50 GB SSD. El SSD acelera significativamente el funcionamiento de la base de datos. Esto será suficiente para el sistema operativo, las imágenes de Docker, los datos de Listmonk y PostgreSQL (para decenas de miles de suscriptores y miles de correos enviados).
  • Red: 100 Mbps. Para la mayoría de las tareas, esto es suficiente. Más importante es la estabilidad y la ausencia de límites de tráfico.

Plan de VPS específico para la tarea:

Para un inicio cómodo y el soporte de varios cientos de miles de suscriptores con envíos regulares, se recomienda considerar el siguiente plan de configuración:

  • CPU: 2-4 vCPU (por ejemplo, Intel Xeon E5 o AMD EPYC).
  • RAM: 4-8 GB DDR4.
  • Disco: 80-160 GB NVMe SSD (NVMe es preferible por su velocidad, pero un buen SATA SSD también servirá).
  • Red: Puerto de 1 Gbps con tráfico ilimitado o un límite alto (por ejemplo, 1-2 TB/mes).
  • Sistema operativo: Ubuntu Server 24.04 LTS (o una versión estable más reciente).

Puede adquirir un VPS con las características indicadas para empezar o considerar opciones más potentes a medida que crezcan sus necesidades.

Cuándo se necesita un dedicado, no un VPS:

Debe considerar un servidor dedicado si tiene:

  • Millones de suscriptores: PostgreSQL requerirá significativamente más recursos de CPU y RAM, así como discos de alta velocidad.
  • Frecuencia de envíos muy alta: El envío de millones de correos por hora requiere un subsistema de red estable y potente, así como recursos dedicados para el servicio SMTP.
  • Requisitos elevados de aislamiento y seguridad: Un servidor dedicado proporciona un aislamiento físico completo de otros usuarios.
  • Necesidad de hardware específico: Por ejemplo, para cálculos de GPU o arreglos RAID especiales, lo cual rara vez se requiere para Listmonk, pero puede ser relevante para tareas asociadas.

Para la mayoría de las tareas de Listmonk a nivel de pequeña y mediana empresa, un VPS bien configurado será más que suficiente.

Ubicación: qué influencia tiene

  • Latencia: Elija una ubicación cercana a su audiencia principal o a usted mismo (para la gestión). Una baja latencia mejora la velocidad de carga de la interfaz de Listmonk y la velocidad de entrega de los correos al proveedor SMTP.
  • Legislación: Si trabaja con datos personales de usuarios de la UE, asegúrese de que el servidor esté en una jurisdicción que cumpla con el GDPR. Lo mismo aplica para otras regiones.
  • Disponibilidad del proveedor SMTP: Algunos proveedores SMTP pueden tener regiones preferidas para un mejor rendimiento.

Preparación del servidor

Схема: Подготовка сервера
Diagrama: Preparación del servidor

Antes de proceder con la instalación de Listmonk, es necesario realizar una configuración básica de seguridad y actualizar el sistema operativo. Utilizaremos Ubuntu Server 24.04 LTS como la plataforma más común y estable para este tipo de tareas.

1. Conexión al servidor por SSH

Utilice un cliente SSH para conectarse a su VPS. Normalmente, el proveedor le proporcionará la dirección IP y las credenciales iniciales (usuario root y contraseña).


ssh root@SU_DIRECCIÓN_IP

2. Actualización del sistema

Primero, actualice la lista de paquetes y los paquetes instalados a las versiones más recientes.


sudo apt update -y  # Обновление списка пакетов
sudo apt upgrade -y # Обновление установленных пакетов
sudo apt autoremove -y # Удаление ненужных зависимостей

3. Creación de un nuevo usuario con permisos sudo

El uso del usuario root para tareas diarias no es seguro. Cree un nuevo usuario y concédale permisos sudo.


adduser listmonkadmin # Создание нового пользователя "listmonkadmin"
usermod -aG sudo listmonkadmin # Добавление пользователя в группу sudo

Ahora, salga de la sesión root e inicie sesión con el nuevo usuario:


exit # Выход из сессии root
ssh listmonkadmin@SU_DIRECCIÓN_IP # Вход под новым пользователем

4. Configuración de claves SSH (recomendado)

Para mejorar la seguridad, se recomienda utilizar claves SSH en lugar de contraseñas. Genere un par de claves en su máquina local (si aún no lo ha hecho):


ssh-keygen -t rsa -b 4096 # На вашей локальной машине

Copie la clave pública al servidor:


ssh-copy-id listmonkadmin@SU_DIRECCIÓN_IP # На вашей локальной машине

Después de esto, puede deshabilitar la autenticación por contraseña en /etc/ssh/sshd_config, estableciendo PasswordAuthentication no y reiniciando el servicio SSH.

5. Configuración del firewall (UFW)

Habilite UFW (Uncomplicated Firewall) y permita solo los puertos necesarios: SSH (22), HTTP (80) y HTTPS (443).


sudo ufw allow OpenSSH # Разрешить SSH
sudo ufw allow http # Разрешить HTTP (для Caddy/Let's Encrypt)
sudo ufw allow https # Разрешить HTTPS
sudo ufw enable # Включить файрвол (подтвердите 'y')
sudo ufw status # Проверить статус файрвола

6. Instalación de Fail2ban

Fail2ban protege contra ataques de fuerza bruta, bloqueando las direcciones IP que intentan adivinar contraseñas de SSH y otros servicios.


sudo apt install fail2ban -y # Установка Fail2ban
sudo systemctl enable fail2ban # Включение автозапуска
sudo systemctl start fail2ban # Запуск службы
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local # Создание локальной копии конфига

Edite /etc/fail2ban/jail.local para configurar los parámetros, por ejemplo, establezca bantime = 1h (tiempo de bloqueo) y maxretry = 5 (número de intentos). Asegúrese de que la sección [sshd] esté activa (enabled = true).

7. Instalación de utilidades básicas

Instale las utilidades necesarias que serán útiles durante el proceso de instalación y para la depuración.


sudo apt install curl wget git nano htop -y

Ahora su servidor está listo para la instalación del software principal.

Instalación de software — paso a paso

Diagrama: Instalación de software — paso a paso
Diagrama: Instalación de software — paso a paso

Para desplegar Listmonk, utilizaremos Docker y Docker Compose. Esto simplifica significativamente la instalación, la gestión de dependencias y garantiza la portabilidad de la solución. Instalaremos Docker Engine, Docker Compose y luego configuraremos los servicios de Listmonk, PostgreSQL y Caddy.

1. Instalación de Docker Engine

Instalaremos Docker desde el repositorio oficial para obtener las versiones más recientes (para 2026, nos centraremos en Docker Engine 26.x y superior).


# Actualización de la lista de paquetes
sudo apt update -y

# Instalación de los paquetes necesarios para trabajar con repositorios HTTPS
sudo apt install ca-certificates curl gnupg lsb-release -y

# Adición de la clave GPG oficial de Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# Adición del repositorio de Docker a las fuentes de Apt
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Actualización de la lista de paquetes teniendo en cuenta el nuevo repositorio
sudo apt update -y

# Instalación de Docker Engine, containerd y Docker Compose (cli)
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

# Adición del usuario actual al grupo docker para trabajar sin sudo
sudo usermod -aG docker $USER

# Nota: Para aplicar los cambios de grupo, debe salir y volver a iniciar sesión en la sesión SSH
echo "Para completar la instalación de Docker, por favor, salga de la sesión SSH y vuelva a iniciar sesión."

Salga de la sesión SSH (exit) y vuelva a iniciar sesión para que los cambios del grupo Docker surtan efecto. Después de esto, verifique la instalación de Docker:


docker run hello-world # Verificación de la instalación exitosa de Docker

Si ve el mensaje "Hello from Docker!", significa que Docker está instalado y funcionando correctamente.

2. Instalación de Docker Compose (plugin)

En las versiones modernas de Docker, docker compose ya viene como un plugin de Docker CLI, por lo que no se requiere una instalación separada. Ya hemos instalado docker-compose-plugin en el paso anterior. Verifiquemos su versión:


docker compose version # Verificación de la versión de Docker Compose

La versión esperada para 2026 será algo como Docker Compose v2.25.x o superior.

3. Creación de un directorio para el proyecto Listmonk

Crearemos un directorio donde se almacenarán todos los archivos de configuración y datos de Listmonk.


mkdir ~/listmonk # Creación del directorio del proyecto en la carpeta de inicio del usuario
cd ~/listmonk # Navegación al directorio del proyecto

4. Preparación del archivo docker-compose.yml

Ahora crearemos el archivo principal docker-compose.yml, que describirá todos nuestros servicios: Listmonk, PostgreSQL y Caddy.


nano docker-compose.yml # Apertura del editor de texto para crear el archivo

Pegue el siguiente contenido (versiones de imágenes actuales para 2026):


version: '3.8'

services:
  db:
    image: postgres:17-alpine # Versión actual de PostgreSQL para 2026, alpine para ligereza
    restart: always
    environment:
      POSTGRES_DB: listmonk # Nombre de la base de datos
      POSTGRES_USER: listmonk # Usuario de la base de datos
      POSTGRES_PASSWORD: ${DB_PASSWORD} # Contraseña del archivo .env
    volumes:
      - db_data:/var/lib/postgresql/data # Almacenamiento persistente de datos de la BD
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U listmonk -d listmonk"]
      interval: 5s
      timeout: 5s
      retries: 5

  listmonk:
    image: listmonk/listmonk:2.5.0 # Versión actual de Listmonk para 2026
    restart: always
    environment:
      LM_APP_NAME: "My Listmonk" # Nombre de su aplicación
      LM_DATABASE_URL: postgres://listmonk:${DB_PASSWORD}@db:5432/listmonk?sslmode=disable # URL de conexión a la BD
      LM_ADMIN_USERNAME: admin # Nombre de usuario del administrador por defecto
      LM_ADMIN_PASSWORD: ${ADMIN_PASSWORD} # Contraseña del administrador del .env
      LM_SMTP_HOST: ${SMTP_HOST} # Host del servidor SMTP (por ejemplo, smtp.sendgrid.net)
      LM_SMTP_PORT: ${SMTP_PORT} # Puerto del servidor SMTP (por ejemplo, 587)
      LM_SMTP_USERNAME: ${SMTP_USERNAME} # Nombre de usuario SMTP
      LM_SMTP_PASSWORD: ${SMTP_PASSWORD} # Contraseña SMTP
      LM_SMTP_AUTH_PROTOCOL: login # Protocolo de autenticación (normalmente login o plain)
      LM_SMTP_FROM_EMAIL: "[email protected]" # Email del remitente por defecto
      LM_SMTP_FROM_NAME: "Your Company" # Nombre del remitente por defecto
      LM_ENABLE_GRAVATAR: "true" # Habilitar Gravatar
      LM_DEBUG: "false" # Deshabilitar el modo de depuración en producción
      LM_TLS_ENABLE: "true" # Habilitar TLS para SMTP (por defecto)
      LM_APP_URL: "https://listmonk.yourdomain.com" # URL pública de su Listmonk
    depends_on:
      db:
        condition: service_healthy # Iniciar Listmonk solo después de que la BD esté lista
    volumes:
      - listmonk_data:/var/lib/listmonk # Almacenamiento persistente de datos de Listmonk (avatares, adjuntos)
    labels:
      caddy: "listmonk.yourdomain.com" # Indicamos a Caddy el dominio para Listmonk
      caddy.reverse_proxy: "{{upstreams}}" # Proxy de solicitudes a Listmonk

  caddy:
    image: caddy:2.7.6-alpine # Versión actual de Caddy para 2026, alpine para ligereza
    restart: always
    ports:
      - "80:80" # Puerto HTTP
      - "443:443" # Puerto HTTPS
    volumes:
      - caddy_data:/data # Para almacenar certificados SSL y otros datos de Caddy
      - caddy_config:/config # Para almacenar la configuración de Caddy
      - ./Caddyfile:/etc/caddy/Caddyfile # Nuestro Caddyfile personalizado
    depends_on:
      - listmonk # Caddy depende de Listmonk (aunque puede iniciarse antes)

volumes:
  db_data:
  listmonk_data:
  caddy_data:
  caddy_config:

IMPORTANTE: Reemplace listmonk.yourdomain.com con su dominio real que planea usar para Listmonk. Asegúrese de que el registro DNS (A o CNAME) para este dominio apunte a la dirección IP de su VPS.

5. Creación del archivo .env para secretos

Por seguridad, almacenaremos las contraseñas y otros datos sensibles en un archivo .env separado, que no se incluirá en el sistema de control de versiones (si lo utiliza).


nano .env # Apertura del editor de texto para crear el archivo

Pegue el siguiente contenido, reemplazando YOUR_DB_PASSWORD, YOUR_ADMIN_PASSWORD, YOUR_SMTP_HOST, etc., con sus propios valores:


DB_PASSWORD=YOUR_DB_PASSWORD_STRONG_AND_UNIQUE
ADMIN_PASSWORD=YOUR_ADMIN_PASSWORD_STRONG_AND_UNIQUE
SMTP_HOST=smtp.your-email-provider.com
SMTP_PORT=587
SMTP_USERNAME=your-smtp-username
SMTP_PASSWORD=YOUR_SMTP_PASSWORD_STRONG_AND_UNIQUE

Guarde el archivo (Ctrl+O, Enter, Ctrl+X).

6. Creación del archivo Caddyfile

Caddy gestiona automáticamente los certificados SSL, lo que simplifica enormemente la configuración de HTTPS. Crearemos un Caddyfile simple para nuestro dominio.


nano Caddyfile # Apertura del editor de texto para crear el archivo

Pegue el siguiente contenido, reemplazando listmonk.yourdomain.com con su dominio real:


listmonk.yourdomain.com {
    reverse_proxy listmonk:9000 # Proxy de solicitudes a Listmonk, que escucha en el puerto 9000 dentro de Docker
    log {
        output stdout
        format json
    }
}

Guarde el archivo (Ctrl+O, Enter, Ctrl+X).

7. Inicio de los servicios de Docker Compose

Ahora que todos los archivos están listos, podemos iniciar todos los servicios con Docker Compose.


docker compose up -d # Inicio de todos los servicios en segundo plano

Este comando descargará las imágenes Docker necesarias (Listmonk, PostgreSQL, Caddy), creará los contenedores, configurará las redes y los iniciará. El flag -d significa iniciar en modo 'detached' (en segundo plano).

8. Inicialización de la base de datos de Listmonk

Después del primer inicio del contenedor Listmonk, es necesario inicializar su base de datos. Esto solo debe hacerse una vez.


docker compose run --rm listmonk ./listmonk --install # Ejecución del comando de instalación de Listmonk en un nuevo contenedor

Este comando creará tablas en la base de datos PostgreSQL y configurará los datos iniciales para Listmonk. El parámetro --rm garantiza que el contenedor temporal se eliminará después de ejecutar el comando.

Después de una inicialización exitosa, puede verificar el estado de los contenedores en ejecución:


docker compose ps # Verificación del estado de los contenedores

Todos los contenedores (db, listmonk, caddy) deben estar en estado running.

Ahora Listmonk debería ser accesible a través de su dominio (por ejemplo, https://listmonk.yourdomain.com) por HTTPS. Caddy obtendrá y configurará automáticamente un certificado SSL de Let's Encrypt.

Configuración

Diagrama: Configuración
Diagrama: Configuración

Durante la fase de instalación, ya hemos creado los archivos de configuración básicos. Ahora, vamos a examinarlos en detalle y asegurarnos de que todo esté configurado correctamente. Los archivos clave que revisaremos son docker-compose.yml, .env y Caddyfile.

1. Resumen de docker-compose.yml

El archivo docker-compose.yml es central para nuestra implementación. Define tres servicios:

  • db (PostgreSQL):
    • image: postgres:17-alpine: Se utiliza la imagen de PostgreSQL versión 17 (para 2026) basada en Alpine Linux para minimizar el tamaño.
    • environment: Aquí se configuran las variables de entorno para PostgreSQL, como el nombre de la base de datos (listmonk), el nombre de usuario (listmonk) y la contraseña (DB_PASSWORD, que se toma del archivo .env).
    • volumes: - db_data:/var/lib/postgresql/data: Esto es críticamente importante. Montamos un volumen nombrado db_data en el directorio donde PostgreSQL almacena sus datos. Esto garantiza que los datos de la base de datos se conserven incluso si se elimina o recrea el contenedor db.
    • healthcheck: Define cómo Docker verificará la salud de la base de datos, lo que permite que Listmonk no se inicie hasta que la BD esté completamente lista.
  • listmonk:
    • image: listmonk/listmonk:2.5.0: Se utiliza la imagen oficial de Listmonk versión 2.5.0 (actual para 2026).
    • environment: Aquí se pasan todas las configuraciones necesarias para Listmonk:
      • LM_APP_NAME: El nombre de su aplicación Listmonk.
      • LM_DATABASE_URL: Cadena de conexión a la base de datos PostgreSQL. Tenga en cuenta que db es el nombre del servicio PostgreSQL en Docker Compose, y se utiliza como host. La contraseña también se toma de .env.
      • LM_ADMIN_USERNAME y LM_ADMIN_PASSWORD: Credenciales para el primer inicio de sesión en el panel de administración de Listmonk (también de .env).
      • LM_SMTP_HOST, LM_SMTP_PORT, LM_SMTP_USERNAME, LM_SMTP_PASSWORD: Configuración para conectarse a su proveedor SMTP (por ejemplo, SendGrid, Mailgun, Brevo). Estos datos también se toman de .env.
      • LM_SMTP_FROM_EMAIL, LM_SMTP_FROM_NAME: Correo electrónico y nombre del remitente predeterminados.
      • LM_APP_URL: URL completa de su Listmonk, que se utilizará en los enlaces de los correos electrónicos.
    • depends_on: Indica que Listmonk solo debe iniciarse después de que el servicio db esté saludable (service_healthy).
    • volumes: - listmonk_data:/var/lib/listmonk: Almacenamiento de datos de Listmonk (por ejemplo, avatares, adjuntos) en un volumen persistente.
  • caddy:
    • image: caddy:2.7.6-alpine: Se utiliza la imagen oficial de Caddy.
    • ports: - "80:80" - "443:443": Mapeo de puertos HTTP y HTTPS desde el host al contenedor Caddy.
    • volumes:
      • caddy_data:/data: Para almacenar los certificados SSL de Let's Encrypt y otra información dinámica de Caddy.
      • caddy_config:/config: Para almacenar la configuración persistente de Caddy.
      • ./Caddyfile:/etc/caddy/Caddyfile: Montaje de nuestro Caddyfile local en el contenedor.

2. Gestión de secretos a través de .env

El archivo .env contiene información sensible, como contraseñas de bases de datos y servicios SMTP. Se carga automáticamente por Docker Compose al iniciar. ¡Nunca suba este archivo a repositorios públicos!

Si necesita cambiar algún secreto, simplemente edite .env y reinicie los servicios:


docker compose down # Detiene y elimina los contenedores
docker compose up -d # Inicia con las nuevas variables

3. Configuración de TLS/HTTPS a través de Caddy

Utilizamos Caddy como proxy inverso, que obtiene y renueva automáticamente los certificados SSL de Let's Encrypt. Esto simplifica enormemente la configuración de HTTPS.

En nuestro Caddyfile:


listmonk.yourdomain.com {
    reverse_proxy listmonk:9000
    log {
        output stdout
        format json
    }
}
  • listmonk.yourdomain.com: Especifica el dominio para el cual Caddy procesará las solicitudes y obtendrá el certificado. Asegúrese de que esta entrada coincida con su dominio y que el registro DNS para este dominio apunte a la dirección IP de su VPS.
  • reverse_proxy listmonk:9000: Redirige todas las solicitudes entrantes al servicio interno listmonk (nombre del contenedor Listmonk en Docker Compose) en el puerto 9000.

En el primer inicio, Caddy intentará automáticamente obtener un certificado SSL. Si encuentra problemas, asegúrese de que:

  • El nombre de dominio está configurado correctamente y apunta a la IP de su VPS.
  • Los puertos 80 y 443 están abiertos en el firewall (esto lo hicimos durante la preparación del servidor).
  • No hay otros errores en el contenedor Caddy (verifique los logs: docker compose logs caddy).

4. Verificación de la funcionalidad

Después de iniciar todos los servicios, es necesario asegurarse de que todo funciona correctamente.


# Verificar el estado de los contenedores
docker compose ps

# Verificar los logs de Caddy (para depuración de SSL o proxy)
docker compose logs caddy

# Verificar los logs de Listmonk (para depuración de conexión a la BD o SMTP)
docker compose logs listmonk

# Verificar la accesibilidad de la interfaz web desde el servidor (reemplace con su dominio)
curl -IL https://listmonk.yourdomain.com

Debería ver los encabezados de respuesta HTTP, incluyendo HTTP/2 200 o HTTP/1.1 200 OK, lo que indica una conexión exitosa.

Abra su dominio en el navegador (por ejemplo, https://listmonk.yourdomain.com). Debería ver la página de inicio de sesión de Listmonk. Use el nombre de usuario admin y la contraseña, especificada en la variable ADMIN_PASSWORD en su archivo .env, para iniciar sesión.

Después de iniciar sesión en el panel de administración de Listmonk, vaya a Settings > SMTP y asegúrese de que su configuración SMTP se haya cargado correctamente. Puede enviar un correo electrónico de prueba para verificar la funcionalidad del servidor SMTP.

Copias de seguridad y mantenimiento

Diagrama: Copias de seguridad y mantenimiento
Diagrama: Copias de seguridad y mantenimiento

Las copias de seguridad son una parte críticamente importante de cualquier implementación. La pérdida de datos puede tener consecuencias catastróficas. En el caso de Listmonk en Docker, necesitamos hacer copias de seguridad de los datos de PostgreSQL, la configuración de Listmonk y los archivos almacenados por Listmonk.

1. Qué respaldar

  • Base de datos PostgreSQL: Contiene todos los suscriptores, listas, campañas, estadísticas y otra información importante. Este es el componente más importante.
  • Datos de Listmonk: Incluyen avatares, archivos adjuntos de correos electrónicos y otros archivos que Listmonk almacena en disco (volumen listmonk_data).
  • Archivos de configuración: docker-compose.yml, .env, Caddyfile. Son necesarios para una rápida recuperación de toda la infraestructura.

2. Script simple de copia de seguridad automática

Crearemos un script simple que realizará una copia de seguridad de la base de datos y los datos de Listmonk, y luego los archivará. Para el almacenamiento, se puede utilizar un servicio externo compatible con S3 u otro VPS.

Cree el archivo backup_listmonk.sh en el directorio ~/listmonk:


nano backup_listmonk.sh

Pegue el siguiente contenido:


#!/bin/bash

# Каталог, где хранятся файлы docker-compose.yml и .env
PROJECT_DIR="/home/listmonkadmin/listmonk" # Убедитесь, что это правильный путь
BACKUP_DIR="/var/backups/listmonk"
DATE=$(date +%Y%m%d%H%M%S)

# Загрузка переменных окружения из .env
set -a
. "$PROJECT_DIR/.env"
set +a

# Создание директории для бэкапов, если она не существует
mkdir -p "$BACKUP_DIR"

echo "--- Начинаем бэкап Listmonk ($DATE) ---"

# 1. Бэкап базы данных PostgreSQL
echo "Бэкапим базу данных PostgreSQL..."
docker compose exec db pg_dump -U listmonk -d listmonk > "$BACKUP_DIR/listmonk_db_$DATE.sql"
if [ $? -eq 0 ]; then
    echo "Бэкап БД успешно создан: $BACKUP_DIR/listmonk_db_$DATE.sql"
else
    echo "Ошибка при создании бэкапа БД."
fi

# 2. Бэкап данных Listmonk (том listmonk_data)
echo "Бэкапим данные Listmonk..."
# Получаем имя тома Docker
LISTMONK_VOLUME_NAME=$(docker volume inspect listmonk_listmonk_data --format '{{ .Mountpoint }}')
if [ -d "$LISTMONK_VOLUME_NAME" ]; then
    tar -czf "$BACKUP_DIR/listmonk_files_$DATE.tar.gz" -C "$LISTMONK_VOLUME_NAME" .
    if [ $? -eq 0 ]; then
        echo "Бэкап файлов Listmonk успешно создан: $BACKUP_DIR/listmonk_files_$DATE.tar.gz"
    else
        echo "Ошибка при создании бэкапа файлов Listmonk."
    fi
else
    echo "Том listmonk_data не найден или путь некорректен."
fi

# 3. Копирование конфигурационных файлов
echo "Копируем конфигурационные файлы..."
cp "$PROJECT_DIR/docker-compose.yml" "$BACKUP_DIR/docker-compose_$DATE.yml"
cp "$PROJECT_DIR/.env" "$BACKUP_DIR/.env_$DATE"
cp "$PROJECT_DIR/Caddyfile" "$BACKUP_DIR/Caddyfile_$DATE"
echo "Конфигурационные файлы скопированы."

# 4. Удаление старых бэкапов (например, старше 7 дней)
echo "Удаляем старые бэкапы (старше 7 дней)..."
find "$BACKUP_DIR" -type f -name "*.sql" -mtime +7 -delete
find "$BACKUP_DIR" -type f -name "*.tar.gz" -mtime +7 -delete
find "$BACKUP_DIR" -type f -name "*.yml" -mtime +7 -delete
find "$BACKUP_DIR" -type f -name "*.env" -mtime +7 -delete
echo "Старые бэкапы удалены."

echo "--- Бэкап Listmonk завершен ---"

Haga que el script sea ejecutable:


chmod +x backup_listmonk.sh

Verifique el funcionamiento del script manualmente:


./backup_listmonk.sh
ls -lh /var/backups/listmonk/

3. Dónde almacenar las copias de seguridad

  • Almacenamiento de objetos externo compatible con S3: Opción recomendada. Fiable, escalable y generalmente económico. Utilice utilidades como s3cmd, rclone o aws cli (para almacenamientos compatibles) para la carga automática de archivos de copia de seguridad.
  • VPS separado: Se puede configurar rsync para copiar las copias de seguridad a otro VPS. Esto proporciona una separación geográfica.
  • Localmente (solo para pruebas): Almacenar las copias de seguridad en el mismo servidor que los datos no es una solución fiable, ya que si se pierde el servidor, también se pierden las copias de seguridad.

Para cargar a un almacenamiento compatible con S3, se puede añadir al script, por ejemplo, después de la archivación:


# Пример загрузки на S3 с помощью rclone (требуется предварительная настройка rclone)
# rclone copy "$BACKUP_DIR/listmonk_db_$DATE.sql" "my_s3_remote:listmonk-backups/"
# rclone copy "$BACKUP_DIR/listmonk_files_$DATE.tar.gz" "my_s3_remote:listmonk-backups/"

4. Automatización de copias de seguridad con Cron

Añada el script a Cron para su ejecución automática, por ejemplo, diariamente a las 3:00 de la madrugada.


crontab -e

Añada la siguiente línea al final del archivo (asegúrese de que la ruta al script sea correcta):


0 3 * * * /home/listmonkadmin/listmonk/backup_listmonk.sh >> /var/log/listmonk_backup.log 2>&1

Esta línea ejecutará el script cada día a las 3 de la madrugada, y redirigirá la salida a un archivo de registro.

5. Actualizaciones: rolling vs maintenance window

Las actualizaciones regulares de software son importantes para la seguridad y para obtener nuevas funciones.

  • Actualización del SO: Se recomienda realizarla una vez al mes (sudo apt update && sudo apt upgrade -y). Para actualizaciones importantes de la distribución (por ejemplo, de 24.04 a 26.04), planifique una ventana de mantenimiento y realice copias de seguridad completas.
  • Actualización de imágenes Docker (Listmonk, PostgreSQL, Caddy):
    • Actualizaciones continuas (rolling updates): Si utiliza la etiqueta latest (no recomendado para producción) o etiquetas específicas pero no fijas (por ejemplo, listmonk/listmonk:2.5 en lugar de listmonk/listmonk:2.5.0), Docker descargará nuevas versiones al ejecutar docker compose pull.
    • Ventana de mantenimiento: Para producción, es mejor fijar las versiones de las imágenes (por ejemplo, listmonk/listmonk:2.5.0). La actualización debe realizarse manualmente: cambiar la versión en docker-compose.yml, ejecutar docker compose pull, y luego docker compose up -d. Se recomienda hacer una copia de seguridad antes de la actualización.

Solución de problemas + Preguntas frecuentes

Incluso con una configuración cuidadosa, pueden surgir problemas. Esta sección le ayudará a diagnosticar y resolver los más comunes.

1. La interfaz de usuario de Listmonk no está disponible o muestra un error 502/503

Qué verificar:

  1. Estado de los contenedores: Asegúrese de que todos los contenedores (db, listmonk, caddy) estén iniciados y en estado running. Use el comando docker compose ps.
  2. Registros de Caddy: Revise los registros de Caddy en busca de errores relacionados con el proxy o SSL. docker compose logs caddy. Busque errores como "connection refused" a Listmonk o problemas con la obtención de certificados Let's Encrypt.
  3. Registros de Listmonk: Revise los registros de Listmonk. Es posible que no pueda conectarse a la base de datos o que haya otros errores internos. docker compose logs listmonk.
  4. Cortafuegos: Asegúrese de que los puertos 80 y 443 estén abiertos en su VPS. sudo ufw status.
  5. Registro DNS: Verifique que su dominio (por ejemplo, listmonk.yourdomain.com) apunte correctamente a la dirección IP de su VPS.

Cómo solucionar: Corrija los errores encontrados en los registros. Si Caddy no puede obtener SSL, asegúrese de que el registro DNS sea correcto y que los puertos 80/443 estén abiertos. Si Listmonk no puede conectarse a la base de datos, verifique las variables de entorno en .env y docker-compose.yml.

2. Error de conexión a la base de datos de Listmonk

Qué verificar:

  1. Variables de entorno: Asegúrese de que DB_PASSWORD en .env coincida con POSTGRES_PASSWORD en docker-compose.yml para el servicio db y se utilice en LM_DATABASE_URL para el servicio listmonk.
  2. Salud del contenedor de la base de datos: docker compose ps. Asegúrese de que el servicio db esté en estado healthy.
  3. Registros de la base de datos: docker compose logs db. Busque errores de inicio de PostgreSQL o problemas de acceso.
  4. Nombre de host de la base de datos: En LM_DATABASE_URL, el host debe ser el nombre del servicio Docker Compose, es decir, db.

Cómo solucionar: Corrija las contraseñas o nombres de usuario incorrectos. Si la base de datos no se inicia, revise los registros. Es posible que el volumen de datos esté dañado y requiera su limpieza (con pérdida de datos si no hay copia de seguridad) y reinicialización.

3. Problemas con el envío de correo electrónico

Qué verificar:

  1. Configuración SMTP: En Listmonk (Settings > SMTP) y en el archivo .env, verifique SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD. Asegúrese de que coincidan con los datos de su proveedor SMTP.
  2. Registros de Listmonk: docker compose logs listmonk. Listmonk suele mostrar errores detallados en caso de un intento fallido de envío de correo electrónico.
  3. Cortafuegos del VPS: Asegúrese de que su VPS pueda establecer conexiones salientes al puerto SMTP (normalmente 587 o 465).
  4. Límites del proveedor SMTP: Verifique si ha excedido los límites de envío de correos electrónicos de su proveedor SMTP.

Cómo solucionar: Ajuste la configuración SMTP. Asegúrese de que su proveedor SMTP no esté bloqueando las conexiones desde su dirección IP. Verifique el estado de su cuenta con el proveedor SMTP.

4. Caddy no obtiene el certificado SSL

Qué verificar:

  1. Registro DNS: El nombre de dominio debe estar configurado y apuntar a la IP pública de su VPS. Verifíquelo con dig listmonk.yourdomain.com.
  2. Puertos 80 y 443: Deben estar abiertos en UFW. sudo ufw status. Let's Encrypt utiliza el puerto 80 para la validación del dominio.
  3. Caddyfile: Asegúrese de que el dominio en Caddyfile esté especificado correctamente y coincida con su dominio.
  4. Registros de Caddy: docker compose logs caddy. Caddy suele informar muy detalladamente sobre los problemas para obtener SSL.

Cómo solucionar: Corrija el registro DNS. Abra los puertos en el cortafuegos. Reinicie Caddy: docker compose restart caddy.

5. ¿Qué configuración mínima de VPS es adecuada?

Para proyectos pequeños con una base de hasta 50.000 suscriptores y envíos poco frecuentes, un VPS con 2 vCPU, 4 GB de RAM y un disco NVMe/SSD de 50-80 GB será mínimamente adecuado. Esto proporcionará un rendimiento suficiente para Listmonk, PostgreSQL y Caddy. Si planea desarrollar activamente el marketing por correo electrónico, debería considerar directamente 4 vCPU y 8 GB de RAM.

6. ¿Qué elegir: VPS o dedicado para esta tarea?

Para la mayoría de los usuarios, incluidos desarrolladores, fundadores individuales y equipos pequeños, un VPS será la opción óptima. Ofrece suficiente potencia, flexibilidad y economía. Un servidor dedicado solo se justifica para escalas muy grandes (cientos de miles o millones de suscriptores, alta frecuencia de envíos) o para requisitos específicos de aislamiento físico y rendimiento que la virtualización no puede proporcionar.

7. ¿Cómo actualizar Listmonk a una nueva versión?

Qué verificar:

  1. Antes de actualizar, es imprescindible realizar una copia de seguridad completa de la base de datos y los datos de Listmonk, como se describe en la sección "Copias de seguridad y mantenimiento".
  2. Revise la documentación oficial de Listmonk para ver si hay migraciones de base de datos o cambios importantes entre versiones.

Cómo solucionar: Edite el archivo docker-compose.yml y cambie la etiqueta de la imagen de Listmonk a la nueva versión (por ejemplo, de listmonk/listmonk:2.5.0 a listmonk/listmonk:2.6.0). Luego, ejecute:


docker compose pull listmonk # Скачать новый образ Listmonk
docker compose up -d # Перезапустить контейнер Listmonk с новым образом

Si la nueva versión requiere migraciones de base de datos, Listmonk suele realizarlas automáticamente al iniciar. Si no, podrían ser necesarios comandos adicionales, indicados en la documentación oficial de Listmonk.

Conclusiones y próximos pasos

Diagrama: Conclusiones y próximos pasos
Diagrama: Conclusiones y próximos pasos

¡Felicidades! Has desplegado Listmonk con éxito en tu servidor VPS, utilizando Docker, PostgreSQL y Caddy. Ahora tienes una herramienta potente y totalmente controlada para la gestión de boletines por correo electrónico, que ofrece flexibilidad, privacidad y no tiene las limitaciones inherentes a muchas soluciones SaaS.

Esta es una solución robusta y escalable, lista para funcionar. Has obtenido control total sobre tu infraestructura y datos, lo cual es una ventaja clave del enfoque self-hosted.

Próximos pasos:

  • Integración con proveedor SMTP: Asegúrate de que tu proveedor SMTP (SendGrid, Mailgun, Brevo, etc.) esté configurado y funcione correctamente. Es posible que debas configurar los registros SPF, DKIM y DMARC para tu dominio para mejorar la entregabilidad de los correos electrónicos.
  • Creación de plantillas de correo electrónico: Desarrolla plantillas atractivas y responsivas para tus boletines. Listmonk admite un editor HTML y la importación de plantillas.
  • Importación de suscriptores y segmentación: Importa suscriptores existentes y configura segmentos para envíos más dirigidos.
  • Configuración de monitoreo: Considera la instalación de sistemas de monitoreo (por ejemplo, Prometheus + Grafana) para rastrear el estado de tu VPS, contenedores Docker y el rendimiento de Listmonk.
  • Escalado: A medida que crezca tu base de suscriptores y el volumen de envíos, considera aumentar los recursos del VPS o migrar a un servidor dedicado. PostgreSQL puede optimizarse para grandes cargas de trabajo.

¿Te fue útil esta guía?

Despliegue de Listmonk en VPS: gestión de newsletters con Docker, PostgreSQL y
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.