If you've ever paid a monthly fee to Mailchimp or ConvertKit just to email a few hundred people, you already know how fast that adds up. Listmonk skips the subscription model entirely. It's a single, self-contained program you run yourself, and if you've already got Proxmox VE running in a closet or a rack somewhere, getting it going costs you about ten minutes and one spare container.
This tutorial walks through the whole process: creating an isolated Linux container for Listmonk, letting the installer handle the database setup, logging into the dashboard for the first time, and getting a test email out the door. By the end you'll have a working newsletter platform that lives entirely on hardware you control.
What You Will Learn
- What Listmonk actually is and who it's a good fit for
- Why running it in a container on Proxmox VE makes sense for a homelab or small business
- What you need in place before you start
- Step-by-step instructions to install it using the community helper script
- What each command in the process actually does
- The errors people run into most often, and how to fix them
- A few habits that will save you from losing a subscriber list down the road
What Is Listmonk?
Listmonk is an open-source newsletter and mailing list manager built by developer Kailash Nadh. It's written in Go and ships as a single binary, which means there's no pile of dependencies to wrangle — the whole application is one executable file plus a PostgreSQL database.
PostgreSQL, if you haven't run into it before, is a free, open-source relational database. Listmonk uses it to store your subscriber lists, campaign content, and delivery statistics. You don't need to know how to administer PostgreSQL to use Listmonk day to day — the installer sets it up for you and Listmonk talks to it automatically.
Once it's running, Listmonk gives you a web dashboard where you can build subscriber lists, design campaigns with a drag-and-drop-ish template editor, segment subscribers with SQL queries if you want to get fancy, and track opens, clicks, and bounces. It doesn't send email on its own — it hands outgoing messages to an SMTP relay you configure, which we'll get to in the prerequisites.
Why Would You Use It?
The obvious reason is cost. Most hosted newsletter tools charge per subscriber, and that bill only grows as your list does. Listmonk has no subscriber cap and no per-send fee — the only cost is the small VM or LXC container it runs in, and the electricity to keep your Proxmox box on.
There's a privacy angle too. Your subscriber data — email addresses, open rates, click behavior — stays on your own infrastructure instead of living on a third-party platform's servers. For anyone dealing with GDPR or just uncomfortable handing customer emails to a SaaS company, that matters.
Honestly, if you're only emailing a dozen friends about a book club, this is overkill — use a free tier somewhere else and save yourself the maintenance. But once your list crosses a few hundred addresses, or you're running a small business newsletter, a community update, or a product changelog, the math starts favoring self-hosting pretty quickly.
Prerequisites
Before you start, make sure you have the following:
- A working Proxmox VE host (8.x or 9.x) with a Debian or Ubuntu LXC template already downloaded, or access to download one during setup
- Root access to the Proxmox VE shell, either through the web console or SSH
- At least 2 vCPU cores and 2 GB of RAM free for the new container — Listmonk itself is lightweight, but PostgreSQL wants some headroom too
- About 8 GB of free storage for the container's disk
- An SMTP relay you can authenticate against — this can be a mail provider like Amazon SES, Mailgun, Brevo, or your own Postfix server. Without one, Listmonk has no way to actually deliver mail
- Basic comfort typing commands into the Proxmox shell
A quick note on that SMTP relay, since people skip this and then wonder why nothing arrives: sending email straight from a residential IP address almost never works. Gmail, Outlook, and most providers will silently drop or spam-folder anything that doesn't come from a server with proper reverse DNS, SPF, and DKIM records. Plan on using a relay from day one rather than trying to send directly.
Step-by-Step Tutorial
Step 1: Open the Proxmox VE Shell
Log into the Proxmox VE web interface, click your node in the left-hand tree, and open Shell. This drops you into a root terminal on the host itself — this is where you'll run the container creation script, not inside an existing VM or container.
Step 2: Run the Community Script
Proxmox VE doesn't ship with app installers built in, so the homelab community maintains a large library of install scripts that automate the whole "create a container, install the app, configure a system service" process. Paste this into the shell:
bash -c "$(curl -fsSL https://community-scripts.github.io/ProxmoxVE/ct/listmonk.sh)"
This downloads and runs the Listmonk installer script maintained by the community-scripts project. It's the same family of scripts used for dozens of other self-hosted apps, so if you've used one before, the flow will look familiar.
Step 3: Choose Default or Advanced Settings
The script asks whether you want Default settings or Advanced. Default is fine for testing — it picks a Debian template, a reasonable disk size, DHCP networking, and an unprivileged container automatically. If you want to set a static IP, pick a specific storage pool, or bump the RAM up front, choose Advanced instead and answer the prompts.
An unprivileged container, by the way, is one where root inside the container doesn't map to real root on the Proxmox host. It's a security boundary — if something inside Listmonk's container is ever compromised, the attacker doesn't automatically get host-level access. Stick with unprivileged unless you have a specific reason not to.
Step 4: Wait for the Install to Finish
The script creates the container, boots it, installs PostgreSQL, downloads the Listmonk binary, initializes the database schema, and sets up a systemd service to keep it running. This usually takes somewhere between three and six minutes depending on your storage speed and internet connection.
When it's done, the script prints a summary with the container's IP address. Write that down — you'll need it in the next step.
Step 5: Open the Listmonk Dashboard
In a browser, go to http://<container-ip>:9000. Port 9000 is Listmonk's default web port. On first load you'll see a setup screen asking you to create a Super Admin account — pick a real email address and a strong password, since this account has full access to every list and campaign.
Step 6: Add an SMTP Relay
Inside the dashboard, go to Settings → SMTP. Add the host, port, username, and password for the relay you set up in the prerequisites. Send a test email from this screen before you do anything else — there's no point building a campaign if the delivery path is broken.
Step 7: Create a List and Send a Test Campaign
Go to Lists, create one (say, "Newsletter"), then add yourself as a subscriber under Subscribers. From Campaigns, create a new campaign, attach it to that list, write something short, and hit send. If it lands in your inbox within a minute or two, you're fully operational.
Commands Explained
| Command | What It Does |
|---|---|
bash -c "$(curl -fsSL .../ct/listmonk.sh)" | Downloads and runs the community install script that creates the container and installs Listmonk plus PostgreSQL inside it |
pct list | Run on the Proxmox host — lists every container and its ID, useful for finding the one you just created |
pct enter <vmid> | Drops you into a root shell inside the specified container, without needing SSH |
systemctl status listmonk | Run inside the container — shows whether the Listmonk service is running and its recent log output |
journalctl -u listmonk -f | Streams live logs from the Listmonk service, handy while troubleshooting a failed send or a crash |
listmonk --upgrade --yes | Applies any pending database schema changes after you update the Listmonk binary to a newer version |
Common Errors
"dial tcp 127.0.0.1:5432: connect: connection refused" — this shows up if Listmonk tries to start before PostgreSQL has finished its own startup, which can happen right after a container reboot. Give it thirty seconds and run systemctl restart listmonk inside the container.
The dashboard won't load at all — double-check the IP address with pct list on the host, and confirm the container actually finished booting. If you're on a VLAN or have a strict firewall, make sure port 9000 isn't being blocked between your workstation and the container.
Test emails never arrive — this is almost always the SMTP relay, not Listmonk. Re-check the username and password under Settings → SMTP, and look at the relay provider's own dashboard (Mailgun, SES, etc.) for a rejected or bounced message. A wrong port number is a common culprit too — 587 with STARTTLS and 465 with implicit TLS are not interchangeable.
Campaigns send but land in spam — this points to missing SPF, DKIM, or DMARC records on the sending domain rather than anything wrong with Listmonk itself. Your SMTP relay provider usually has a setup page walking through exactly what DNS records to add.
Troubleshooting
Start with the logs. Inside the container, journalctl -u listmonk -n 100 shows the last hundred log lines, which is usually enough to spot a crash or a config error. If Listmonk itself looks healthy but PostgreSQL doesn't, check it separately with systemctl status postgresql.
If the web interface loads but looks broken or half-rendered, it's often a stale browser cache from an earlier failed load — a hard refresh (Ctrl+Shift+R) fixes it more often than you'd expect.
For port conflicts, if something else in the container is already bound to 9000, Listmonk will fail to start and the logs will say so directly. That's rare in a fresh container from the install script, but it can happen if you've layered other software on top afterward.
Best Practices
Back up the container. A subscriber list you've built up over months is not something you want to lose because of a bad disk. Set up a scheduled backup job in Proxmox VE (Datacenter → Backup) targeting this container, ideally to Proxmox Backup Server if you have one running.
Put a reverse proxy with a real TLS certificate in front of Listmonk rather than exposing port 9000 directly, especially if you'll ever access it from outside your network. Nginx Proxy Manager or Caddy both work well for this and let you use a proper domain name instead of an IP address and port.
Don't skip SPF, DKIM, and DMARC setup on your sending domain. It's a one-time DNS chore, and without it, your delivery rate will be miserable no matter how good your relay is.
Keep the underlying Debian OS patched with a regular apt update && apt upgrade inside the container, separately from updating Listmonk itself. They're two different maintenance tasks.
Frequently Asked Questions
Is Listmonk really free?
Yes. It's licensed under AGPLv3, with no subscriber limits, no paid tiers, and no feature gating.
Can I use Listmonk for transactional email, like password resets?
Not well. It's built for bulk campaigns and list management, not for triggered, single-recipient transactional messages. Use a dedicated transactional service for that instead.
Do I need to run my own mail server?
No. Any SMTP relay you can authenticate against works — a hosted provider, your ISP's outbound relay, or a Postfix server you already run elsewhere.
How many subscribers can it realistically handle?
Comfortably into the hundreds of thousands on modest hardware. It's a lean Go binary backed by PostgreSQL, so the database is more often the bottleneck than the application itself.
Can I import an existing subscriber list from Mailchimp or another platform?
Yes. Listmonk accepts CSV imports under Subscribers → Import, so migrating an existing list is a matter of exporting from your old platform and uploading the file.
Conclusion
Fifteen minutes ago you had a Proxmox host and an idea for a newsletter. Now you've got a running Listmonk instance, a container you fully control, and a delivery pipeline through your own SMTP relay. It's not going to out-polish a big-name SaaS tool on visual design, but for the price — free, minus a bit of RAM — it does the actual job of getting emails out the door without a monthly invoice attached.
If this is your first time using one of the community install scripts, it's worth knowing the same pattern applies to a long list of other self-hosted software. Once you're comfortable spinning up one container this way, the next one takes even less time.