How to Set Up Mautic 5.x on Kubernetes: A Step-by-Step Guide
This guide is the fruit of my recent endeavor to set up Mautic 5.x, a marketing automation tool, in a local environment. The process shed light on the inner workings of the Doctrine queue and the role of cron jobs in background data processing. While Mautic setup guides are a dime a dozen, I found myself drawn to the installation methods using Docker Compose or Kubernetes Helm Chart. This post zeroes in on the latter, primarily to scratch my itch for expanding Kubernetes expertise.
We’ll cover:
- Setting up a local Kubernetes cluster with Minikube
- Installing Mautic with its accompanying ecosystem (MySQL, Mailhog) as Helm charts
- A walkthrough of cron jobs
Estimated time to complete: 60 minutes.
What is Mautic?
Mautic is an open-source marketing automation platform that helps businesses streamline and automate their marketing activities. It stands out from proprietary alternatives by offering a fully customizable solution without licensing fees. Mautic provides features such as lead management, email marketing, campaign orchestration, and analytics, all within a self-hosted environment. This gives organizations the keys to the kingdom when it comes to their data and infrastructure, making it particularly appealing for businesses with specific privacy requirements or those looking to weave marketing automation seamlessly into their existing systems.
Prerequisites
Before diving in, let’s ensure you have all the necessary tools in your developer’s toolkit. For macOS users, you can install the prerequisite software with the following command:
|
|
To take your Kubernetes interaction up a notch, I highly recommend getting your hands on k9s.
Mautic stack design
Kubernetes cluster setup with Minikube
Let’s get the ball rolling.
|
|
We’ll leverage the ingress
feature to expose both Mautic UI and Mailhog.
Next, add the required Helm repositories:
|
|
With these steps completed, we’re locked and loaded for the next phase of our setup.
MySQL
We’ll kick things off by setting up the MySQL database with a custom configuration file:
|
|
Then, proceed with installing the chart.
|
|
MySQL service type is set to ClusterIP
, meaning that it is not accessible from outside of the cluster. There are multiple ways to connect to it, for example creating a NodePort
service and instructing Minikube to forward the connection.
|
|
Then install the service using kubectl
and forward the connection:
|
|
Keep your eyes peeled for the port number – it’s a moving target each time you run minikube service mysql-nodeport
.
Mailhog
Mailhog installation is straightforward, but we’ll configure it to use ingress routing. This setup enables browser access to the Mailhog UI for reviewing emails sent by Mautic.
Create a configuration file for Mailhog:
|
|
Now, install the Mailhog chart using this configuration:
|
|
Mautic
I’m leveraging the robust mautic-chart repository maintained by Tanjim Hossain. A few quirks need addressing before running the service properly. I’ll raise these issues with the author, but at the time of writing, these steps were crucial.
Missing favicon ConfigMap
The Helm chart flags a missing ct-favicon
ConfigMap definition, necessitating manual creation.
|
|
|
|
Adjust values files
Modify specific properties from the original chart’s values.yaml file:
- Update
SITE_URL
tohttp://mautic.local
, - Revise
MAUTIC_ADMIN_*
related credentials, - Configure
MAUTIC_MAILER_DSN
tosmtp://mailhog.default.svc.cluster.local:1025
for Mailhog SMTP integration, - Modify the HTTP health-check probe to respond to 200 status code instead of 301,
- Update
db
properties, setting the host tomysql.default.svc.cluster.local
and adjusting user credentials accordingly - Enable
ingress
mode by setting the service host tomautic.local
Optional adjustments::
- Fine-tune cron job schedules (see below)
- Enable API access by setting both
MAUTIC_API_ENABLED: "1"
andMAUTIC_API_ENABLE_BASIC_AUTH: "true"
, - Add geo IP lookup table credentials by setting the
MAUTIC_IP_LOOKUP_AUTH
variable.
You can reference the example of the desired mautic-values.yaml
file here.
By default, the config/local.php
config file is set to be read-only, which prevents you from manually configuring the service. However, you can temporarily relax the permissions to look up the file after changes and persist them in your mautic-values.yaml
.
Notice the variable prefix of MAUTIC_
required for the changes to be applied to the file.
|
|
Start service and fix permissions issue
At this point, you should be able to install the Helm chart using the specific revision.
|
|
After a while, you’ll notice that the mautic
pod fails to start due to the healthcheck endpoint returning a 500 status code.
The error is caused by Kubernetes claiming invalid ownership of the var/ directory. We can resolve this manually:
|
|
After this adjustment, the entire stack should be fully functional.
Web UI access
To reach both Mailhog and Mautic apps in the browser, we’ll leverage Minikube’s tunneling feature.
|
|
Additionally, add the following entries to the /etc/hosts
file:
|
|
And voilà, you should be able to access both Mautic and Mailhog from the browser.
API access
Here are a couple of examples of how you can interact with Mautic using the HTTP API. Before proceeding, ensure that you’ve enabled API access in the mautic-values.yaml
file.
Each request requires authorization, meaning you need to provide your credentials using basic auth. Assuming the username is admin
with password Maut1cR0cks!
, the authorization header should look like this:
|
|
|
|
|
|
|
|
You can reference Mautic Developer docs for a full API reference here.
Jobs
Mautic leverages jobs to process background tasks. There are a few types of jobs, each with different purposes and interdependencies. These jobs are often set up with cron jobs at the server level but can also be triggered via CLI.
mautic-values.yaml
by setting the enabled
property to false
and then execute the php bin/console <job_name>
command.Essentials
Several essential cron jobs are required to keep the Mautic service running and updating data in the background, laying the groundwork for its core functionality. Note that most of them can be parameterized for efficiency (like the input batch size).
The following ones are dependent on each other, thus they should be staggered and scheduled in the following order:
mautic:segments:update
This job identifies new contacts to be added to a segment and orphaned contacts to be removed from segments. (code) (alias mautic:segments:rebuild
)
mautic:campaigns:rebuild
This job updates campaign membership by adding or removing contacts from campaigns based on the selected segments. (code) (alias mautic:campaigns:update
)
mautic:campaigns:trigger
This job triggers timed events for published campaigns. (code)
Queue processing
Events like sending emails and registering page hits are buffered in the messenger_messages
table using the Doctrine framework. You need to set up certain jobs to periodically process the queue.
messenger:consume email
Consume email messages from the message queue and process them.
messenger:consume hit
Consumes page/video hits from the message queue and processes them.
messenger:consume failed
Consumes failed messages from the message queue and tries to re-processes them.
Others
mautic:broadcasts:send
Handles the sending of scheduled emails (by setting Publish/Unpublish dates).
mautic:messages:send
Attempts to process all pending (bounced) emails that haven’t reached their maximum retry count.
php bin/console
command without any arguments, you will see the list of available Mautic jobs.Next steps
- Deploy Mautic on a public cloud provider with SSL/TLS certificates.
- Configure Mautic to send emails using a real SMTP server.
- Set up database backup policies.
- Configure data migration tools to feed the Mautic with real data.