Install Mautic Self-Hosted Email Marketing on Ubuntu 20.04

This tutorial will be showing you how to set up Mautic email marketing platform on Ubuntu 20.04 with Apache or Nginx web server. Mautic is a free open source alternative to commercial email service providers like MailChimp.

Mautic Features

  • Lead nurturing and tracking
  • Marketing campaigns
  • Dripflow programs
  • Modern email and landing page builder (responsive design, drag & drop blocks, MJML templates).
  • A/B testing for emails and landing pages.
  • Create segments for any list based on any conditions you define (country, state, city, timezone, device type, device OS, points, visited URL, etc)
  • You can organize and categorize segments.
  • Automatically ad contacts via API
  • Social media monitoring
  • Install plugins to extend the functionality of Mautic.
  • Mautic can be easily integrated with third-party SMTP relay services like Gmail, Mandrill, Sendgrid, Amazon SES. You can also use your own mail server.
  • Can integrate with many popular third-party apps like Twilio, Pipedrive, Salesforce, Gmail, Facebook, Instagram, Twitter, GoToMeeting, Hubspot, SugarCRM, MailChimp, Zoho CRM, Zapier, and many more.
  • Automatic bounce handling via IMAP, so you don’t have to manually remove nonexistent email addreses.
  • Send reports to your email.
  • The From: address can be customized on a per-email basis.
  • Progressive profiling for forms (queue unlimited fields, show only a specified number of fields, set a field to always show even if the value is known).
  • Supports multiple user accounts and roles.
  • And much more

Install Mautic Self-Hosted Email Marketing Platform on Ubuntu 20.04 Server

Benefits of Self Hosting Email Marketing Platform

Why do you want to self-host email marketing platform instead of using third-party ESPs (Email Service Provider) like MailChimp?

For starters, self-hosting can save you a lot of money. Mautic is free and open-source software. You only need to pay $26/month for the VPS (virtual private server), which can run a full-featured mail server and the Mautic 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.

Another reason is that the Firefox browser blocks third-party trackers (cross-site tracking) by default, so the MailChimp signup widget on your website may not work properly and the MailChimp pop-up won’t be shown to your visitors. By hosting the email marketing platform under your own domain name, Firefox doesn’t block the tracker, so your signup widget or popup can work properly. This is also true if users of other web browsers decide to block third-party trackers.

Firefox blocks third-party trackers

Firefox blocks third-party trackers

In addition, you can manipulate subscribers’ information from the database and even automate it with a Cron job. For example, I often see there are typos when a visitor enters information on the sign-up form. I use a cron job to automatically correct some common typos.

Last but not least, self-hosting can protect your freedom of speech. You never need to worry about an email service provider closing your account like Mailchimp did.

Challenges of Self Hosting Email Marketing Platform

The first problem you face is finding a good self-hostable email marketing platform. Previously we have discussed how to set up Mailtrain, which is an open-source alternative to MailChimp, on Ubuntu 20.04 server. However, Mailtrain is missing several features a typical site owner would like to have.

  • Mailtrain doesn’t provide users with an easy way to insert signup widget or popup on the website.
  • Users can’t set time schedule for RSS campaigns.
  • No contact rating.

After all, Mailtrain is just a project of a handful of software developers.

Mautic, on the other hand, is a project of a team of developers and has developed more and more features over the years. You do have an easy way to insert signup widget and popup on your website with Mautic. There’s also a vibrant and very active community around it. Furthermore, Mautic is more than just a newsletter/email marketing platform. It’s a full-blown digital experience platform, as they call it. With Acquia (which is a company offering paid service for the Drupal open source content management system) acquiring Mautic in May 2019, the future for Mautic has never been brighter. So I feel it’s time to switch from Mailtrain to Mautic.

The second challenge is to have the technical expertise to set up the email marketing platform on your own server. Don’t worry, I will show you how in just a few moments.

The third challenge is that you need to have a good reputation for the IP address of your mail server and your domain name as well. Otherwise, your emails will land in the spam folder. Gmail Postmaster Tools can show you if you have a good reputation for your domain name and IP address. As you can see from the screenshot below, I always have high domain reputation with Gmail, because I always follow best practices to send emails to my subscribers. It’s very rare that my subscribers report my email as spam.

gmail-postmaster-tools-mail-server-domain-reputation

To send out bulk emails, you need to follow these rules or practices.

  1. Make sure the recipient gave you permission to send email. Use double opt-in to verify the subscriber’s email address.
  2. Don’t send cold emails to thousands of people who have never received emails from you before. Instead, you need to warm up your IP address. For example, send 500 emails on day 1, then send 1000 emails on day 2, send 2000 emails on day 3.
  3. Include your contact information and your mailing address at the bottom of the email message.
  4. Personalize the email message as much as possible. For example, include the recipient’s name in the email.
  5. Conform to CAN-SPAM Act
  6. Avoid large attachments.
  7. Clean your email list. For example, delete email subscribers that haven’t opened your email in the last 30 days.
  8. Get approved as Return Path Certified Sender.
  9. Test your email placement with GlockApps.
  10. Use multiple IP addresses to spread email traffic so you will have better email deliverability.

It’s also highly recommended to improve your IP/domain reputation before sending bulk emails. Now let’s look at how to install Mautic on Ubuntu 20.04 server.

Prerequisites of installing Mautic on Ubuntu 20.04 Server

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 Mautic, so you don’t have to spend money on commercial SMTP relay service.

Mautic is written in PHP and relies on MySQL/MariaDB database server. So you need to set up a LAMP stack or LEMP stack. If you prefer Apache web server, then set up LAMP stack.

If you prefer Nginx web server, then set up LEMP stack.

Note that iRedMail will automatically set up a LEMP stack for you, so if you are going to install Mautic on your iRedMail server, you don’t need to set up LEMP stack again.

You also need a domain name. I registered my domain name from NameCheap because the price is low and they give whois privacy protection free for life. Without further ado, let’s install Mautic on Ubuntu 20.04 server.

Step 1: Download Mautic onto Your Ubuntu 20.04 Server

Download the latest stable version by executing the following command on your server.

wget https://github.com/mautic/mautic/releases/download/4.2.1/4.2.1-update.zip

Install the unzip utility and unzip it to /var/www/mautic/ directory.

sudo apt install unzip

sudo mkdir -p /var/www/mautic/

sudo unzip 4.2.1-update.zip -d /var/www/mautic/

Then make the web server user (www-data) as the owner of this directory.

sudo chown -R www-data:www-data /var/www/mautic/

Step 2: Create a MariaDB Database and User for Mautic

Log in to MariaDB console.

sudo mysql -u root

Next, create a new database for Mautic using the following command. This tutorial names it mautic, you can use whatever name you like for the database.

CREATE DATABASE mautic DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

The following command will create a database user and password, and at the same time grant all permission of the new database to the new user so later on Mautic can write to the database. Replace red texts with your preferred database name, username and password.

GRANT ALL ON mautic.* TO 'mauticuser'@'localhost' IDENTIFIED BY 'password';

Flush privileges table and exit MariaDB console.

FLUSH PRIVILEGES;

EXIT;

Step 3: Install Required and Recommended PHP Modules.

Run the following command to install PHP modules required or recommended by Mautic

sudo apt install php-imagick php7.4-fpm php7.4-mysql php7.4-common php7.4-gd php7.4-imap php7.4-imap php7.4-json php7.4-curl php7.4-zip php7.4-xml php7.4-mbstring php7.4-bz2 php7.4-intl php7.4-gmp

If you use Apache web server, then you need to disable the PHP module for Apache.

sudo a2dismod php7.4

You also need to disable the prefork MPM module in Apache.

sudo a2dismod mpm_prefork

Now you need to run the following command to enable three modules in order to use PHP-FPM in Apache, regardless of whether mod_php is installed on your server.

sudo a2enmod mpm_event proxy_fcgi setenvif

Then restart Apache.

sudo systemctl restart apache2

Step 4: Create Apache Virtual Host or Nginx Config File for Mautic

Apache

If you use Apache web server, create a virtual host for Mautic.

sudo nano /etc/apache2/sites-available/mautic.conf

Put the following text into the file. Replace mautic.example.com with your real domain name and don’t forget to set DNS A record for it.

<VirtualHost *:80>
  ServerName mautic.example.com
  DocumentRoot /var/www/mautic/

  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

  <Directory />
    Options FollowSymLinks
    AllowOverride All
  </Directory>

  <Directory /var/www/mautic/>
    Options FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    allow from all
  </Directory>

</VirtualHost>

Save and close the file. Then enable this virtual host with:

sudo a2ensite mautic.conf

Reload Apache for the changes to take effect.

sudo systemctl reload apache2

Now you should be able to see the Mautic web-based install wizard at http://mautic.example.com/installer.

Nginx

If you use Nginx web server, create a virtual host for Mautic.

sudo nano /etc/nginx/conf.d/mautic.conf

Note: If you install Mautic on iRedMail server, you should create the virtual host under /etc/nginx/sites-enabled/ directory.

sudo nano /etc/nginx/sites-enabled/mautic.conf

Put the following text into the file. Replace mautic.example.com with your real domain name and don’t forget to create DNS A record for it. Also note that if you install Mautic on iRedMail server, you should use the TCP socket (127.0.0.1:9999) instead of the Unix socket (unix:/run/php/php7.4-fpm.sock).

server {
   listen 80;
   listen [::]:80;
   server_name mautic.example.com;

   root /var/www/mautic;
   error_log /var/log/nginx/mautic.error;
   access_log /var/log/nginx/mautic.access;
   client_max_body_size 20M;

   index index.php index.html index.htm index.nginx-debian.html;

   location / {
     # try to serve file directly, fallback to app.php
     try_files $uri /index.php$is_args$args;
   }

   location ~ /(mtc.js|1.js|mtracking.gif|.*\.gif|mtc) {
       # default_type "application/javascript";
       try_files $uri /index.php$is_args$args;
   }

   # redirect some entire folders
     rewrite ^/(vendor|translations|build)/.* /index.php break;

   location ~ \.php$ {
     include snippets/fastcgi-php.conf;
     fastcgi_pass unix:/run/php/php7.4-fpm.sock;
     #Note: If you install Mautic on iRedMail server, you should use the TCP socket instead. 
     #fastcgi_pass 127.0.0.1:9999;
   }

   location ~* ^/index.php {
     # try_files $uri =404;
     fastcgi_split_path_info ^(.+\.php)(/.+)$;
     # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

     fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
     #Note: If you install Mautic on iRedMail server, you should use the TCP socket instead.
     #fastcgi_pass 127.0.0.1:9999;
     fastcgi_index index.php;
     fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
     include fastcgi_params;

     fastcgi_buffer_size 128k;
     fastcgi_buffers 256 16k;
     fastcgi_busy_buffers_size 256k;
     fastcgi_temp_file_write_size 256k;
   }

    # Deny everything else in /app folder except Assets folder in bundles
    location ~ /app/bundles/.*/Assets/ {
        allow all;
        access_log off;
    }
    location ~ /app/ { deny all; }

    # Deny everything else in /addons or /plugins folder except Assets folder in bundles
    location ~ /(addons|plugins)/.*/Assets/ {
        allow all;
        access_log off;
    }
    # location ~ /(addons|plugins)/ { deny all; }

    # Deny all php files in themes folder
      location ~* ^/themes/(.*)\.php {
        deny all;
    }

    # Don't log favicon
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    # Don't log robots
    location = /robots.txt  {
        access_log off;
        log_not_found off;
    }

    # Deny yml, twig, markdown, init file access
    location ~* /(.*)\.(?:markdown|md|twig|yaml|yml|ht|htaccess|ini)$ {
        deny all;
        access_log off;
        log_not_found off;
    }

  # Allow access to certbot directory in order to obtain TLS certificate
     location ~ /.well-known/acme-challenge {
      allow all;
   }

  # Deny all attempts to access hidden files/folders such as .htaccess, .htpasswd, .DS_Store (Mac), etc...
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    # Deny all grunt, composer files
    location ~* (Gruntfile|package|composer)\.(js|json)$ {
        deny all;
        access_log off;
        log_not_found off;
    }

    # Deny access to any files with a .php extension in the uploads directory
        location ~* /(?:uploads|files)/.*\.php$ {
                deny all;
    }

     # A long browser cache lifetime can speed up repeat visits to your page
  location ~* \.(jpg|jpeg|gif|png|webp|svg|woff|woff2|ttf|css|js|ico|xml)$ {
       access_log        off;
       log_not_found     off;
       expires           360d;
  }
}

Save and close the file. Then test Nginx configuration.

sudo nginx -t

If the test is successful, reload Nginx for the changes to take effect.

sudo systemctl reload nginx

Now you should be able to see the Mautic web-based install wizard at http://mautic.example.com/installer.

Step 5: Enabling HTTPS

To encrypt the HTTP traffic, 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 20.04 server.

sudo apt install certbot

Make sure the .well-known/acme-challenge/ directory exists and www-data is the owner.

sudo mkdir -p /var/www/mautic/.well-known/acme-challenge

sudo chown www-data:www-data /var/www/mautic/.well-known/acme-challenge

If you use Nginx, then you also need to install the Certbot Nginx plugin.

sudo apt install python3-certbot-nginx

Next, run the following command to obtain and install TLS certificate.

sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d mautic.example.com

If you use Apache, install the Certbot Apache plugin.

sudo apt install python3-certbot-apache

And run this command to obtain and install TLS certificate.

sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d mautic.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.

The certificate should now be obtained and automatically installed.

mautic https letsencrypt

If you encounter the following error, then you can try using the webroot plugin to obtain TLS certificate.

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: mautic.your-domain.com
   Type:   unauthorized
   Detail: Invalid response from
   http://mautic.your-domain.com/.well-known/acme-challenge/oPobDrRkFbimsOD5Jbcx2VQfbMh9Hv3VueNhKdyhbcg
   [xx.xx.xx.xx]: "<html>\r\n<head><title>404 Not
   Found</title></head>\r\n<body>\r\n<center><h1>404 Not
   Found</h1></center>\r\n<hr><center>nginx</center>\r\n"

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address.

Nginx web server with webroot plugin

sudo certbot --webroot -w /var/www/mautic -i nginx --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d mautic.example.com

Apache web server with webroot plugin

sudo certbot --webroot -w /var/www/mautic -i -apache --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d mautic.example.com

Step 6: Finish Mautic Installation in Web Browser

Now in your browser address bar, type in your domain name for Mautic to access the web install wizard.

https://mautic.your-domain.com/installer

or

https://mautic.your-domain.com/index.php/installer

install mautic ubuntu 18.04

Click Next Step. If you see the following warning,

The memory_limit setting in your PHP configuration is lower than the suggested minimum limit of 512M. Mautic can have performance issues with large datasets without sufficient memory.

Then edit the php.ini file.

sudo nano /etc/php/7.4/fpm/php.ini

Find the following line

memory_limit = 128M

Change its value to 512M.

memory_limit = 512M

Also, you can set a default timezone in PHP. Find the following line.

;date.timezone =

Change it to:

date.timezone = America/New_York

You can find your own time zone format on the official PHP website. Save and close the file. Then reload PHP7.4-FPM, and the warning should be gone.

sudo systemctl reload php7.4-fpm

In step 1, enter the MariaDB/MySQL database details. For security reasons, you can add a database table prefix in this step. You can use a short random character as the table prefix such as 6aC8_. It’s recommended to end the prefix with an underscore _.

mautic mariadb database

If you encounter the following error:

An error occured while attempting to add default data: There's no active transaction.

You need to change the database driver from MySQL PDO to MySQLi.

In step 2, create an admin account for the Mautic web interface.

install mautic on ubuntu 18.04 server

In step 3, configure email settings. You have many options in mailer transport. You can use PHP Mail, sendmail, or Gmail or integrate Mautic with third-party email services like Mandrill, Sendgrid, Amazon SES, etc. These settings can always be changed after installation in Mautic configurations page. If Mautic is installed on your mail server, then you need to choose Sendmail as the mailer transport, so Mautic will use your own mail server to send email. Email handling should be set to Send immediately, so transactional emails will be sent immediately and marketing emails will be queued.

mautic email server configuration sendmail

If Mautic and your mail server are running on different hosts and you want Mautic to send emails via your mail server, then you need to choose Other SMTP server as mailer transport. Then

  • Enter the hostname of your mail server
  • Choose port 587
  • Choose TLS encryption.
  • Choose Plain as the authentication mode.
  • Enter the login credential of an email address on your mail server.

mautic other smtp service

After step 3 is done, you can log into Mautic dashboard.

mautic php7.2

If you see the 500 internal server error, please check Mautic logs, which can be found in /var/www/mautic/app/logs/ directory. If you forgot your Mautic database password, you can find it in the /var/www/mautic/app/config/local.php file.

Step 7: Enable HTTP2 to Improve Performance

You can enable HTTP2 protocol to improve page loading performance for Mautic.

Apache

First, you need to enable the HTTP2 module.

sudo a2enmod http2

Then open the SSL virtual host file.

sudo nano /etc/apache2/sites-enabled/mautic-le-ssl.conf

Put the following directive after the opening <VirtualHost *:443> tag.

Protocols h2 http/1.1

Save and close the file. Then restart Apache for the changes to take effect.

sudo systemctl restart apache2

Nginx

To enable HTTP2 protocol in Nginx virtual host, find the following line.

listen 443 ssl; # managed by Certbot

Simply add http2 after ssl.

listen 443 ssl http2; # managed by Certbot

Save and close the file. Then reload Nginx.

sudo systemctl reload nginx

Step 8: Install the RSS To Email Plugin

For many site owners, the ability to automatically fetch content from RSS feed and send it to subscribers is a must. Mautic doesn’t support this feature natively, but you can install a plugin to implement this feature.

You can download the plugin by clicking this link. Then upload this plugin to the /var/www/mautic/plugins/ directory.

Next, go to the Mautic plugins directory.

cd /var/www/mautic/plugins/

Unzip the archive.

sudo unzip MauticRssToEmailBundle.zip

Clear the Mautic cache.

sudo -u www-data php7.4 /var/www/mautic/bin/console cache:clear

In the Mautic dashboard, click the gear icon on the upper-right corner and select plugins. Click the Install/Upgrade plugins button and the Mautic RSS to Email plugin will show up in the plugin list.

mautic rss to email plugin

Step 9: Add Cron Jobs

Mautic relies on Cron jobs to update mailing list segments, email marketing campaigns, campaign events and process email queues. Edit the www-data user’s crontab file. (You should not add Mautic commands in root user’s crontab file.)

sudo -u www-data crontab -e

And add Mautic Cron jobs like below.

######  Mautic Cron Jobs #######

# update segments every 15 minutes
* * * * * php7.4 /var/www/mautic/bin/console mautic:segments:update  > /dev/null 

# update campaigns every 15 minutes starting with an offset of 5 minutes at the beginning of each hour
5-59/15 * * * * php7.4 /var/www/mautic/bin/console mautic:campaigns:update  > /dev/null 

# execute campaigns events every 15 minutes with an offset of 10 minutes
10-59/15 * * * * php7.4 /var/www/mautic/bin/console mautic:campaigns:trigger  > /dev/null 

# process email queue
2-59/15 * * * * php7.4 /var/www/mautic/bin/console mautic:emails:send  > /dev/null

# import list in the background
* * * * * php7.4 /var/www/mautic/bin/console mautic:import  > /dev/null

# Fetch bounce messages
@hourly php7.4 /var/www/mautic/bin/console mautic:email:fetch

# update MaxMind GeoLite2 IP Database once a week
@weekly php7.4 /var/www/mautic/bin/console mautic:iplookup:download  > /dev/null

If you have a transactional email campaign that needs to send emails immediately, then you should add a line like the below to execute the campaign every minute.

# execute transactional campaign every minute.
* * * * * php7.4 /var/www/mautic/bin/console mautic:campaign:trigger -i campaign_id > /dev/null

You can find the campaign ID after you create a campaign.

Save and close the file.

Note that Mautic cron jobs may use a fair amount of CPU and RAM resources. If Mautic and iRedMail are installed on a server with 2GB RAM, you should not deploy additional programs on the server, or you can choose to upgrade the server specs.

Step 10: Download IP Lookup Database

In order to know the subscriber’s geolocation, you need to download MaxMind’s free GeoLite2 IP lookup database.

First, you need to create an account at MaxMind. Maxmind will send you an email. Click the link in the email to set a password, then log in to your MaxMind account. Next, select My License Key on the left bar.

maxmind license key

Click the Generate New License Key button.

maxmind generate new license key

Give your license key a name. Then choose No, because we don’t need to use the geoipupdate program. Then click the Confirm button.

geoipupdate

Once the license key is created, copy the license key. Go to Mautic dashboard, click the cog icon on the upper right corner and select configuration. In the System settings tab, scroll down to Miscellaneous Settings.

  • Select Maxmind GeoLite2 City Download for the IP lookup service
  • In the IP lookup service authentication field, enter your Maxmind email address and Maxmind license key like this:   [email protected]:JNQEpLFM8OCudQ== You need to use a colon as the delimiter.

Next, Click the Fetch IP Lookup Data Store button. Finally, click the Apply button on the upper-right corner.

mautic maxmind geolite 2 city IP lookup

Step 11: Install the Tracking JavaScript

In the tracking settings tab, you can find a code snippet that you can add to your website for tracking visitors. If you use WordPress, then copy this code snippet and paste it in the footer.php file under the WordPress theme folder.

Muatic tracking javascript

Note that you need to go to the System settings tab, and add your website’s address in the CORS settings for the tracking JavaScript to work.

Mautic CORS settings

While you are at it, you should also set the default timezone on this page.

mautic set time zone

Click the Apply button. Note: I found that I need to wait sometime for the timezone setting to take effect. You can clear Mautic cache with the following command for the timezone setting to take effect immediately.

sudo rm /var/www/mautic/app/cache/* -rf

To check if it’s working, you can use another device to visit your website, then go to the Mautic dashboard. If it’s working, there should be new page visits displayed on the dashboard.

Importing Contacts to Mautic

Check out the Mautic contact import page. When importing contacts from a CSV file, you can choose the contact owner, contact segment, and tags. You can also match the CSV file column with the existing Mautic contact fields.

mautic import contacts from csv file

Please note that when importing a large list (more than one thousand contacts) to Mautic, you should choose import in the background instead of importing in the browser. That’s because the default PHP maximal execution time is 30 seconds, but importing a large list can take several minutes, so it will be stopped by the PHP limit if you choose to import in the browser.

If the importing process appears to be not making any progress then you can try importing it from the command line. It may give you some clue why it’s not making progress.

sudo -u www-data php7.4 /var/www/mautic/bin/console mautic:import

A column in the CSV file should not contain too many characters (no longer than 170 characters, I think), or the import can fail and the error “There was a database error: The EntityManager is closed” will be shown in the command line.

How to Send Emails in Mautic

In Mautic, you can use 3 types of email campaigns:

  • automated campaign: for marketing automation
  • Manual campaign: broadcast emails to a whole segment
  • RSS campaign: If you installed the RSS to Email plugin

In Mautic, there’s no such concept as an email list. You need to import contacts and group them into segments.

Create an Automated Campaign (Marketing Automation)

  1. Go to the Contacts tab and import your contacts to Mautic.
  2. Go to the Segment tab to create a segment
  3. Add the contacts into the segment.
  4. Go to Channels -> Email and create the template emails that you want to send to subscribers.
  5. Go to the Campaigns tab to create a campaign. The campaign builder allows you to create automated campaigns. Assign a segment to the campaign.
  6. Publish the campaign and you are done. Wait for the Emails to be sent.

Create Manual Campaign (Broadcast Emails)

Go to Channels -> Email, click the New button to create a new Segment Email.

  • Segment Emails can be sent manually (broadcast)
  • Template emails can not be sent manually. They are used with automated campaigns.

Once the segment email is created, you can click the send button to broadcast the emails to your subscribers.

Create RSS Campaign

Go to Channels -> Email, click the New button to create a new Template Email. Add the following content in the email body. Replace https://www.example.com/feed with your own RSS feed URL.

         <br> 
         <div id="ivxsr">
            <p id="ih3yw">{feed url="https://www.example.com/feed"}
              {feeditems count="3"}
            </p>
           <h3>
                <a href="{feeditem:link}" id="igybl">{feeditem:title}</a>
           </h3>
           <p id="ijdmp">
                  <small>{feeditem:date format="d-m-Y H:i"}</small>
           </p>
           <p id="iv7cu">{feeditem:description}
           </p>
           <hr id="ipapb">
           {/feeditems}
            {/feed}
       </div>

Next, create a campaign to send this email every day. For more details on using RSS, please read the README file in the plugins directory.

How to Integrate with Twilio SMS Marketing

Twilio allows you to programmatically make and receive phone calls, send and receive text messages using its web service APIs. Go to Twilio.com to create an account (You will get $15.50 trial credit). Then go to Mautic Settings -> Plugins. Click the Install/Upgrade Plugins button. The Twilio plugin will show up. Click on it. Then

  • Change the published status from No to Yes.
  • Enter your Twilio account SID
  • Enter your Twilio Auth Token
  • Go to your Twilio account to get a trial phone number, copy the number and paste it to the Sending Phone Number field in Mautic.

mautic twilio

mautic SMS marketing

Click the Save & close button. Now if you create a campaign in the campaign builder, you have the option to send SMS text messages.

mautic send text messages

And you have a new item called text messages under the channels tab.

Note that phone numbers stored in Mautic should have the + sign with the contact’s country code like +44. If there’s no + sign, Mautic will automatically add the US country code (+1).

How to Handle SMS Subscriptions

If you a user don’t want to receive your SMS messages, you need to allow the user to unsubscribe from your SMS campaign. This can be achieved via the Mautic SMS reader plugin. To install this plugin, run

cd /var/www/mautic/plugins/

sudo git clone https://github.com/nebev/mautic-sms-reader.git

sudo mv mautic-sms-reader SmsreaderBundle

Clear the Mautic application cache.

sudo -u www-data php7.4 /var/www/mautic/bin/console cache:clear

Then go to Mautic Settings -> Plugins. Click the Install/Upgrade Plugins button. The Smsreader plugin will show up. Next, log out and log back in. You will see the Twilio SMS Reader menu item in Settings. Enter your Twilio Account SID and the unsubscribe/re-subscribe keywords.

Unable to Send SMS?

If Mautic is unable to send SMS, and you see the following error message in the Cron job.

PHP Warning: Use of undefined constant CURLOPT_URL - assumed 'CURLOPT_URL'

It’s because your server is missing the PHP CURL extension. You can fix this error with the following command.

sudo apt install php7.4-curl

Automatic Bounce Handling

You can use the Monitored Inbox feature in Mautic to automatically remove email address from Mautic. Go to Mautic configuration -> Email settings -> Monitored Inbox.  Enter your mailbox login credentials, then test connection and fetch folders.

Mautic monitored inbox

Once the connection is successful, you can select the folder to monitor for bounce messages. Note that you need to create the folder as a sub-foler of the main inbox folder in your mailbox, otherwise you might see “the value is not valid” error when selecting the folder to check. If you use the Roundcube webmail, you can go to the Roundcube settings -> Folders to create the sub folder (Inbox.bounces).

mautic automatic bounce handling

Then Mautic will allow you to choose the INBOX.bounces as the folder to check. Click the Save and close button. In Roundcube, you can create a filter to automatically put bounce messages into the Inbox.bounces folder.  The filter rule is as follows:

  • Subject contains “Undelivered Mail Returned to Sender”
  • To contains “[email protected]

roundcube bounce message filter

Next, you can run the following command on your server, so Mautic can fetch the bounce messages from the mailbox.

sudo -u www-data php7.4 /var/www/mautic/bin/console mautic:email:fetch

This command is already in the Cron jobs, so you don’t have to run it manually every day.

By default, bounced email addresses won’t be automatically remove from Mautic, but will be labeled as Do not Contact, so Mautic won’t send emails to those addreses. If you want to remove them, you can create a segment called bounced emails with the filter Bounce - Email equals Yes.

mautic bounced emails segment

Segment will be updated by Cron jobs.

Next, you can create a campaign in Mautic to automatically delete the contacts in the bounced email segment.

Can’t Open the HTML Code Editor in Page Builder?

Since Mautic 4.0, the landing page builder uses the GraphJS framework and one of the problems is that you can open the HTML code editor only once. If you want to re-edit the code, it refuses to load the editor.

The trick is that you need to press F5 to refresh the web page and open the page builder again, then you will be able to open the HTML code editor.

Mautic PHP Console Commands

The Mautic Cron jobs are several PHP console commands. There are also other commands you might find useful. List available commands with:

sudo -u www-data php7.4 /var/www/mautic/bin/console

For example, you can update Mautic from the command line.

sudo -u www-data php7.4 /var/www/mautic/bin/console mautic:update:find
sudo -u www-data php7.4 /var/www/mautic/bin/console mautic:update:apply

The console in a PHP web application is usually available as bin/console, app/console, or console.php. Not every PHP web application provides console commands. The available commands are not the same for different web applications. For instance, some allow you to create users and reset passwords, while others may not allow you to do so.

Tips

  • If you use Adblocker, please disable it on your Mautic URL, or you might have problems editing landing pages in Mautic.
  • If you use Mautic in a production environment, it’s recommended that you wait some time to upgrade to the next version. For example, when version 4.3 comes out, I stay with version 4.2. I only upgrade to version 4.3 when version 4.4 comes out.

Wrapping Up

I hope this tutorial helped you install Mautic on Ubuntu 20.04. You can also check out Mautic getting started guide to learn how to use it. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂

Rate this tutorial
[Total: 9 Average: 4.6]

25 Responses to “Install Mautic Self-Hosted Email Marketing on Ubuntu 20.04

  • Hello, great article. As always.
    I was wondering if you could do a post on an open-source membership management product, an alternative to providers like MemberMouse? That’d be dope.

  • Victor Olvera
    3 years ago

    If you can’t send e-mails and get “permission denied” errors in your mail logs, go to Configuration → Email Settings → Mail Send Settings and try changing “Sendmail” for “Other SMTP Server” and put your own server settings (Host, Port:25, SMTP encryption type, SMTP auth mode, Username and Password) in the fields.

  • Hello Xiao,

    Mautic 3.3.x already support PHP 7.3 and 7.4.

    Can I just skip “Step 3: Install Required and Recommended PHP Modules” or it is necessary to so something else?


    Kindest Regards,
    Ale

    • Xiao Guoan (Admin)
      3 years ago

      Thanks for the tip. I just changed PHP7.3 to PHP7.4 in step 3, so you need to run the following command to install necessary PHP modules.

      sudo apt install php-imagick php7.4-fpm php7.4-mysql php7.4-common php7.4-gd php7.4-imap php7.4-json php7.4-curl php7.4-zip php7.4-xml php7.4-mbstring php7.4-bz2 php7.4-intl php7.4-gmp
  • This is by far the best and most comprehensive tutorial for installing Mautic on Ubuntu. Thank you Xiao!

  • John Harris
    3 years ago

    Thank you for this superb guide. I respectfully suggest one minor correction for “Step 10: Download IP Lookup Database.” One cannot paste only the MaxMind license key into the field “IP lookup service authentication.” One must also prepend the username, which will be an email address provided to MaxMind, followed immediately by a colon. Thus the field entry will be [username]:[license key].

  • Hi,
    When I used the queue to send segmented emails, I encountered this error:Mautic 500 error

    2021/10/16 15:47:49 [error] 4057#4057: *1155 recv() failed (104: Connection reset by peer) while reading response header fro>
    2021/10/16 15:50:09 [error] 4057#4057: *1155 FastCGI sent in stderr: “PHP message: PHP Notice: SessionHandler::gc(): ps_fil>
    2021/10/16 16:33:21 [error] 4057#4057: *1228 FastCGI sent in stderr: “PHP message: PHP Notice: SessionHandler::gc(): ps_fil>

    Just as this issue:
    https://forum.mautic.org/t/notices-trying-to-access-array-offset-on-value-of-type-null/18008

    • 2021/10/16 15:18:01 [error] 4057#4057: *1078 FastCGI sent in stderr: “PHP message: PHP Notice: Trying to access array offset on value of type null in /var/www/mautic/app/bundles/EmailBundle/Views/FormTheme/Email/_emailform_dynamicContent_entry_filters_entry_filters_entry_widget.html.php on line 14” while reading response header from upstream, client: x.x.x.x, server: mydomain.com, request: “POST /s/emails/edit/6?mauticUserLastActive=110&mauticLastNotificationId=3 HTTP/2.0”, upstream: “fastcgi://unix:/run/php/php7.4-fpm.sock:”, host: “mydomain.com”, referrer: “https://mydomain.com/s/emails/edit/6”
      2021/10/16 15:47:49 [error] 4057#4057: *1155 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: x.x.x.x, server: mydomain.com, request: “POST /s/config/edit?mauticUserLastActive=426&mauticLastNotificationId=3 HTTP/2.0”, upstream: “fastcgi://unix:/run/php/php7.4-fpm.sock:”, host: “mydomain.com”, referrer: “https://mydomain.com/s/config/edit”
      2021/10/16 15:50:09 [error] 4057#4057: *1155 FastCGI sent in stderr: “PHP message: PHP Notice: SessionHandler::gc(): ps_files_cleanup_dir: opendir(/var/lib/php/sessions) failed: Permission denied (13) in /var/www/mautic/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php on line 101” while reading response header from upstream, client: x.x.x.x, server: mydomain.com, request: “GET /s/config/edit HTTP/2.0”, upstream: “fastcgi://unix:/run/php/php7.4-fpm.sock:”, host: “mydomain.com”, referrer: “https://mydomain.com/s/config/edit”
      2021/10/16 16:33:21 [error] 4057#4057: *1228 FastCGI sent in stderr: “PHP message: PHP Notice: SessionHandler::gc(): ps_files_cleanup_dir: opendir(/var/lib/php/sessions) failed: Permission denied (13) in /var/www/mautic/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php on line 101” while reading response header from upstream, client: x.x.x.x, server: mydomain.com, request: “GET /s/dashboard/widget/5?ignoreAjax=true&_=1634400158394&mauticUserLastActive=1843&mauticLastNotificationId=3 HTTP/2.0”, upstream: “fastcgi://unix:/run/php/php7.4-fpm.sock:”, host: “mydomain.com”, referrer: “https://mydomain.com/s/dashboard”

      • 问题已解决。解决方法是:把报错的文件加上组用户写权限。感谢肖先生的教程。

  • Hi,
    The BEST guide online to install Mautic. Thanks for all the time that you invest in bringing this to us.

    On step 1 you mentioned

    wget https://github.com/mautic/mautic/releases/download/3.3.3/3.3.3-update.zip

    Can you explain to us how to use always get the latest version directly from GitHub? you guide is for version 3.3.3 but mautic is on version 4.1 and soon 4.1.1.

    This will avoid us having to update Mautic at the end of this installation.

    Thanks again for all.
    Take care,
    Rub

    • Just found it 🙂

      wget https://github.com/mautic/mautic/archive/refs/heads/4.x.zip
      
      sudo unzip 4.x.zip -d /var/www/mautic/
      

      Again, awesome guide.

  • Hi,

    As always your tutorials are super thorough and i am happy to reference them whenever I can.

    I did find a small issue with the config of the nginx file regarding focus items:
    location ~ /(mtc.js|1.js|mtracking.gif|.*\.gif|mtc) {
    # default_type “application/javascript”;
    try_files $uri /index.php$is_args$args;

    The issue is if you are using a focus item inside a campaign (lets say example id 8.js) the above configuration will not allow this specific item to be displayed, as it is only letting 1.js.

    I am unfamiliar with nginx configuration so the only way around this is by adding a pipe and the other focus items I want to show within specific campaigns.

  • When installed, mautic does not show the logotype, and further during operation, mautic does not insert, show, or send images. Please help me I’m willing to pay

  • Chirayu
    2 years ago

    Hi, your tutorial is really very helpful. Even though I am a nontechnical person, I was able to use it. Thank you very much.

    I have some issues, please help me if possible.

    1) When I try to add a cron job with this command “sudo -u www-data crontab -e” , I found “Problem with history file” (attached screenshot). What will be the impact of this problem? And how can I remove this problem? Please guide me with step by step process.

    2) When I use the command “listen 443 ssl; # managed by Certbot” to enable HTTPS2, I got this response:

    "Command 'listen' not found, but can be installed with:  "sudo apt install ruby-listen"

    Then I installed ruby-listen with “sudo apt install ruby-listen” command and again start with your process with “listen 443 ssl; # managed by Certbot” command. After that, I got this response:

    Traceback (most recent call last):
    5: from /usr/bin/listen:4:in `
    ' 4: from /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require' 3: from /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require' 2: from /usr/lib/ruby/vendor_ruby/listen/cli.rb:1:in `' 1: from /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require' /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require': cannot load such file -- thor (LoadError)

    What is the meaning of the above response? How can I solve this and enable HTTPS2?

    Thank you again.

    • Xiao Guoan (Admin)
      2 years ago

      1. To fix this “Problem with history file” error, run the following commands:

      sudo touch /var/www/.selected_editor
      
      sudo mkdir -p /var/www/.local
      
      sudo chown www-data:www-data /var/www/.selected_editor
      
      sudo chown www-data:www-data /var/www/.local -R
      

      2. listen 443 ssl; # managed by Certbot is not a Linux command. It’s a line in the Nginx configuration file /etc/nginx/sites-enabled/mautic.conf or /etc/nginx/conf.d/mautic.conf.

  • Hello,

    Many thanks for this wonderful comprehensive guide, I do greatly appreciate it.

    I’ve a questions please. My VPS has Nginx that is installed separately without any package.

    This line triggers Nginx error below,

    include  snippets/fastcgi-php.conf;

    The error:

    root@myvps:~# nginx -t
    nginx: [emerg] open() "/etc/nginx/snippets/fastcgi-php.conf" failed (2: No such file or directory) in /etc/nginx/conf.d/mautic.conf:25
    nginx: configuration file /etc/nginx/nginx.conf test failed

    I commented it and added this one:

    include  fastcgi_params;

    And the installation works like a charm without any problem but I just wanna understand the problem and the differences between the two.

    Thanks so much in advance, you’re doing great work, lots of respect!

    • Xiao Guoan (Admin)
      2 years ago

      The standard Nginx package on Ubuntu has this file /etc/nginx/snippets/fastcgi-php.conf:

      # regex to split $uri to $fastcgi_script_name and $fastcgi_path
      fastcgi_split_path_info ^(.+?\.php)(/.*)$;
      
      # Check that the PHP script exists before passing it
      try_files $fastcgi_script_name =404;
      
      # Bypass the fact that try_files resets $fastcgi_path_info
      # see: http://trac.nginx.org/nginx/ticket/321
      set $path_info $fastcgi_path_info;
      fastcgi_param PATH_INFO $path_info;
      
      fastcgi_index index.php;
      include fastcgi.conf;
      

      If your VPS doesn’t have it, you can manually create this file.

  • hello, I have this kind of problem during installation of mautic. Can you help me please.
    Find in attached.

    Enzo

  • Could you help me? i don’t understand one part of installation , if I installed Iredmail before this .
    Note: i want to install iredmail and mautic in one ip address and vps . It’s possible?

    Thanks you

  • Thanks, it’s great tutorial. Everything worked well except the cronjobs, they don’t work. But when I run them manually they work. How to fix this issue, please?

  • Thanks, it’s great tutorial. Everything worked well except the cronjobs, they don’t work. But when I run them manually they work. How to fix this issue, please advise.

  • When I added the jobs in the file: sudo -u www-data crontab -e, it didn’t work. But when I added them in the file: crontab -e, it worked. Do you know why please? And why didn’t you recommend to add them in crontab -e?

    Thanks.

  • HI,

    Thanks for great tutorials. Can you please help me when we install mautic on aws machine. we are not able to run mautic

    hp

    /*
    * @copyright 2014 Mautic Contributors. All rights reserved
    * @author Mautic
    *
    * @link http://mautic.org
    *
    * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
    */
    define(‘MAUTIC_ROOT_DIR’, __DIR__);

    // Fix for hosts that do not have date.timezone set, it will be reset based on users settings
    date_default_timezone_set(‘UTC’);

    require_once ‘autoload.php’;

    use Mautic\CoreBundle\ErrorHandler\ErrorHandler;
    use Mautic\Middleware\MiddlewareBuilder;
    use function Stack\run;

    ErrorHandler::register(‘prod’);

    run((new MiddlewareBuilder(new AppKernel(‘prod’, false)))->resolve());

  • Great tutorial. I have a question. How can I use mautic with multiple smtp’s (multiple IP’s and domains) to send bulk emails? In another tutorial you have you say this is possible, but I can figure that out yet. Here is your tutorial where you say this: https://www.linuxbabe.com/mail-server/postfix-multiple-instances-ip-rotation-on-a-single-vps

    “Why Use Multiple IP Addresses
    If you send bulk emails using a self-hosted email marketing software like Mautic, it’s a good practice to use multiple IP addresses to spread your email traffic. If mailbox providers observe a large volume of emails coming from a single IP address, then it’s likely to be identified as spam. To maintain good IP reputation, you need to slow down the email traffic sent from a single IP address.”

    Thanks in advance

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.

The maximum upload file size: 2 MB. You can upload: image. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop file here