Self-host Listmonk on a managed VPS: your newsletters on your own server

To self-host Listmonk on a managed VPS is to keep your subscriber lists and campaigns on a machine of your own, which our teams keep up to date and watch day and night. Listmonk is free software under the AGPL-3.0 licence. This guide follows its official documentation: which version to choose, Docker Compose, PostgreSQL, HTTPS, sending over SMTP, bounces, consent, backups and updates.

Simon Vasconcelos Lee By Published on 12 November 202613 minute read

All guides

In short

  1. The AGPL-3.0 licence lets you use Listmonk in business with no licence to buy; if you modify it, your remote users must be able to obtain the source code of your version.
  2. Install stable version 6.2.0 with a fixed Docker tag: version 7, shown first on GitHub, is still a beta.
  3. Docker Compose runs Listmonk and PostgreSQL. Publish port 9000 locally, serve it over HTTPS behind a reverse proxy and fill in its "Root URL".
  4. Listmonk sends through the SMTP servers you configure: for bulk sending, use a specialized email delivery service on port 587, with SPF, DKIM and DMARC on your domain.
  5. Prefer double opt-in, turn on bounce processing, and export the database with pg_dump before every update.

What Listmonk does

Listmonk manages your mailing lists and newsletters from a web interface. It is a single program, written in Go, whose only dependency is PostgreSQL. Its lists are one-way: you write to your subscribers, and it is not a discussion list between them.

What the AGPL-3.0 licence allows

Listmonk is published under the GNU AGPL version 3 licence. You can use it, in business too, and send your own campaigns as well as your clients’, with no licence to buy. What remains is the cost of the server and of your email delivery service.

Section 13 adds a condition specific to the AGPL: if you modify the program, your version must prominently offer everyone who uses it remotely, over a network, the chance to obtain its source code at no charge. If you distribute copies, the licence’s source-sharing obligations apply as well. Running Listmonk unmodified does not trigger this section.

Which version of Listmonk to install?

One point to know before you start. On GitHub, the "Latest" label currently sits on v7.0.0-beta.2 of November 10, 2026, which the project itself presents as a beta. The latest stable version is v6.2.0, which carries security fixes for permissions. As of November 11, 2026, the Docker image latest points to this v6.2.0.

VersionDocker imageStatus
v6.2.0listmonk/listmonk:v6.2.0Stable: the one used in this guide
v7.0.0-beta.2listmonk/listmonk:betaBeta: try it on a copy, with a backup
nightlylistmonk/listmonk:nightlyUntested, according to the project: at your own risk

Version 7 replaces the entire admin interface, changes some of its URLs, turns the app.from_email setting into a list of addresses and changes translation keys, which affects custom templates. Read its release notes before moving to it.

The project’s Compose file runs --upgrade --yes on every start: a new image migrates the database without asking you. A migrated database cannot be read by an older version, and going back means restoring a backup. With a fixed tag such as v6.2.0, changing versions stays your decision.

Installing with Docker Compose

The project recommends Docker Compose: its file runs Listmonk and PostgreSQL together. On a server with Docker installed, create a folder and download this file:

Terminal
mkdir listmonk
cd listmonk
curl -LO https://github.com/knadh/listmonk/raw/master/docker-compose.yml

The project asks you to adapt this file to your environment. These are the only lines to change, and the rest stays as it is:

docker-compose.yml, the lines to change
x-db-credentials: &db-credentials
  POSTGRES_USER: &db-user listmonk
  POSTGRES_PASSWORD: &db-password un-mot-de-passe-long
  POSTGRES_DB: &db-name listmonk

services:
  app:
    image: listmonk/listmonk:v6.2.0
    ports:
      - "127.0.0.1:9000:9000"
    hostname: listmonk.example.com

Then start the services and create the Super Admin account in advance. These two variables are only used on the first start, and without them the account is created on the first visit to the interface: it is best to have it in place before you open your domain.

Terminal
LISTMONK_ADMIN_USER=votre-identifiant LISTMONK_ADMIN_PASSWORD=votre-mot-de-passe docker compose up -d

Without Docker: the binary

Listmonk also runs as a standalone program, alongside your own PostgreSQL server, version 12 or later, where the database already exists.

  1. Download the v6.2.0 archive from the project’s releases page, for example listmonk_6.2.0_linux_amd64.tar.gz, skipping the beta shown first, and extract the binary.
  2. Generate the configuration file, then enter the database credentials in config.toml.
  3. Install the tables, then start Listmonk.
Terminal
./listmonk --new-config
./listmonk --install
./listmonk

By default, config.toml listens on localhost:9000, which suits a reverse proxy. The repository provides a listmonk@.service file for systemd.

Server size

The project’s website cites a production instance sending a campaign of more than 7 million emails with a fraction of a single CPU core and peak memory use of 57 MB. It publishes neither a minimum nor a figure for PostgreSQL, whose volume grows with your subscribers, views and clicks. On a managed VPS, describe your usage to us and we will recommend the right size.

HTTPS and the reverse proxy

Your subscribers click links that point to your instance: unsubscribing, confirming, click tracking. So it is served over HTTPS on its own domain name. Create the A and AAAA records for this name pointing to your server, where visitors arrive on ports 80 and 443. The Listmonk documentation leaves the choice of proxy to you; here are two common configurations.

With Caddy

Caddy obtains and renews the certificate on its own:

Caddyfile
listmonk.example.com {
    reverse_proxy 127.0.0.1:9000
}

With Nginx and Certbot

By default, Nginx rejects requests over 1 MB with a 413 error. To import a subscriber file or images, raise this limit to match your files:

Nginx block
server {
    listen 80;
    listen [::]:80;
    server_name listmonk.example.com;
    client_max_body_size 100m;

    location / {
        proxy_pass http://127.0.0.1:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Certbot then installs the Let’s Encrypt certificate and the redirect to HTTPS, and renews the certificate on its own:

Terminal
sudo certbot --nginx -d listmonk.example.com

First settings

Log in at https://listmonk.example.com/admin, then open "Settings":

What stays public, what can be closed

To filter access, by IP address or through an authentication proxy, the documentation divides the routes this way:

RoutesPurposeAccess
/admin/*, /api/*, /webhooks/bounceThe admin interface, its API and the internal bounce webhookPrivate
/subscription/*, /public/*The subscription pages and their filesPublic
/link/*, /campaign/*Link tracking and the tracking pixelPublic
/webhooks/service/*Bounces sent by your email delivery servicePublic
/uploads/*The images in your emailsPublic

Sending: Listmonk goes through your SMTP servers

Listmonk prepares and paces your emails, then hands them to the SMTP servers you declare in "Settings", "SMTP". It does not deliver them to your subscribers’ inboxes itself: delivery quality depends on that server, your domain and your lists.

For bulk sending, choose a specialized email delivery service: it carries the reputation of your sending and the signatures of your domain, and it can report bounces back. From a Simafri VPS, email goes out through an authenticated SMTP relay on port 587: here, that of this service.

For reference, the Listmonk documentation describes bounces from Amazon SES, Azure Communication Services, SendGrid, Postmark, Forward Email and Lettermint. Compare them according to your volume and your recipients.

SettingValueWhat to check
HostThe SMTP address of your serviceReplaces the example value provided
Port587The presets on this screen often offer another port: switch back to 587
TLSSTARTTLSGoes with port 587
Auth protocolThe one your service uses, often LOGINWith the service’s SMTP username and password

Then click "Test connection": Listmonk sends a test message and shows the server’s error if sending fails. You can declare several servers, choose one per campaign, or route sending by sender address or domain.

Throughput

Set it in "Settings", "Performance", below your service’s limit:

A message that fails is retried according to the "Retries" setting, on other connections to the server. If it fails again, Listmonk logs it as an error and moves on: keep an eye on these errors during a large campaign.

Hosting the application leaves you in charge of these topics, and they decide whether your emails arrive.

SPF, DKIM and DMARC

Send from an address on your domain, and publish in its DNS zone the SPF and DKIM records your email delivery service gives you, along with a DMARC record. Google requires all three from senders of more than 5,000 messages a day to Gmail accounts, with a sending domain aligned with SPF or DKIM, one-click unsubscribe for marketing messages, and a spam report rate below 0.30%, ideally below 0.10%.

Unsubscribing

Your recipients’ consent

Listmonk applies the list type you choose. On a single opt-in list, a subscriber added without confirmation still receives your campaigns. On a double opt-in list, they first receive a confirmation email, and only confirmed subscribers receive your campaigns. This is the choice that best protects your sending reputation and keeps a clear record of the agreement.

The rules depend on your recipients’ country. In France, for example, the data protection authority (CNIL) requires prior consent from individuals, through a positive action such as an unchecked box, with an exception for your customers on similar products or services. Between professionals, prospecting can rest on legitimate interest if it concerns their line of work. In every case, each message identifies the sender and offers a simple way to refuse further messages.

Write only to people who are expecting your messages. A purchased or stale list drives up bounces and spam reports, and your domain bears the consequences.

View and click tracking

The tracking pixel and click tracking touch on privacy, and the documentation asks that they be used in compliance with rules such as the GDPR. By default, this tracking is not tied to each subscriber: the "Individual subscriber tracking" option ties it, and "Disable tracking" turns it off entirely, in "Settings", "Privacy".

Bounces

Continuing to write to an address that rejects your messages damages your sending reputation. Bounce processing is off from the start: turn it on in "Settings", "Bounces", then choose one of these two routes.

For a dedicated mailbox, declare it as the return address in "Settings", "SMTP", "Custom headers":

Custom headers
[
  {"Return-Path": "your-bounce-inbox@example.com"}
]

The starting settings are the ones the documentation gives for SES, and they make a good base:

Bounce typeCountAction
Soft (temporary)2None
Hard (permanent)1Blocklist: the address is blocked
Complaint (spam report)1Blocklist: the address is blocked

PostgreSQL, the only dependency

Listmonk requires PostgreSQL 12 or later. The Compose file brings postgres:17-alpine, with its data in the Docker volume listmonk-data. Subscribers, campaigns, templates, statistics and most settings live there; only the database credentials and the listening address stay in the configuration.

To use an existing PostgreSQL server, change the LISTMONK_db__host, LISTMONK_db__port, LISTMONK_db__user, LISTMONK_db__password and LISTMONK_db__database variables of the app service.

Listmonk is built for large lists. As the database grows, it is what can slow down the interface: with millions of subscribers, the dashboard and counters can take tens of seconds to display. The project then advises two steps:

Terminal, in the docker-compose.yml folder
docker compose exec db psql -U listmonk -d listmonk -c 'VACUUM ANALYZE;'

Backups and updates

Two things make up your instance: the PostgreSQL database and the uploads folder, if your images stay on disk. pg_dump produces a consistent export without stopping Listmonk or blocking other access to the database:

Terminal, in the docker-compose.yml folder
docker compose exec -T db pg_dump -U listmonk listmonk > listmonk-$(date +%F).sql
tar -czf listmonk-uploads-$(date +%F).tar.gz uploads

To restore, stop Listmonk, empty the database and reload the export. As the documentation points out, this wipes the existing database:

Terminal
docker compose stop app
docker compose exec db psql -U listmonk -d listmonk -c 'DROP SCHEMA public CASCADE; CREATE SCHEMA public;'
docker compose exec -T db psql -U listmonk -d listmonk < listmonk-2026-11-01.sql
docker compose start app

Updating

  1. Read the notes for the new version: Listmonk flags new versions in its interface, and some carry security fixes.
  2. Export the database, as the project asks before any update.
  3. Change the image tag in docker-compose.yml.
  4. Run the commands from the documentation. The Compose file migrates the database on startup.
Terminal
docker compose down app
docker compose pull
docker compose up app -d

With the binary, stop Listmonk, replace the binary, run ./listmonk --upgrade, then start it again. To go back to an earlier version, restore the export taken before the update, then put the old tag back.

Who does what on a Managed VPS

Self-hosting means running the server as well as the application. On a Managed VPS, our teams take charge of the server and proactively monitor your instance; Listmonk remains your software, with its settings, your lists and your campaigns.

TopicOur teamsYou
The serverSystem and security updates, server interventions includedThe time that suits your business
MonitoringServer watched 24/7, with intervention without waiting for your callFollowing your campaigns and bounces
ListmonkProactive monitoring: errors, slowdowns and disk space spotted, fix recommendedIts installation, updates and settings, which you apply, yourself or through your AI assistant
SendingA server that reaches your SMTP relay on port 587Your email delivery service, your DNS records, your lists and your recipients’ consent
BackupsEvery night, encrypted and kept off the machine; restores includedThe restore request, and your export before each update
MigrationYour current server migrated, free of chargeThe time of the switchover

If you would rather have our teams work inside the application itself, this service is billed hourly or at a fixed price, with an estimate provided before the work begins.

Listmonk, on a server run for you

With a Simafri Managed VPS, our teams keep your Listmonk instance’s server up to date, monitor it day and night and step in without waiting for your call; they also proactively monitor your instance and recommend useful fixes, which you apply, yourself or through your AI assistant. Backups are encrypted every night and kept off the machine, restores are included, and migrating your current server is free.

Explore Managed VPS

Frequently asked questions

Is Listmonk free for a business?

Yes. Listmonk is under the AGPL-3.0 licence: you can use it in business with no licence to buy. If you modify it, your remote users must be able to obtain the source code of your version. What remains is the cost of the server and of your email delivery service.

Which version of Listmonk should I install?

v6.2.0, the latest stable version as of November 11, 2026. v7.0.0-beta.2, shown first on GitHub, is a beta. In Docker Compose, pin the image to listmonk/listmonk:v6.2.0: changing versions then stays your decision, since a migrated database cannot be read by an older version.

How do I install Listmonk with Docker Compose?

Download the project’s docker-compose.yml file, change the database password and the image tag, then run docker compose up -d. The interface responds on port 9000, with PostgreSQL alongside it. Serve it over HTTPS behind a reverse proxy and fill in its Root URL.

Which SMTP server should I use with Listmonk?

Listmonk sends through the SMTP servers you configure. For bulk sending, use a specialized email delivery service, with STARTTLS on port 587, and publish SPF, DKIM and DMARC on your domain. The Listmonk documentation describes bounces from Amazon SES, SendGrid and Postmark, for example.

How do I handle bounces in Listmonk?

Turn on processing in Settings, Bounces, then connect your email delivery service’s webhook or a dedicated POP3 mailbox. The starting settings block an address after one permanent bounce or one spam report.

How do I back up Listmonk?

Export the database with pg_dump, without stopping the service, and keep the uploads folder if your images are on disk. The project asks for this export before every update, since an earlier version cannot read a database that has already been migrated.

Does Listmonk handle consent and unsubscribing?

It gives you the tools: double opt-in lists, an unsubscribe link in your templates, a List-Unsubscribe header, and data export and erasure by the subscriber. Collecting consent itself is up to you, according to the rules of your recipients’ country.

Does a Managed VPS cover Listmonk?

A Managed VPS covers the server: system, security, monitoring and backups. Our teams also proactively monitor your instance and recommend useful fixes, which you apply. Work inside the application is billed hourly or at a fixed price.

Contact us