Mailtrain is an open-source, self-hosted newsletter application built on Node.js and MySQL/MariaDB. It gives you full control over subscriber management, email campaigns, list segmentation, automation, and templates – without relying on paid services like Mailchimp or SendGrid. Mailtrain supports multiple users, custom fields, RSS campaigns, and integrates with any SMTP provider for delivery.
Note: Mailtrain’s last official release was in June 2021. The GitHub repository still receives community contributions but is not under active development. The software works well for self-hosted newsletter needs, but keep this in mind for long-term planning. This guide covers installing Mailtrain v2 on Ubuntu 24.04 with Node.js 20, MariaDB, Nginx reverse proxy, and SSL.
Prerequisites
- A server running Ubuntu 24.04 LTS with at least 2 vCPUs and 4GB RAM
- Root or sudo access
- A registered domain name pointing to your server IP (e.g. newsletter.example.com)
- Ports 80, 443, and 25 (SMTP) open in your firewall
- An SMTP relay service or local mail server for sending emails
Step 1: Install Node.js 20 LTS on Ubuntu 24.04
Mailtrain v2 requires Node.js 14 or later. We will install Node.js 20 LTS from the NodeSource repository, which provides a stable and well-supported runtime.
Start by installing dependencies and adding the NodeSource repository.
sudo apt update
sudo apt install -y curl gnupg2 ca-certificates
Add the NodeSource repository for Node.js 20.
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
Install Node.js from the repository.
sudo apt install -y nodejs
Verify that Node.js and npm are installed correctly.
node -v
npm -v
The output should show Node.js 20.x and npm version 10.x or later.
Step 2: Install MariaDB Server
Mailtrain stores subscriber data, campaign information, and configuration in a MySQL-compatible database. MariaDB is a solid choice and ships in the Ubuntu 24.04 default repositories.
sudo apt install -y mariadb-server mariadb-client
Start and enable the MariaDB service.
sudo systemctl enable --now mariadb
Confirm the service is running.
sudo systemctl status mariadb
The status should show active (running). Run the security hardening script to set the root password and remove test databases.
sudo mariadb-secure-installation
Accept the defaults – set a root password, remove anonymous users, disable remote root login, and remove the test database.
Step 3: Create the Mailtrain Database and User
Log in to the MariaDB shell as root.
sudo mariadb -u root -p
Create a dedicated database and user for Mailtrain. Replace StrongPassword123 with your own secure password.
CREATE DATABASE mailtrain CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'mailtrain'@'localhost' IDENTIFIED BY 'StrongPassword123';
GRANT ALL PRIVILEGES ON mailtrain.* TO 'mailtrain'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Step 4: Clone and Install Mailtrain
Clone the Mailtrain v2 repository from GitHub into /opt/mailtrain.
sudo apt install -y git build-essential python3
cd /opt
sudo git clone https://github.com/Mailtrain-org/mailtrain.git
cd mailtrain
sudo git checkout v2
Install the npm dependencies for the server, client, shared, and zone-mta components.
cd /opt/mailtrain/server
sudo npm install --unsafe-perm
cd /opt/mailtrain/client
sudo npm install --unsafe-perm
Build the client-side assets.
cd /opt/mailtrain/client
sudo npm run build
Install dependencies for the shared library.
cd /opt/mailtrain/shared
sudo npm install --unsafe-perm
Install Zone-MTA dependencies if you plan to use the built-in mail transport agent.
cd /opt/mailtrain/zone-mta
sudo npm install --unsafe-perm
Step 5: Configure Mailtrain
Mailtrain uses YAML configuration files. The default settings are in server/config/default.yaml. Create a production override file to set your database credentials and domain.
sudo vi /opt/mailtrain/server/config/production.yaml
Add the following configuration. Replace the domain names, database password, and secret values with your own.
www:
host: 127.0.0.1
proxy: true
secret: "replace-with-a-long-random-string"
trustedUrlBase: "https://newsletter.example.com"
sandboxUrlBase: "https://sbox-newsletter.example.com"
publicUrlBase: "https://newsletter.example.com"
mysql:
host: localhost
user: mailtrain
password: StrongPassword123
database: mailtrain
redis:
enabled: false
log:
level: info
The proxy: true setting tells Mailtrain it runs behind Nginx and should trust the X-Forwarded-For headers. The trustedUrlBase is the URL where administrators log in, while publicUrlBase is where subscribers interact with campaigns.
Step 6: Create a Systemd Service for Mailtrain
Create a dedicated system user to run Mailtrain.
sudo useradd -r -s /usr/sbin/nologin mailtrain
sudo chown -R mailtrain:mailtrain /opt/mailtrain
Create the systemd service file.
sudo vi /etc/systemd/system/mailtrain.service
Add the following service configuration.
[Unit]
Description=Mailtrain Newsletter Application
After=network.target mariadb.service
[Service]
Type=simple
User=mailtrain
Group=mailtrain
WorkingDirectory=/opt/mailtrain/server
ExecStart=/usr/bin/node index.js
Environment=NODE_ENV=production
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Reload systemd, then start and enable the Mailtrain service.
sudo systemctl daemon-reload
sudo systemctl enable --now mailtrain
Check the service status to confirm it started without errors.
sudo systemctl status mailtrain
The output should show active (running). If there are errors, check the logs with journalctl -u mailtrain -f to troubleshoot.
Mailtrain listens on port 3000 (trusted), 3003 (sandbox), and 3004 (public) by default. Verify the ports are open.
ss -tlnp | grep node
You should see Node.js listening on ports 3000, 3003, and 3004.
Step 7: Configure Nginx as a Reverse Proxy
Nginx will handle incoming HTTPS connections and proxy requests to Mailtrain’s internal ports. Install Nginx first.
sudo apt install -y nginx
Create the Nginx virtual host configuration for Mailtrain.
sudo vi /etc/nginx/sites-available/mailtrain
Add the following configuration. Replace newsletter.example.com with your actual domain.
server {
listen 80;
server_name newsletter.example.com;
client_max_body_size 50M;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
}
}
server {
listen 80;
server_name sbox-newsletter.example.com;
location / {
proxy_pass http://127.0.0.1:3003;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
}
}
Enable the site and test the Nginx configuration.
sudo ln -s /etc/nginx/sites-available/mailtrain /etc/nginx/sites-enabled/
sudo nginx -t
If the syntax test passes, restart Nginx to apply the changes.
sudo systemctl restart nginx
Step 8: Enable SSL with Let’s Encrypt
Secure the Mailtrain web interface with a free SSL certificate from Let’s Encrypt using Certbot.
sudo apt install -y certbot python3-certbot-nginx
Request certificates for both domains.
sudo certbot --nginx -d newsletter.example.com -d sbox-newsletter.example.com
Certbot will automatically modify the Nginx configuration to add SSL settings and redirect HTTP to HTTPS. Follow the prompts to provide your email address and accept the terms.
Verify the certificate auto-renewal timer is active.
sudo systemctl status certbot.timer
The timer should show as active (waiting), which means certificates will renew automatically before expiration.
Step 9: Configure the Firewall
If UFW is enabled on your server, open the required ports for web traffic and SMTP.
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 25/tcp
sudo ufw reload
Verify the firewall rules are in place.
sudo ufw status
You should see ports 80, 443, and 25 listed as ALLOW. Do not expose ports 3000, 3003, or 3004 directly – Nginx handles all external traffic.
Step 10: Configure SMTP Relay for Email Delivery
Mailtrain needs an SMTP server to send newsletter emails. You can use any SMTP provider – Amazon SES, Mailgun, SendGrid, or your own mail server. Configure the SMTP settings in the Mailtrain web interface after login.
Open your browser and navigate to https://newsletter.example.com. Log in with the default credentials.
- Username:
admin - Password:
test
Change the default password immediately after your first login. Go to Administration > Users and update the admin account.
To configure SMTP, navigate to Administration > Send Configurations. Create a new send configuration or edit the default one with your SMTP provider details.
- Hostname – Your SMTP server address (e.g.
email-smtp.us-east-1.amazonaws.comfor SES) - Port – Usually 587 (STARTTLS) or 465 (SSL)
- Username/Password – Your SMTP credentials
- Encryption – TLS/STARTTLS recommended
- Max connections – Start with 5, increase based on your provider limits
Click the “Check Status” button to verify the SMTP connection works before sending any campaigns.
For production use, also configure SPF, DKIM, and DMARC records for your sending domain to improve email deliverability and avoid spam filters.
Conclusion
Mailtrain is now running on Ubuntu 24.04 behind Nginx with SSL, connected to MariaDB, and ready to send newsletters through your SMTP relay. The application gives you complete control over your subscriber data without depending on third-party newsletter platforms.
For production hardening, set up regular database backups with mariadb-dump, monitor the Mailtrain service with systemd watchdog or a monitoring tool, and keep Node.js updated for security patches. Consider setting up a staging environment to test campaign templates before sending to your full subscriber list.