Install Mailtrain Self-Hosted Newsletter App on Ubuntu 22.04 with Docker
This tutorial will show you how to install Mailtrain on Ubuntu 22.04. Mailtrain is an open-source self-hosted newsletter app, an alternative to commercial email service providers like Mailchimp. You can use Mailtrain to send emails to your email subscribers via your own email server or by using any email-sending service (Sendinblue, SendGrid, AmazonSES, Mailgun, etc) via SMTP relay.
Mailtrain is released under the terms of GPL v3.0 license, built on Node.js and MySQL/MariaDB. Features of Mailtrain are as follows:
- It allows you to easily manage large mailing lists (like 1 million subscribers).
- You can add subscribers manually, through the API, or import from a CSV file.
- It supports custom fields (text fields, numbers, drop-downs or checkboxes), merge tags and custom forms.
- List segmentation.
- RSS campaign: auto-generate newsletter from RSS feed and send it to subscribers.
- Subscribers can upload their GPG public keys and Mailtrain will encrypt the newsletter for them.
- It allows you to check individual click statistics for every link.
- Advanced email template editors and HTML code editor.
- Automation: send specific emails when user activates your predefined trigger.
- You can create an open email list (allow public subscription) and closed email list (subscribers are added to the list by admin).
- Create multiple users with granular user permissions and flexible sharing.
- Hierarchical namespaces for enterprise-level situations
- Localize the user interface per user
- List export
- Ability to send to multiple lists with prevention of double delivery.
- Multiple send configurations
- SMTP Throttling to prevent your server from sending a large volume of emails in a short amount of time, which will improve email deliverability.
- If you need to send emails as fast as possible, simply configure Mailtrain to use as many sender processers as you want, as long as the server has enough CPU and RAM resources.
Step 1: Choose the Right Hosting Provider
Self-hosting can save you a lot of money. Mailtrain is free and open-source software. You only need to pay about $20/month for the VPS (virtual private server), which can run a full-featured mail server and the Mailtrain email marketing platform. It can easily handle millions of subscribers. So your total cost is always $26/month no matter how many subscribers you have. If you own millions of subscribers on MailChimp, the cost would be thousands of dollars per month.
It’s not an easy task to find a VPS (Virtual Private Server) provider suitable for email hosting and email marketing. Many hosting companies like DigitalOcean blocks port 25. DigitalOcean would not unblock port 25, so you will need to set up SMTP relay to bypass blocking, which can cost you additional money. If you use Vultr VPS, then port 25 is blocked by default. They can unblock it if you open a support ticket, but they may block it again at any time if they decide your email sending activity is not allowed. Vultr actually may re-block it if you use their servers to send newsletters.
Another problem is that big well-known hosting providers like DigitalOcean or Vultr are abused by spammers. Often the server IP address is on several blacklists. Vultr has some entire IP ranges blacklisted.
ScalaHosting is a very good option to run a mail server because
- They don’t block port 25.
- The IP address isn’t on any email blacklist. (At least this is true in my case. I chose the Dallas data center.) You definitely don’t want to be listed on the dreaded Microsoft Outlook IP blacklist or the SpamRats blacklist. Some blacklists block an entire IP range and you have no way to delist your IP address from this kind of blacklists.
- You can edit PTR record to improve email deliverability.
- They allow you to send newsletters to your email subscribers with no hourly limits or daily limit, whatsoever. Note that you are not allowed to send spam, also known as unsolicited bulk email. If the recipient doesn’t explicitly give you permission to send emails, and you send emails to them, that’s unsolicited email.
I recommend following the tutorial linked below to properly set up a Linux VPS server on ScalaHosting. Use coupon code linuxbabe2021
on ScalaHosting payment page to save $100 if you choose to pay 12 months upfront.
You also need a domain name. I registered my domain name from NameCheap because the price is low and they give you whois privacy protection free for life.
If you don’t have your own mail server yet, I recommend using the free iRedMail program to quickly set up your own mail server before installing Mailtrain, so you don’t have to spend money on commercial SMTP relay service.
Step 2: Install Docker on Ubuntu 22.04 Server
The easiest way to install Mailtrain is by using Docker. First, we need to install Docker and Docker Compose, the latest version of which can be installed from Docker’s official repository.
Create a source list file for Docker repository.
echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list
Then import Docker’s PGP key by running the command below.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Since this repository uses HTTPS connection, we also need to install apt-transport-https
and ca-certificates
package.
sudo apt install apt-transport-https ca-certificates
Next, update package index and install the latest version of Docker CE (Community Edition).
sudo apt update sudo apt install -y docker-ce docker-compose
Once installed, the Docker daemon should be automatically started. You can check it with:
systemctl status docker
Output:
● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2022-07-11 09:42:28 SAST; 26s ago TriggeredBy: ● docker.socket Docs: https://docs.docker.com Main PID: 387272 (dockerd) Tasks: 8 Memory: 31.8M CGroup: /system.slice/docker.service └─387272 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
If it’s not running, then start the daemon with this command:
sudo systemctl start docker
And enable auto-start on system boot:
sudo systemctl enable docker
Check Docker version.
docker -v
Sample output:
Docker version 20.10.17, build 100c701
Check Docker Compose version.
docker-compose --version
Sample output:
docker-compose version 1.25.0, build unknown
Step 3: Install MariaDB Database Server
Note: If you followed my iRedMail tutorial to set up your email server, then you should already have MariaDB up and running, so you can skip this step.
Your subscribers’ data will be stored in a database. Mailtrain supports MySQL and MariaDB. MariaDB is a drop-in replacement for MySQL. It is developed by former members of MySQL team who are concerned that Oracle might turn MySQL into a closed-source product. So let’s install the MariaDB database server.
Enter the following command to install MariaDB on Ubuntu 20.04.
sudo apt install mariadb-server mariadb-client
After it’s installed, MariaDB server should be automatically started. Use systemctl to check its status.
systemctl status mariadb
Output:
● mariadb.service - MariaDB 10.3.22 database server Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2020-04-10 14:19:16 UTC; 18s ago Docs: man:mysqld(8) https://mariadb.com/kb/en/library/systemd/ Main PID: 9161 (mysqld) Status: "Taking your SQL requests now..." Tasks: 31 (limit: 9451) Memory: 64.7M CGroup: /system.slice/mariadb.service └─9161 /usr/sbin/mysqld
If it’s not running, start it with this command:
sudo systemctl start mariadb
To enable MariaDB to automatically start at boot time, run
sudo systemctl enable mariadb
By default, MariaDB listens on localhost (127.0.0.1), but later Mailtrain needs to access MariaDB from the Docker network (172.18.0.0/24), so we need to configure MariaDB to listen on all network interfaces. Edit MariaDB config file.
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
Set bind-address
to 0.0.0.0
.
bind-address = 0.0.0.0
Save and close the file. Then restart MariaDB.
sudo systemctl restart mariadb
Allow Docker to access MariaDB database.
sudo ufw insert 1 allow in from 172.17.0.0/24 sudo ufw insert 1 allow in from 172.18.0.0/24
Step 4: Create a Database and User for Mailtrain
Run the following command to log into MariaDB console.
sudo mysql -u root
Create a database for Mailtrain using the following command. I named it mailtrainv2
, but you can use whatever name you like. (Don’t leave out the semicolon.)
create database mailtrain;
Then enter the command below to create a database user for Mailtrain and grant all privileges of the mailtrain database to the user. Replace mailtrain
and mailtrain_password
with your preferred username and password.
grant all privileges on mailtrain.* to 'mailtrain'@'localhost' identified by 'mailtrain_password'; grant all privileges on mailtrain.* to 'mailtrain'@'%' identified by 'mailtrain_password';
Flush the privileges table for the changes to take effect and then get out of MariaDB console.
flush privileges; exit;
Step 5: Install MongoDB
MongoDB is a document-oriented NoSQL database program. Run the following command to install it.
sudo apt install mongodb
Start MongoDB.
sudo systemctl start mongodb
Enable auto-start at boot time.
sudo systemctl enable mongodb
Check its status:
systemctl status mongodb
Sample output:
mongodb.service - An object/document-oriented database
Loaded: loaded (/lib/systemd/system/mongodb.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2022-07-11 10:03:00 SAST; 1min 4s ago
Docs: man:mongod(1)
Main PID: 390040 (mongod)
Tasks: 23 (limit: 4565)
Memory: 44.5M
CGroup: /system.slice/mongodb.service
└─390040 /usr/bin/mongod --unixSocketPrefix=/run/mongodb --config /etc/mongodb.conf
As you can see, it’s active (running).
Edit MongoDB config file.
sudo nano /etc/mongodb.conf
Find
bind_ip = 127.0.0.1
Change it to
bind_ip = 0.0.0.0
Save and close the file. Then restart MongoDB.
sudo systemctl restart mongodb
Step 6: Install Redis Cache
You can install Redis server for session cache. This will allow Mailtrain to run 5 processes instead of the default single process, which will speed up email delivery if you have lots of email subscribers.
sudo apt install redis -y
After it’s installed, Redis should be automatically started. You can check its status with:
systemctl status redis
Sample output:
● redis-server.service - Advanced key-value store Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2022-07-11 10:06:02 SAST; 3s ago Docs: http://redis.io/documentation, man:redis-server(1) Process: 390794 ExecStart=/usr/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS) Main PID: 390796 (redis-server) Tasks: 4 (limit: 4565) Memory: 2.4M CGroup: /system.slice/redis-server.service └─390796 /usr/bin/redis-server 127.0.0.1:6379
If it’s not running, you can start it with:
sudo systemctl start redis
Enable auto-start at boot time:
sudo systemctl enable redis
Edit Redis config file.
sudo nano /etc/redis/redis.conf
Find
bind 127.0.0.1 ::1
Comment it out.
#bind 127.0.0.1 ::1
Save and close the file. Then restart Redis.
sudo systemctl restart redis
Step 7: Running Mailtrain with Docker
Download Mailtrain files from the Github repository.
sudo apt install git git clone https://github.com/Mailtrain-org/mailtrain.git
Change to the mailtrain
directory.
cd mailtrain
Back up the docker-compose.yml
file.
cp docker-compose.yml docker-compose.yml.backup
Edit the docker-compose.yml
file.
nano docker-compose.yml
Change it to the following.
version: '3' services: mailtrain: image: mailtrain/mailtrain:latest environment: - ADMIN_PASSWORD=Secret_Password - URL_BASE_TRUSTED=https://mailtrain.example.com - URL_BASE_SANDBOX=https://sbox-mailtrain.example.com - URL_BASE_PUBLIC=https://newsletter.example.com - WWW_PROXY=true - WWW_SECRET=GVuMGYAXF0cS3DwezNKUa2w - MONGO_HOST=172.17.0.1 - REDIS_HOST=172.17.0.1 - MYSQL_HOST=172.17.0.1 - MYSQL_PORT=3306 - MYSQL_DATABASE=mailtrain - MYSQL_USER=mailtrain - MYSQL_PASSWORD=mailtrain_password - WITH_ZONE_MTA=false ports: - "3000:3000" - "3003:3003" - "3004:3004" volumes: - mailtrain-files:/app/server/files volumes: mailtrain-files:
Then start containers defined in docker-compose.yml
file.
sudo docker-compose up -d
If everything goes well, you will see a message like below.
The mailtrain_default
network will be created and containers will be running: mailtrain-latest
, as can be seen by issuing the following commands:
sudo docker network ls sudo docker ps
Step 8: Setting up Reverse Proxy
We can use Nginx or Apache web server to set up the reverse proxy.
Nginx
If you use iRedMail, then you should choose Nginx.
Install Nginx web server.
sudo apt install nginx
Create 3 Nginx virtual hosts for the 3 URL endpoints.
sudo nano /etc/nginx/sites-enabled/mailtrain.example.com.conf sudo nano /etc/nginx/sites-enabled/sbox-mailtrain.example.com.conf sudo nano /etc/nginx/sites-enabled/newsletter.example.com.conf
The content of the 3 files are as follows:
mailtrain.example.com.conf
server {
listen 80;
server_name mailtrain.example.com;
access_log /var/log/nginx/mailtrain.access;
error_log /var/log/nginx/mailtrain.error;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
sbox-mailtrain.example.com
server {
listen 80;
server_name sbox-mailtrain.example.com;
access_log /var/log/nginx/sbox-mailtrain.access;
error_log /var/log/nginx/sbox-mailtrain.error;
location / {
proxy_pass http://127.0.0.1:3003;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
newsletter.example.com.conf
server {
listen 80;
server_name newsletter.example.com;
access_log /var/log/nginx/newsletter.access;
error_log /var/log/nginx/newsletter.error;
location / {
proxy_pass http://127.0.0.1:3004;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Save and close the files. Then test Nginx configurations.
sudo nginx -t
If the test is successful, reload Nginx.
sudo systemctl reload nginx
Apache
Install Apache web server.
sudo apt install apache2
Create 3 Apache virtual hosts for the 3 URL endpoints.
sudo nano /etc/apache/sites-enabled/mailtrain.example.com.conf sudo nano /etc/apache/sites-enabled/sbox-mailtrain.example.com.conf sudo nano /etc/apache/sites-enabled/newsletter.example.com.conf
The content of the 3 files are as follows:
mailtrain.example.com
<VirtualHost *:80>
ServerName mailtrain.example.com
ServerSignature Off
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
ErrorLog /var/log/apache2/mailtrain.linuxbabe.org.error
</VirtualHost>
sbox-mailtrain.example.com
<VirtualHost *:80>
ServerName sbox-mailtrain.example.com
ServerSignature Off
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3003/
ProxyPassReverse / http://127.0.0.1:3003/
ErrorLog /var/log/apache2/sbox.mailtrain.linuxbabe.org.error
</VirtualHost>
newsletter.example.com.conf
<VirtualHost *:80> ServerName newsletter.example.com ServerSignature Off ProxyPreserveHost On ProxyPass / http://127.0.0.1:3004/ ProxyPassReverse / http://127.0.0.1:3004/ ErrorLog /var/log/apache2/newsletter.linuxbabe.org.error </VirtualHost>
Save and close the files. You need to enable 3 modules in Apache.
sudo a2enmod proxy proxy_http headers
Then enable the 3 virtual hosts.
sudo a2ensite mailtrain.example.com.conf newsletter.example.com.conf sbox-mailtrain.example.com.conf
Restart Apache web server.
sudo systemctl restart apache2
Step 9: Enable HTTPS
To encrypt the HTTP traffic when you visit Mailtrain, we can enable HTTPS by installing a free TLS certificate issued from Let’s Encrypt. Run the following command to install Let’s Encrypt client (certbot) on Ubuntu.
sudo apt install certbot
If you use Nginx web server, you also need to install the Certbot Nginx plugin.
sudo apt install python3-certbot-nginx
Then run the following 3 command to obtain and install TLS certificate.
sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d mailtrain.example.com sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d sbox.mailtrain.example.com sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d newsletter.example.com
If you use Apache web server, you also need to install the Certbot Apache plugin.
sudo apt install python3-certbot-apache
Then run the following command to obtain and install TLS certificate.
sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d mailtrain.example.com sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d sbox.mailtrain.example.com sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d newsletter.example.com
Where:
--nginx
: Use the nginx plugin.--apache
: Use the Apache plugin.--agree-tos
: Agree to terms of service.--redirect
: Force HTTPS by 301 redirect.--hsts
: Add the Strict-Transport-Security header to every HTTP response. Forcing browser to always use TLS for the domain. Defends against SSL/TLS Stripping.--staple-ocsp
: Enables OCSP Stapling. A valid OCSP response is stapled to the certificate that the server offers during TLS.--email
: Your email address, which is used for account recovery and other important notification messages.
The certificate should now be obtained and automatically installed.
Step 10: Mailtrain Configuratin
Go to https://mailtrain.example.com
. Login with username admin
and password test
.
Then go to Administration
-> Users
page to change your account email address and password.
admin
to something else. The Mailtrain web interface doesn’t provide such option, but you can change the username in MariaDB database using SQL command.Go to Administration
-> Global Settings
page to change default configurations. You should change the service address from http://localhost:3000/
to your sub-domain (https://newsletter.example.com
).
Next, go to Administration
-> send configurations
to configure SMTP settings, so your Mailtrain can send emails. By default, Mailtrain is configured to use ZoneMTA. Click the Edit button to change the default setting.
In the Mailer Settings
, you can use SMTP if you have your own email server or use Amazon SES. Actually, you can also use other SMTP relay services in the SMTP
tab. In the screenshot below, I use my own email server. Emails will be submitted on port 587 with STARTTLS encryption.
If Mailtrain is installed on your email server, then you should use the following SMTP settings. The hostname should be 127.0.0.1
and port should 25
. There’s no need to enable encryption or authentication when talking to localhost.
Save your settings. Then you can create a list to test the functionalities of Mailtrain.
Managing Users and Roles
Mailtrain v2 supports multiple users with granular user permissions and flexible sharing. You can create additional users in the Mailtrain web interface. By default, there are 3 roles a user can take.
- Global master: This is the super admin user.
- Campaign admin
- None
I hope this tutorial helped you install Mailtrain on Ubuntu 22.04 with Docker. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care.
Thanks for the article. I am trying to see if this will fit what I want to do. I have a blog site and I want my readers to be able to subscribe so that when there is a new article, they will get an email. I am suspecting that Maintrain does this. I am having a hard time trying to figure out how to build the subscription form. Do you have any info?
Thanks