Pourquoi auto-héberger Listmonk sur un VPS
Listmonk est un binaire Go unique adossé à PostgreSQL, capable de gérer des listes massives et des campagnes segmentées avec un débit d'envoi très élevé. Le self-hosting devient pertinent dès que votre base d'abonnés dépasse quelques milliers de contacts : les plateformes SaaS facturent alors des centaines d'euros par mois pour une tâche qu'un VPS modeste exécute pour le prix du serveur. Vous gardez la propriété intégrale de votre base d'e-mails (aucune fuite vers un tiers), vous branchez le relais SMTP de votre choix et vous pilotez la cadence d'envoi pour préserver votre réputation d'expéditeur. Un VPS est ici indispensable car Listmonk a besoin d'un processus persistant, d'une base PostgreSQL et de ports SMTP sortants ouverts — des libertés qu'aucun mutualisé n'accorde.
Bénéfices concrets de Listmonk auto-hébergé
- Aucun coût au contact : la facture ne dépend plus de la taille de votre liste mais uniquement du VPS.
- Segmentation par requêtes SQL : ciblez des sous-ensembles d'abonnés avec une précision impossible sur la plupart des SaaS.
- Templating riche (Go templates + HTML) et campagnes A/B versionnables dans votre dépôt.
- API REST complète : déclenchez des envois transactionnels depuis votre application via webhook.
- Suivi des ouvertures, clics et bounces dans une interface unifiée, sans pixel tiers.
- Choix libre du relais (Postmark, Amazon SES, OVH, votre propre Postfix) pour optimiser délivrabilité et coût.
Prérequis techniques
Listmonk lui-même est très léger, mais PostgreSQL et le volume d'envoi imposent un dimensionnement raisonnable : prévoyez 2 vCPU, 2 Go de RAM et 20 Go de disque pour une base de quelques dizaines de milliers de contacts ; montez à 4 Go de RAM si vous gérez des campagnes simultanées volumineuses. Côté infrastructure : Docker et Docker Compose, un domaine mail.votredomaine.com en A vers le VPS, et surtout les enregistrements DNS d'authentification e-mail (SPF, DKIM, DMARC) configurés sur le domaine d'envoi. Un relais SMTP avec identifiants (host, port 587, user, mot de passe) est nécessaire — l'envoi direct depuis l'IP d'un VPS est souvent bloqué par les fournisseurs.
Déployer Listmonk pas à pas
Récupérer la stack officielle
Sur le VPS, créez
/opt/listmonkpuis téléchargez le compose de référence :curl -LO https://raw.githubusercontent.com/knadh/listmonk/master/docker-compose.yml. Il déclare deux services,app(listmonk) etdb(PostgreSQL).Initialiser la base de données
Lancez la migration initiale avant le premier run :
docker compose run --rm app ./listmonk --install. Cette commande crée le schéma PostgreSQL et l'utilisateur administrateur. Renseignez un mot de passe admin solide à l'invite.Démarrer le service
Lancez la stack avec
docker compose up -d. Listmonk écoute sur le port 9000 en interne. Vérifiez l'état des conteneurs avecdocker compose pset consultez les logs au besoin.Configurer le reverse proxy et le SSL
Exposez Listmonk derrière un reverse proxy avec HTTPS. Exemple Caddy :
mail.votredomaine.com { reverse_proxy app:9000 }. Le certificat Let's Encrypt est généré automatiquement. Ne publiez jamais le port 9000 directement sur Internet.Brancher le relais SMTP
Dans Réglages > SMTP, saisissez les paramètres de votre relais (host, port 587, identifiants, TLS activé). Envoyez un e-mail de test depuis l'interface pour valider la connexion avant toute campagne.
Sécuriser la délivrabilité
Vérifiez avec un outil externe que SPF, DKIM et DMARC passent au vert sur votre domaine d'envoi. Démarrez par de petites campagnes pour « chauffer » l'IP du relais et surveillez le taux de bounce dans le tableau de bord.
Configuration avancée : SMTP, listes et segments
Listmonk supporte plusieurs serveurs SMTP simultanément : créez un serveur dédié aux envois transactionnels (confirmations, mots de passe oubliés) et un second pour les campagnes marketing, chacun avec ses propres identifiants et limites de débit. Pour gérer les bounces automatiquement, activez le Bounce Processor dans Réglages > Bounces : Listmonk interroge une boîte IMAP (ou un webhook de votre relais) et désinscrit les adresses invalides sans intervention manuelle.
Pour les listes, préférez le double opt-in (Réglages > Listes > Opt-in) : un e-mail de confirmation est envoyé à chaque nouvel abonné, ce qui protège votre réputation et respecte le RGPD. Les segments dynamiques (Listes > Nouveau segment) s'appuient sur des requêtes SQL directes contre la table des abonnés : par exemple attribs->>'plan' = 'pro' AND created_at > NOW() - INTERVAL '30 days' pour cibler les nouveaux clients premium. Ces attributs personnalisés se passent à l'inscription via l'API (POST /api/subscribers) dans le champ attribs (objet JSON libre).
Mise à jour de Listmonk
Avant toute mise à jour, sauvegardez la base : docker exec listmonk_db_1 pg_dump -U listmonk listmonk > backup-avant-maj.sql. Ensuite, arrêtez la stack, récupérez la nouvelle image et exécutez le script de migration :
docker compose down
docker compose pull
docker compose run --rm app ./listmonk --upgrade
docker compose up -dL'option --upgrade applique les migrations de schéma nécessaires entre versions. Consultez le journal des changements sur le dépôt officiel avant de passer d'une version majeure à une autre : certaines migrations sont irréversibles. Une fois le service redémarré, vérifiez l'interface et envoyez un e-mail de test pour confirmer que tout fonctionne.
Dépannage courant
Connexion SMTP refusée — connection refused sur le port 587. La plupart des fournisseurs de VPS bloquent les ports SMTP sortants (25, 465, 587) pour lutter contre le spam. La solution : utiliser un relais SMTP externe (Postmark, Amazon SES, Brevo en mode relay) dont le trafic sort via l'API HTTPS ou un port autorisé. Vérifiez aussi que TLS est activé côté Listmonk (STARTTLS pour le 587).
Base PostgreSQL inaccessible au démarrage — dial tcp db:5432: connect: connection refused. Le conteneur app démarre avant que PostgreSQL soit prêt. Ajoutez une directive depends_on avec condition: service_healthy dans votre docker-compose.yml, ou attendez quelques secondes avant de relancer : docker compose restart app.
502 Bad Gateway avec Caddy. Le conteneur Listmonk n'est pas démarré ou a planté. Vérifiez docker compose ps : si app est en état Exited, lancez docker compose logs app pour identifier l'erreur, puis docker compose up -d pour le relancer.
Import CSV bloqué ou abonnés manquants. Listmonk exige un fichier CSV encodé en UTF-8 sans BOM, avec au minimum une colonne email. Un fichier exporté depuis Excel peut contenir un BOM (marqueur invisible en début de fichier) ou un encodage Windows-1252 : convertissez-le avec iconv -f WINDOWS-1252 -t UTF-8 liste.csv > liste-utf8.csv avant l'import.
Réglez la limite de débit d'envoi (Settings > Performance > max concurrent connections et message rate) en fonction des quotas de votre relais SMTP. Un envoi trop agressif fait grimper le taux de spam et le rejet. Pour les e-mails transactionnels critiques, créez un second serveur de messagerie dans Listmonk dédié à ces envois, séparé du serveur marketing : ainsi un problème de réputation sur les newsletters n'affecte pas vos e-mails de confirmation.
RGPD et listes de suppression
Listmonk maintient automatiquement une liste de suppression (unsubscribes + bounces durs). Pour être conforme au RGPD, activez le double opt-in sur toutes vos listes publiques et configurez la page de désabonnement avec un lien {{ UnsubscribeURL }} dans chaque template. Les données des abonnés désinscrits restent en base (pour éviter une réinscription accidentelle) mais sont marquées blocklisted : ils ne reçoivent plus aucun envoi. Exportez et purgez régulièrement ces entrées si votre DPA l'exige.
Cas d'usage : boutique e-commerce avec e-mails transactionnels et newsletters
Imaginez une boutique PrestaShop ou WooCommerce auto-hébergée sur un VPS ServOrbit. Configurez Listmonk comme moteur d'e-mail central : les confirmations de commande et les notifications d'expédition transitent par l'API transactionnelle (/api/tx) avec un template Listmonk ; les clients qui opt-inent à la newsletter reçoivent une campagne hebdomadaire via la liste Listmonk. Un seul relais SMTP, une seule plateforme, zéro frais par abonné. La segmentation par attributs personnalisés (panier moyen, catégorie préférée, date du dernier achat) vous permet de cibler des offres précises — sans exporter vos données vers un SaaS tiers.
Sauvegarde et portabilité des données
Listmonk stocke toutes ses données dans PostgreSQL (volume Docker listmonk-db). Pour sauvegarder : docker exec listmonk_db_1 pg_dump -U listmonk listmonk > backup.sql. Pour restaurer sur une autre instance : créez un nouveau déploiement Listmonk vide, arrêtez l'app, restaurez la base (psql -U listmonk listmonk < backup.sql) et redémarrez. Les fichiers attachés (images en ligne) sont dans le volume listmonk-uploads. L'API REST de Listmonk permet aussi d'exporter les abonnés en CSV à tout moment depuis l'interface ou par script.