Listmonk
Overview
Listmonk is a popular open-source, self-hosted newsletter and mailing-list manager. You manage subscribers and lists, design and send campaigns and transactional email through your own SMTP server at high throughput, and track opens and clicks. It is a privacy-respecting alternative to hosted email platforms, and you can deploy it in your own virtual network.
This SecureAnyCloud image runs the Listmonk server, a single Go binary that serves both the admin app and the public pages, behind nginx as a reverse proxy. PostgreSQL is the datastore. The server listens on 127.0.0.1:9000 and is reached through nginx on port 80. The server and the database bind to the loopback interface only.
On the first boot of every VM, a one-shot service recreates an empty database, rotates the PostgreSQL password and initialises the Listmonk schema. It then creates a single super-administrator account with a per-VM password and writes the login to /root/listmonk-credentials.txt with mode 0600. No shared or default credentials ship in the image.
What you get:
- Listmonk 6.1 server binary at
/opt/listmonk/listmonk, with the admin app and public pages in one - nginx reverse proxy on
:80in front of the Listmonk server (bound to loopback:9000) - PostgreSQL datastore for subscribers, lists, campaigns and analytics, bound to loopback
- Two dedicated Azure data disks, re-provisioned with every VM: the PostgreSQL data tier at
/var/lib/postgresql, and the Listmonk binary, config and uploaded media at/opt/listmonk - A per-VM super-administrator login generated at first boot and kept in a root-only file, plus a per-VM database password
listmonk.service,postgresql.serviceandnginx.serviceas systemd units, enabled and active- 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting point. Scale up for very large subscriber bases or high-throughput sending.
Configure the network security group (NSG) to allow inbound 22/tcp from your management network. Also allow 80/tcp (plus 443/tcp once you enable HTTPS) from the networks your team and subscribers use to reach Listmonk.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Listmonk by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).
Review the two dedicated data disks on the Disks tab, then select Review + create and Create.
Step 2 - Deploy from the Azure CLI
Accept the Marketplace terms, create the VM and open port 80:
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:listmonk-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name listmonk \
--image sac1647283583153:listmonk-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name listmonk --port 80 --priority 1010Step 3 - Connect to your VM
Connect over SSH as azureuser:
ssh azureuser@<vm-public-ip>First-boot initialisation completes in under a minute. The credentials file is in place by the time SSH is ready.
Step 4 - Confirm the services are running
Check the three services and the open /health endpoint:
systemctl is-active listmonk.service postgresql.service nginx.service curl -fsS http://127.0.0.1/healthAll three services report active, and the open health endpoint returns {"data":true}. This confirms that the full stack (nginx, the Listmonk server and PostgreSQL) is serving.
Both data tiers live on their own Azure data disks. Confirm the mounts:
findmnt -no SOURCE,SIZE,FSTYPE,TARGET /var/lib/postgresql
findmnt -no SOURCE,SIZE,FSTYPE,TARGET /opt/listmonkStep 5 - Retrieve your administrator login
The super-administrator password is generated uniquely on the first boot of your VM and written to a root-only file. Read it:
sudo cat /root/listmonk-credentials.txtThe file contains the Listmonk admin URL, the administrator username and the password, plus the PostgreSQL login for the local database. To confirm that the admin API authenticates end to end, run this from the same session:
PASS=$(sudo grep '^listmonk.admin.pass=' /root/listmonk-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'no session -> HTTP %{http_code}\n' http://127.0.0.1/api/settings
CJ=$(mktemp)
curl -s -o /dev/null -c "$CJ" --data-urlencode "username=admin" --data-urlencode "password=$PASS" http://127.0.0.1/admin/login
curl -s -o /dev/null -w 'signed in -> HTTP %{http_code}\n' -b "$CJ" http://127.0.0.1/api/settings rm -f "$CJ"The unauthenticated request is rejected. The same request, with a session signed in using the per-VM password, returns HTTP 200.
Step 6 - First sign-in
Open http://<vm-public-ip>/admin in a web browser. Listmonk shows its sign-in page. Enter the username admin and the password from /root/listmonk-credentials.txt, then select Login.
After you sign in, the dashboard shows subscribers, lists, campaign views and click analytics at a glance.
Step 7 - Configure your SMTP server
The image ships no email-sending credentials, so you bring your own SMTP server. Open Settings > SMTP and enable a server. Enter the host, port and credentials of your provider, such as Azure Communication Services, Amazon SES, SendGrid, Mailgun, a corporate relay or any SMTP endpoint.
Select Test connection to verify, then select Save. Campaigns do not send until SMTP is configured.
Step 8 - Create lists, import subscribers and send a campaign
Open Lists to create your first mailing list. A list can be public or private, with single or double opt-in. Import subscribers under Subscribers > Import (CSV), or let people subscribe through the public form pages that Listmonk serves on the same port.
Next, open Campaigns > New campaign and pick the list. Write your content as rich text, Markdown, raw HTML or a saved template. Send yourself a test from the Preview pane, then select Start to run the campaign. Opens, clicks and bounces are tracked per campaign under Analytics.
Security baseline
The image ships fully patched at capture time and keeps patching itself. Ubuntu's unattended-upgrades service is enabled, so security updates install automatically on your running VM. Verify the state at any time:
systemctl is-enabled unattended-upgrades grep -h . /etc/apt/apt.conf.d/20auto-upgrades
sudo ss -tlnp | grep -E ':(9000|5432) ' || trueThe Listmonk server (:9000) and PostgreSQL (:5432) are bound to the loopback interface only. nginx on :80 is the single network-facing entry point.
Enabling HTTPS
For any production deployment, serve Listmonk over HTTPS so that logins and subscriber data cannot be intercepted. The image ships with nginx, which certbot can configure automatically.
The commands below assume a DNS record that points your fully qualified domain name at the VM's public IP address, and 443/tcp open in the NSG:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d news.your-domain.example \
--non-interactive --agree-tos -m you@your-domain.example \
--redirectAfter certbot finishes, sign in and set Settings > General > Root URL to https://news.your-domain.example. Links in your emails (unsubscribe, tracking, archive) then use the HTTPS address.
Backup and maintenance
Listmonk keeps all of its state in PostgreSQL: subscribers, lists, campaigns, templates, settings and analytics. Any uploaded media is under /opt/listmonk/uploads. Back up both regularly:
sudo -u postgres pg_dump listmonk > <backup-dir>/listmonk-db-$(date +%F).sql
sudo tar czf <backup-dir>/listmonk-uploads-$(date +%F).tgz -C /opt/listmonk uploadsThe database (/var/lib/postgresql) and the application directory (/opt/listmonk) are each on their own Azure data disk, so you can also take coordinated disk snapshots in Azure.
Keep the OS patched with sudo apt update && sudo apt upgrade. To upgrade Listmonk, replace /opt/listmonk/listmonk with a newer release, run ./listmonk --upgrade, and restart the service. See https://listmonk.app/docs/.
Support
This image is backed by 24/7 SecureAnyCloud support. Guaranteed response within 24 hours, one hour average for critical issues. Contact sales@secureanycloud.com for help with deployment, SMTP and deliverability configuration, upgrades, TLS termination and database administration.
For general Listmonk questions, consult the documentation at https://listmonk.app/docs/. Listmonk is a trademark of its respective owner; use here is nominative and does not imply affiliation or endorsement. All product and company names are trademarks or registered trademarks of their respective holders.
Deploy on Azure
Launch Listmonk on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
Listmonk is an open-source, self-hosted newsletter and mailing-list manager. You manage subscribers and lists, design and send campaigns and transactional email through your own SMTP server at high throughput, and track opens and clicks.
This SecureAnyCloud image runs the Listmonk server behind nginx as a reverse proxy, with PostgreSQL as the datastore for subscribers, lists, campaigns and analytics.
What you get:
- The Listmonk server on
127.0.0.1:9000, reached through nginx on port 80 (and 443 once you add TLS) - nginx and PostgreSQL bound to the loopback interface only
- A super-administrator account and a PostgreSQL password generated on the first boot of every deployed instance, with the login written to
/root/listmonk-credentials.txtwith mode 0600 - No email-sending credentials. You configure your own SMTP server after signing in
Prerequisites
Before you deploy this image, you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from the networks your administrators use
- The AWS CLI (version 2) installed locally, if you plan to deploy from the command line
- SMTP credentials for sending email (Amazon SES, or any provider)
Launch the instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for Listmonk. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login).
Under Network settings, select your VPC and subnet. Create or select a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from the networks your administrators use. Leave the root volume at the default size or larger.
Select Launch instance. First-boot initialisation takes approximately one minute after the instance state becomes Running and the status checks pass.
Launch the instance from the AWS CLI
Run the command below to launch an instance from the SecureAnyCloud Listmonk Marketplace AMI into an existing subnet and security group. Replace the values in angle brackets:
- <ami-id>: the AMI ID shown on the Marketplace listing
- <key-name>: your EC2 key pair name
- <subnet-id>: your subnet ID
- <security-group-id>: a security group that opens ports 22, 80 and 443 as described above
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":30,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=listmonk-01}]'On success, the command prints a JSON document. Note the instance ID. Once the instance is running, retrieve its public address with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.
Connect and retrieve the administrator login
Connect over SSH with the key pair you selected and the public IP address from step 2. The SSH login user depends on the operating system of the AMI variant you launched. For Listmonk 6 on Ubuntu 24.04, the user is ubuntu.
The first-boot service runs before the SSH daemon is ready, so the credentials file is always in place when you first log in. Read it:
ssh <login-user>@<public-ip>
sudo cat /root/listmonk-credentials.txtThe file is plain text. It contains the Listmonk URL, the admin username and the password.
From the same SSH session, confirm that the deployment is healthy. The health endpoint is open:
curl -fsS http://127.0.0.1/health{"data":true}A {"data":true} response confirms that the full stack (nginx, the Listmonk server and PostgreSQL) is serving.
First sign-in
Open http://<public-ip>/admin in a web browser. Listmonk shows its sign-in page. Enter the username admin and the password from /root/listmonk-credentials.txt, then select Login.
After you sign in, the dashboard shows lists, subscribers, campaigns and analytics at a glance.
Configure SMTP
The image ships no email-sending credentials, so you must connect an SMTP server before you send. Open Settings, select the SMTP tab, and enter your provider's host, port, authentication and credentials.
For Amazon SES, use your SES SMTP endpoint (for example email-smtp.eu-west-1.amazonaws.com, port 587) and SES SMTP credentials. Send a test, then save.
Create lists and import subscribers
Open Lists and create a list, with single or double opt-in. Then open Subscribers to add subscribers individually or import them in bulk from a CSV file. You can segment subscribers with SQL-like queries and attributes.
Build and send a campaign
Open Campaigns, then select Create new. Give the campaign a name and subject, choose the lists to send to, and pick a format: rich text, HTML, Markdown or plain text. Compose the content.
Send a test message to yourself, then schedule or send the campaign. Track opens, clicks and bounces from the campaign's analytics.
Enable HTTPS with Let's Encrypt
For any production deployment, serve Listmonk over HTTPS so that the admin session and subscriber data cannot be intercepted. The image ships with nginx, which certbot can configure automatically.
The commands below assume a DNS record that points your fully qualified domain name at the instance's public IP address.
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d listmonk.your-domain.example \
--non-interactive --agree-tos -m you@your-domain.example \
--redirectAfter certbot finishes, open Settings, then General, and set the root URL to your HTTPS address. Links and unsubscribe URLs in emails then use the correct address.
Backups and maintenance
Listmonk keeps all of its state in PostgreSQL: subscribers, lists, campaigns, templates and analytics. Any uploaded media is under /opt/listmonk. Back up both:
sudo -u postgres pg_dump listmonk > <backup-dir>/listmonk-db-$(date +%F).sql
sudo tar -czf <backup-dir>/listmonk-uploads-$(date +%F).tgz -C /opt/listmonk uploadsShip both files to an Amazon S3 bucket or another object store. Because the database is on its own EBS volume, you can also take coordinated EBS snapshots.
Ubuntu's unattended-upgrades is enabled by default for kernel and package updates. To upgrade Listmonk, replace /opt/listmonk/listmonk with a newer release and run sudo systemctl stop listmonk && sudo -u listmonk /opt/listmonk/listmonk --config /opt/listmonk/config.toml --upgrade --yes && sudo systemctl start listmonk. Always back up first. See https://listmonk.app/docs/.
Scaling and deliverability
- Move PostgreSQL to Amazon RDS for PostgreSQL and update the
[db]section of/opt/listmonk/config.toml - Use Amazon SES for high-volume, reputable sending, and configure SPF, DKIM and DMARC on your sending domain for deliverability
- Put the web tier behind an Application Load Balancer and serve uploaded media through Amazon CloudFront
Each of these is documented in the official Listmonk documentation at https://listmonk.app/docs/.
Support
SecureAnyCloud provides 24/7/365 expert technical support for this image. Guaranteed response within 24 hours, one hour average for critical issues. Contact sales@secureanycloud.com.
For general Listmonk questions, consult the documentation at https://listmonk.app/docs/. Listmonk is a trademark of its respective owner; use here is nominative and does not imply affiliation or endorsement.
Deploy on AWS
Launch Listmonk on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com