Innovate | Connect | Transform
ContactService statusUSD $

GICT knowledge base

Self-Hosted Newsletter with Listmonk: The Mailchimp Alternative You Run on Your VPS

Published

Email
Self-Hosted Newsletter with Listmonk: The Mailchimp Alternative You Run on Your VPS

Mailchimp charges you per subscriber. Send to 100,000 people and you are paying $100 or more every month. Listmonk flips this. It is a self-hosted newsletter and mailing list manager that runs on a $10 VPS. It handles subscriber management, list segmentation, email campaigns, transactional emails, and analytics. It talks to any SMTP provider: Amazon SES, Mailgun, SMTP2GO, or your own mail server. This article covers the full setup on a VPS, from zero to a live campaign.

What you need before starting

  • A VPS with Ubuntu 24.04 and at least 1GB RAM
  • Docker and Docker Compose installed on the server
  • A domain name pointed to your server (optional but recommended)
  • An SMTP provider for sending emails

If you do not have an SMTP provider yet, SMTP2GO has a free tier of 1,000 emails per month. Amazon SES is the cheapest option for high volume at $0.10 per 1,000 emails.

Step 1: Install Docker on your VPS

Log into your server and install Docker if it is not already there:

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
docker compose version

The last command should print a version number. If it does, Docker is ready.

Step 2: Download Listmonk

Create a directory for Listmonk and download the official docker-compose file:

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

Set your admin credentials when you start the container:

LISTMONK_ADMIN_USER=admin LISTMONK_ADMIN_PASSWORD=YourSecurePassword123 \
  docker compose up -d

The admin user is created automatically on first start if you set these environment variables. Otherwise, visit port 9000 after starting and create the account through the web interface.

Step 3: Start Listmonk

docker compose up -d

Watch the logs to confirm everything started cleanly:

docker compose logs --follow

Press Ctrl+C after confirming the app is running. Verify both containers are up:

docker compose ps

You should see two containers: listmonk_app and listmonk_db, both showing as healthy or up. At this point, Listmonk is running on port 9000 of your server.

Step 4: Set up Nginx as a reverse proxy with SSL

Do not expose port 9000 directly to the internet. Put Nginx in front of it and add a free SSL certificate from Let us Encrypt.

Install Nginx and Certbot:

sudo apt install nginx certbot python3-certbot-nginx -y

Create an Nginx config for Listmonk. Replace news.example.com with your actual domain:

sudo nano /etc/nginx/sites-available/listmonk

Add this configuration:

server {
    listen 80;
    server_name news.example.com;

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

Enable the site and get an SSL certificate:

sudo ln -s /etc/nginx/sites-available/listmonk /etc/nginx/sites-enabled/
sudo nginx -t
sudo certbot --nginx -d news.example.com

Follow the prompts. Certbot will automatically modify the config to add SSL. Your Listmonk instance is now accessible at https://news.example.com with HTTPS.

Step 5: Configure your SMTP provider

Log into Listmonk at your domain and go to Settings, then SMTP. The fields depend on your provider.

For Mail.baby (free tier works fine for testing):

  • Host: email_server_hostname
  • Port: 587
  • Auth protocol: LOGIN
  • Username: your username
  • Password: your password
  • TLS: STARTTLS

For Amazon SES, use your SMTP credentials from the SES console. Set host to email-smtp.us-east-1.amazonaws.com (replace with your region) and port to 587.

Sending limits: Most SMTP providers have daily or monthly sending limits. SMTP2GO free tier allows 1,000 emails per month with a 200/day cap. Amazon SES is effectively unlimited for production use but requires domain verification and a production access request.
Start sending E-mails using simplest and most affordable SMTP service -> mail.baby

Step 6: Create a subscriber list and send your first campaign

Go to Lists in the sidebar and rename the default list to match your newsletter. Choose between single opt-in (subscribers added immediately) and double opt-in (subscribers must confirm via email). Double opt-in produces a cleaner list but reduces confirmed subscriber rates.

Copy the subscription form HTML from the list settings and embed it on your website. It is a clean form that talks directly to your Listmonk instance.

To send a campaign, go to Campaigns and create a new one. Give it a name you will recognize (internal only), set the subject line, choose your list, and select Email as the messenger. The content editor supports a visual block editor, raw HTML, or plain text. Listmonk uses Go templates, so you can personalize emails using variables like {{ .Subscriber.Name }}.

Use the Preview button to see exactly what subscribers will receive. When ready, click Start Campaign. Listmonk queues all emails and sends them in the background. Monitor progress in the campaign view.

Upgrading Listmonk

Listmonk releases are tagged as a single binary. To update, pull the new image and restart:

cd ~/listmonk
docker compose pull
docker compose up -d

The database migrations run automatically on startup via the –upgrade –yes flag in the compose file.

What you end up with

A working newsletter system that you own and control. The server costs $10 to $20 per month. There is no per-subscriber fee and no platform taking a cut of your audience. The data stays on your VPS, and you connect any SMTP provider you choose.

Related guides

Account services are unavailable until the production backend is configured.