SSD Nodes Learn 8GB RAM — $66/Jahr
Anleitungen Matt ConnorVon Matt Connor · Aktualisiert 2026-08-01

Listmonk auf einem VPS selbst hosten

Installieren Sie Listmonk v6.2.0 auf Ubuntu 24.04 mit PostgreSQL, config.toml, systemd und TLS. Verbinden Sie SMTP und planen Sie mehrere Wochen fuer Reputation ein.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Was ein selbst gehosteter Newsletter mit Listmonk benötigt

Listmonk ist ein selbst gehosteter Newsletter- und Mailinglisten-Manager: eine Go-Binärdatei, eine PostgreSQL-Datenbank, eine Konfigurationsdatei und eine systemd-Unit. Ein kleiner VPS führt die Anwendung problemlos aus, weil Listmonk Abonnenten speichert und Kampagnen in eine Warteschlange stellt, die E-Mails aber nicht selbst zustellt. Listmonk übergibt jede Nachricht an einen SMTP-Server (Simple Mail Transfer Protocol). Daher hängt Ihre Zustellrate von der Reputation dieses Servers ab und nicht von dieser Software.

Diese Anleitung installiert Listmonk v6.2.0, die aktuelle Version im Juli 2026, auf Ubuntu 24.04. Sie benötigen einen VPS mit einer öffentlichen IP-Adresse, einen Domainnamen, den Sie verwalten, und PostgreSQL 12 oder neuer. Die Installation dauert etwa eine Stunde. Der Aufbau der Absenderreputation dauert mehrere Wochen. Dieser Teil wird gegen Ende behandelt.

PostgreSQL installieren und die Datenbank erstellen

Ubuntu 24.04 stellt PostgreSQL 16 in einem eigenen Repository bereit. Das liegt deutlich über der von Listmonk benötigten Version.

sudo apt update
sudo apt install -y postgresql curl
sudo systemctl enable --now postgresql

Erstellen Sie die Rolle und die Datenbank in einer einzigen psql-Sitzung. -v ON_ERROR_STOP=1 beendet psql nach der ersten fehlgeschlagenen Anweisung. Dadurch führt ein Tippfehler nicht zu einer unvollständigen Einrichtung, die fertig aussieht.

sudo -u postgres psql -v ON_ERROR_STOP=1 <<'SQL'
CREATE USER listmonk WITH PASSWORD 'pick-a-long-random-password';
CREATE DATABASE listmonk OWNER listmonk;
SQL

OWNER listmonk ist nicht überflüssig. Die Schema-Installation erstellt Tabellen, Typen, Indizes und Funktionen. Daher muss die Rolle Eigentümerin der Datenbank sein. Wenn Sie Listmonk auf eine Datenbank verweisen, die einer anderen Rolle gehört, wird die Installation mit permission denied beendet, auch nachdem Sie GRANT CONNECT ausgeführt haben.

Bestätigen Sie, dass die Datenbank vorhanden ist, bevor Sie fortfahren.

sudo -u postgres psql -tAc "SELECT datname FROM pg_database WHERE datname='listmonk';"

Dies gibt listmonk aus. Eine leere Zeile bedeutet, dass die CREATE-Anweisung nicht ausgeführt wurde. Lesen Sie daher erneut die psql-Ausgabe.

Listmonk-Binärdatei installieren

Listmonk veröffentlicht eine statische Binärdatei für jede Architektur. Prüfen Sie Ihre Architektur zuerst, da der Kernel eine amd64-Binärdatei auf einem ARM-VPS nicht ausführt.

dpkg --print-architecture
cd /tmp
curl -fsSLO https://github.com/knadh/listmonk/releases/download/v6.2.0/listmonk_6.2.0_linux_amd64.tar.gz
tar -xzf listmonk_6.2.0_linux_amd64.tar.gz
sudo install -m 755 listmonk /usr/bin/listmonk
listmonk --version

Auf einem ARM-VPS ersetzen Sie amd64 durch arm64 im Dateinamen. Wenn listmonk --version eine Versionszeichenfolge ausgibt, ist dies der erste Beleg dafür, dass die Binärdatei zur Maschine passt.

config.toml erstellen und absichern

--new-config schreibt config.toml in das aktuelle Arbeitsverzeichnis. Deshalb befindet sich cd innerhalb von sh -c und nicht vor sudo.

sudo install -d -m 750 /etc/listmonk
sudo sh -c 'cd /etc/listmonk && listmonk --new-config'

Die erzeugte Datei ist kurz. Unter [app] bindet address = "localhost:9000" den HTTP-Server nur an Loopback. Dadurch ist das Admin-Panel aus dem Internet nicht erreichbar, bis Sie einen Reverse-Proxy davorschalten. Lassen Sie diese Zeile unverändert. Unter [db] finden Sie host = "localhost", port = 5432, user = "listmonk", database = "listmonk" und ssl_mode = "disable". Diese Standardwerte passen bereits zu der von Ihnen erstellten Datenbank. Sie müssen nur die Passwortzeile ändern.

ssl_mode = "disable" ist korrekt, solange Postgres auf demselben System an Loopback lauscht. Dieser Datenverkehr verlässt das System nicht. Verschieben Sie die Datenbank auf einen anderen Host, setzen Sie den Wert auf require. Andernfalls wird das Passwort unverschlüsselt über das Netzwerk übertragen.

Bearbeiten Sie die Passwortzeile unter [db], sodass sie zur Rolle passt. Erstellen Sie anschließend das Dienstkonto und entziehen Sie allen anderen Logins den Zugriff auf die Datei.

sudo useradd --system --home-dir /var/lib/listmonk --create-home --shell /usr/sbin/nologin listmonk
sudo chown -R root:listmonk /etc/listmonk
sudo chmod 640 /etc/listmonk/config.toml

Jetzt kann das Dienstkonto die Datei lesen, und kein anderer Benutzer kann dies.

sudo -u listmonk cat /etc/listmonk/config.toml > /dev/null && echo readable
stat -c '%U:%G %a' /etc/listmonk/config.toml

Der erste Befehl gibt readable aus. Der zweite gibt root:listmonk 640 aus. Jedes andere unprivilegierte Konto, das denselben cat ausführt, erhält Permission denied. Genau das ist der Zweck: Diese Datei enthält Ihr Datenbankpasswort im Klartext, und auf einem Server gibt es normalerweise mehr als ein Login. Dieselbe Überlegung gilt für jeden Dienst, den Sie ausführen. Lesen Sie daher einmal Dienstbenutzer mit geringsten Rechten und wenden Sie dieses Prinzip überall an.

Schema mit --install erstellen

--install erstellt die Tabellen und legt die Standardeinstellungen an. Legen Sie die erste Administratoranmeldung mit Umgebungsvariablen fest, damit das Konto vorhanden ist, bevor das Panel erreichbar ist.

sudo -u listmonk env LISTMONK_ADMIN_USER=admin \
  LISTMONK_ADMIN_PASSWORD='another-long-random-password' \
  listmonk --config /etc/listmonk/config.toml --install --yes

--yes beantwortet die Bestätigungsabfrage. Lesen Sie diese Abfrage einmal, bevor Sie den Vorgang automatisieren, weil --install die erste Installationsausführung ist und ein vorhandenes Listmonk-Schema löscht. Wenn Sie den Befehl ein zweites Mal in einer aktiven Datenbank ausführen, werden Ihre Abonnenten gelöscht. Verwenden Sie in jedem Skript, das möglicherweise zweimal ausgeführt wird, --install --idempotent --yes. Dieser Befehl führt nichts aus, wenn die Tabellen bereits vorhanden sind. Schemaänderungen, die mit einer neuen Version ausgeliefert werden, wenden Sie mit --upgrade an, niemals mit --install.

Prüfen Sie das Ergebnis auf Datenbankseite und nicht im Browser.

sudo -u postgres psql -d listmonk -c '\dt'
sudo -u postgres psql -d listmonk -tAc "SELECT username FROM users;"

Der erste Befehl listet die Listmonk-Tabellen auf, darunter subscribers, lists, campaigns, templates und bounces. Der zweite gibt admin aus. Ein leeres Ergebnis des zweiten Befehls bedeutet, dass die Umgebungsvariablen den Prozess nicht erreicht haben. In diesem Fall fordert das Panel Sie stattdessen im Browser auf, den ersten Benutzer anzulegen.

Listmonk unter systemd ausführen

Schreiben Sie /etc/systemd/system/listmonk.service.

[Unit]
Description=Listmonk newsletter and mailing list manager
After=network-online.target postgresql.service
Wants=network-online.target

[Service]
Type=simple
User=listmonk
Group=listmonk
WorkingDirectory=/var/lib/listmonk
ExecStart=/usr/bin/listmonk --config /etc/listmonk/config.toml
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true

[Install]
WantedBy=multi-user.target

WorkingDirectory ist wichtig, weil Listmonk relative Pfade, einschließlich eines Dateisystempfads für Medien-Uploads, relativ dazu auflöst. After=postgresql.service startet den Dienst lediglich in der angegebenen Reihenfolge. Der Befehl wartet nicht, bis Postgres Verbindungen akzeptiert. Restart=on-failure deckt daher den Fall ab, dass Listmonk etwas zu früh startet und keine Verbindung herstellen kann.

sudo systemctl daemon-reload
sudo systemctl enable --now listmonk
ss -ltnp | grep 9000
curl -sI http://127.0.0.1:9000/

ss sollte 127.0.0.1:9000 im Status LISTEN anzeigen. Wenn curl eine beliebige HTTP-Statuszeile zurückgibt, antwortet der Server. Wenn curl mit Connection refused fehlschlägt, wurde der Prozess während des Starts beendet. journalctl -u listmonk -n 50 --no-pager gibt den Grund an. Beachten Sie, dass enable --now der Teil ist, der einen Neustart übersteht: Ein manuell gestarteter Prozess ist nach dem nächsten Kernel-Upgrade beendet.

nginx und TLS vorschalten

Listmonk verwendet auf dem Loopback-Interface einfaches HTTP. nginx beendet daher TLS (Transport Layer Security) und leitet die Anfrage weiter.

server {
    listen 443 ssl;
    server_name lists.example.com;

    client_max_body_size 25m;

    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;
    }
}

client_max_body_size muss erhöht werden, weil Abonnentenimporte und Medienuploads Datei-Uploads sind. nginx weist standardmäßig alles über 1 MB mit 413 Request Entity Too Large zurück. Stellen Sie das Zertifikat mit certbot aus. certbot schreibt auch die listen 443 ssl-Zeilen und die Weiterleitung von Port 80 für Sie. Die Schritte finden Sie im Leitfaden zu Let's-Encrypt-Zertifikaten für nginx. Öffnen Sie die Ports 80 und 443. Lassen Sie Port 9000 geschlossen, da der Proxy ihn über das Loopback-Interface erreicht. Wenn die Firewall noch nicht konfiguriert ist, beginnen Sie mit den Grundlagen der ufw-Firewall.

Öffnen Sie anschließend das Administrationspanel und setzen Sie unter Settings die Root-URL auf https://lists.example.com. Eine neue Installation enthält http://localhost:9000. Listmonk schreibt diesen Wert in jeden Abmeldelink und jede Medien-URL, die es in eine E-Mail einfügt. Senden Sie eine Kampagne, bevor Sie den Wert ändern. Dann erhält jeder Empfänger Links, die auf den eigenen Rechner verweisen. Diese Links funktionieren für den Leser nicht. Für einen Spamfilter sehen sie außerdem so aus, als könne der Absender seine eigene Domain nicht konfigurieren.

SMTP verbinden, das nicht in config.toml enthalten ist

Suchen Sie in config.toml nach einem SMTP-Abschnitt. Sie werden keinen finden. Die Maileinstellungen liegen in der Datenbank, in der Tabelle settings. Sie bearbeiten sie im Administrationsbereich unter Settings und SMTP. Deshalb bleibt die erzeugte Datei so kurz. Eine SMTP-Änderung erfordert außerdem keinen Neustart.

Für den SMTP-Server selbst gibt es zwei sinnvolle Optionen. Sie betreiben einen eigenen Server. Damit liegt die Reputation vollständig in Ihrer Hand, und der Betrieb ist ein eigenständiges Projekt: einen eigenen Mailserver mit Mailcow betreiben beschreibt den erforderlichen Aufwand. Oder Sie verbinden Listmonk mit einem Transaktionsrelay und überlassen die IP-Reputation einem anderen Anbieter.

Verwenden Sie in beiden Fällen Port 587 mit STARTTLS oder Port 465 mit implizitem TLS. Planen Sie keinen ausgehenden Port 25 ein. Die meisten VPS-Anbieter blockieren ihn bei neuen Konten standardmäßig. Ein blockierter Port 25 sieht genau wie eine hängende Verbindung aus, weil die Pakete verworfen und nicht abgewiesen werden. Der Client wartet daher auf einen Timeout, statt sofort einen Fehler zu melden.

Testen Sie die Konfiguration, bevor Sie ihr vertrauen. Erstellen Sie eine Liste, fügen Sie Ihre eigene Adresse als Abonnent hinzu und senden Sie eine Kampagne an einen Empfänger. Öffnen Sie die empfangene Nachricht und lesen Sie die vollständigen Header. Der von der empfangenden Seite hinzugefügte Header Authentication-Results zeigt, ob SPF und DKIM erfolgreich waren.

Zustellbarkeit ist die gesamte Aufgabe

Listmonk erstellt die Nachricht, verwaltet die Liste und übergibt die E-Mail. Jede Entscheidung darüber, ob diese E-Mail den Posteingang erreicht, trifft der empfangende Provider anhand der sendenden IP-Adresse und der sendenden Domain. Eine neue VPS-IP-Adresse hat keinerlei Historie. Bei allen großen Mailbox-Providern gilt das als leicht verdächtig.

Vier Dinge sind nicht optional:

  • Ein SPF-(Sender Policy Framework-)TXT-Record, der den zum Senden für Ihre Domain berechtigten Host angibt.
  • Ein DKIM-(DomainKeys Identified Mail-)Schlüssel, der als TXT-Record veröffentlicht wird. Die Signatur muss vom Mailserver und nicht von Listmonk erstellt werden.
  • Ein DMARC-(Domain-based Message Authentication, Reporting and Conformance-)Record, der den Empfängern mitteilt, wie sie verfahren sollen, wenn die ersten beiden Prüfungen fehlschlagen.
  • Ein Bounce-Postfach, das Listmonk liest. Dadurch werden Adressen, die E-Mails ablehnen, aus der Liste entfernt, statt dauerhaft erneut angeschrieben zu werden.

Senden Sie anfangs langsam. Eine Domain, über die bisher keine E-Mails gesendet wurden und die plötzlich zehntausend Nachrichten innerhalb einer Stunde zustellt, entspricht genau dem Muster eines kompromittierten Kontos. Daher wird sie entsprechend gefiltert. Beginnen Sie mit Ihren aktivsten Abonnenten und erhöhen Sie das Volumen über mehrere Tage.

Jede Vorlage benötigt außerdem einen funktionierenden Abmeldelink. In einer Listmonk-Vorlage ist das {{ UnsubscribeURL }}. Der Kampagneninhalt wird an der Stelle eingefügt, an der {{ template "content" . }} steht. Dieser Marker muss in jeder Vorlage genau einmal vorkommen. Eine Kampagne ohne Abmeldelink führt zu Spam-Beschwerden statt zu Abmeldungen. Beschwerden sind der schnellste Weg, eine Absenderreputation zu verlieren, deren Aufbau Wochen gedauert hat.

Backups und was für eine Wiederherstellung tatsächlich erforderlich ist

Zwei Dinge müssen den Server verlassen: der Datenbank-Dump und config.toml. Fügen Sie das Medienverzeichnis hinzu, wenn Sie Bilder in Kampagnen hochladen.

sudo -u postgres pg_dump -Fc listmonk > listmonk-$(date +%F).dump

Der Dump enthält Abonnenten, Kampagnen, Vorlagen und alle Einstellungen, einschließlich der SMTP-Zugangsdaten. Verschlüsseln Sie ihn daher und bewahren Sie ihn außerhalb dieses Servers auf. Die Zeitplanung dafür ist gelöst: Siehe verschlüsselte restic-Backups in einem Remotespeicher. config.toml umfasst nur wenige Zeilen, enthält aber das Datenbankpasswort. Behandeln Sie die Datei daher genauso.

Bei Upgrades ist die Reihenfolge festgelegt. Stoppen Sie den Dienst, erstellen Sie einen Dump, ersetzen Sie die Binärdatei in /usr/bin, führen Sie listmonk --config /etc/listmonk/config.toml --upgrade aus und starten Sie anschließend den Dienst. Schema-Migrationen werden nur vorwärts ausgeführt. Dieser Dump ist daher Ihre einzige Möglichkeit zur Wiederherstellung des vorherigen Zustands.

Warum kann Listmonk nicht gestartet werden?

Lesen Sie zuerst das Journal mit journalctl -u listmonk -n 50 --no-pager. Fast jeder Startfehler steht als eine Zeile im Block [db].

pq: password authentication failed for user "listmonk" bedeutet, dass das Passwort in [db] nicht mit der PostgreSQL-Rolle übereinstimmt. Das Präfix pq weist darauf hin, dass der PostgreSQL-Treiber die Ablehnung des Servers meldet. Die Konfiguration wurde daher korrekt gelesen, aber die Zugangsdaten waren falsch. Setzen Sie die Rolle mit sudo -u postgres psql -c "ALTER USER listmonk WITH PASSWORD 'new-password';" zurück und tragen Sie im Dateiinhalt dieselbe Zeichenfolge ein.

pq: database "listmonk" does not exist bedeutet, dass der Wert database in [db] keine vorhandene Datenbank bezeichnet. sudo -u postgres psql -l listet die Datenbanken auf dem Server auf, einschließlich der Schreibweise, die Sie versehentlich verwendet haben.

permission denied während --install bedeutet, dass die Rolle eine Verbindung herstellen kann, aber nicht Eigentümer der Datenbank ist und deshalb darin keine Tabellen erstellen kann. Beheben Sie das mit sudo -u postgres psql -c "ALTER DATABASE listmonk OWNER TO listmonk;" und führen Sie die Installation erneut aus.

Der Dienst startet nie, und im Journal wird die Konfigurationsdatei genannt. Ein Prozess, der als listmonk ausgeführt wird, kann eine Datei mit config.toml nicht öffnen, wenn diese mit root:root und dem Modus 600 angelegt wurde. stat -c '%U:%G %a' /etc/listmonk/config.toml sollte root:listmonk 640 ausgeben, und das übergeordnete Verzeichnis sollte root:listmonk 750 sein.

Das Panel funktioniert, aber es kommen keine E-Mails an. Das ist kein Startproblem. Prüfen Sie zuerst Settings und SMTP. Prüfen Sie anschließend das Protokoll der Kampagne im Admin-Panel. Dort wird der Fehler erfasst, den der Mailserver bei jedem Versuch zurückgegeben hat.

FAQ

Benötige ich einen eigenen Mailserver, um Listmonk zu verwenden?

Nein. Listmonk ist kein Mailserver. Es benötigt SMTP-Zugangsdaten für einen Server, der Ihre E-Mails annimmt und zustellt. Das kann ein Transaktionsrelay oder ein von Ihnen selbst betriebener Mailserver sein. Tragen Sie diese Zugangsdaten im Administrationsbereich unter Settings und SMTP ein, nicht in config.toml, da die Mail-Einstellungen in der Datenbank gespeichert werden. Verwenden Sie Port 587 mit STARTTLS oder Port 465 mit implizitem TLS, da die meisten VPS-Anbieter ausgehenden Port 25 bei neuen Konten blockieren.

Die Einstellung für die Root-URL verwendet noch den Installationsstandard http://localhost:9000. Listmonk schreibt diesen Wert beim Versand einer Kampagne in Abmeldelinks und Medien-URLs. Öffnen Sie Settings im Administrationsbereich, setzen Sie die Root-URL auf Ihre echte HTTPS-Adresse und speichern Sie die Einstellung. Bereits zugestellte Nachrichten können nicht korrigiert werden. Senden Sie sich daher eine Testkampagne und klicken Sie darin auf den Abmeldelink, bevor Sie eine echte Liste anschreiben.

Werden meine Abonnenten gelöscht, wenn ich --install erneut ausführe?

Ja. --install ist das Installationsprogramm für die erste Einrichtung. Es löscht das vorhandene Listmonk-Schema. --yes entfernt die Abfrage, die Sie davor gewarnt hätte. Verwenden Sie in jedem Skript, das möglicherweise zweimal ausgeführt wird, --install --idempotent --yes. Dieser Befehl führt nichts aus, wenn die Tabellen bereits vorhanden sind. Um die Schemaänderungen einer neuen Version anzuwenden, stoppen Sie den Dienst, erstellen Sie ein pg_dump und führen Sie anschließend --upgrade aus.

Warum meldet Listmonk, dass die Kennwortauthentifizierung für den Benutzer listmonk fehlgeschlagen ist?

Das Kennwort im Block [db] von /etc/listmonk/config.toml stimmt nicht mit dem Postgres-Rollenkonto gleichen Namens überein. Die Journal-Zeile lautet pq: password authentication failed for user "listmonk". pq gibt die Ablehnung des Servers durch den Postgres-Treiber weiter. Das bedeutet, dass die Konfigurationsdatei gefunden und gelesen wurde. Setzen Sie das Kennwort der Rolle mit sudo -u postgres psql -c "ALTER USER listmonk WITH PASSWORD 'new-password';" zurück, schreiben Sie dieselbe Zeichenfolge in die Konfigurationsdatei und führen Sie anschließend sudo systemctl restart listmonk aus.