MultiPortal Support does not cover High Availability unless they have been deployed by MultiPortal Professional Services team.
This article shows how to install MultiPortal on HA configuration. With this setup, you can deploy front facing HAProxy Load Balancer to distribute workload.

3 virtual or physical machines with OS installed. (for this guide, we use Ubuntu 24.04)
Internet Connectivity
Install MultiPortal following the guide Ubuntu | MultiPortal or Installation Guide | MultiPortal.
For this guide, we used the FQDN for servers below
mpha004.lab.multiportal.io
mpha005.lab.multiportal.io
mpha006.lab.multiportal.io
Login to 3 nodes and install required packages by running command below
apt update
apt install mariadb-server galera-arbitrator-4 mariadb-backup -y
Once Installed, login to node 2 (mpha005) and run commands below
login as root by running command below
sudo -i
run the command below to delete the database on node 2 and node 3
mariadb -u root -e "DROP DATABASE multiportal;"
stop the services
systemctl stop caddy.service
systemctl stop multiportal.service
systemctl stop mariadb.service
repeat steps above on node 3 (mpha006)
Login to node1 (mpha004) create mariabackup user and configure galera cluster
login as root by running command below
sudo -i
create log directory
mkdir /var/log/mariadb
chown mysql:mysql /var/log/mariadb
create mariabackup user by running commands below
mariadb -u root -e 'create user "mariabackup"@"%" identified by "b@ckup123!";'
mariadb -u root -e 'GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO "mariabackup"@"%";'
mariadb -u root -e 'create user "mariabackup"@"localhost" identified by "b@ckup123!";'
mariadb -u root -e 'GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO "mariabackup"@"localhost";'
mariadb -u root -e 'flush privileges;'
modify server config file by running command below
cat <<EOL >> "/etc/mysql/mariadb.conf.d/50-server.cnf"
log_warnings=2
log_error=/var/log/mysql/mariadb.err
general_log = 1
general_log_file = /var/log/mysql/mariadb.log
[mariabackup]
user=mariabackup
password='b@ckup123!'
databases-exclude=lost+found
EOL
configure mariadb galera cluster by editing the file /etc/mysql/mariadb.conf.d/60-galera.cnf
#
# * Galera-related settings
#
# See the examples of server wsrep.cnf files in /usr/share/mysql
# and read more at https://mariadb.com/kb/en/galera-cluster/
[galera]
# Mandatory settings
wsrep_on = ON
wsrep_cluster_name = "galera_cluster"
wsrep_cluster_address = "gcomm://NODE1IP,NODE2IP,NODE3IP" #configurethis
wsrep_provider=/usr/lib/galera/libgalera_smm.so
binlog_format = row
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
# Allow server to accept connections on all interfaces.
bind-address = 0.0.0.0
# Optional settings
wsrep_slave_threads = 1
innodb_flush_log_at_trx_commit = 0
wsrep_sst_auth = mariabackup:manager
wsrep_sst_method = mariabackup
wsrep_node_address = THISNODEIP #configurethis
wsrep_sst_receive_address= THISNODEIP #configurethis
sample configuration:
#
# * Galera-related settings
#
# See the examples of server wsrep.cnf files in /usr/share/mysql
# and read more at https://mariadb.com/kb/en/galera-cluster/
[galera]
# Mandatory settings
wsrep_on = ON
wsrep_cluster_name = "galera_cluster"
wsrep_cluster_address = "gcomm://192.168.112.204,192.168.112.205,192.168.112.206"
wsrep_provider=/usr/lib/galera/libgalera_smm.so
binlog_format = row
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
# Allow server to accept connections on all interfaces.
bind-address = 0.0.0.0
# Optional settings
wsrep_slave_threads = 1
innodb_flush_log_at_trx_commit = 0
wsrep_sst_auth = mariabackup:manager
wsrep_sst_method = mariabackup
wsrep_node_address = 192.168.112.204
wsrep_sst_receive_address= 192.168.112.204
stop mariadb service by running command below
systemctl stop mariadb.service
bootstrap the new cluster by running command below
galera_new_cluster
verify if cluster is running by running command below
ps -f -u mysql
The start position on the very first start should look like the following.
UID PID PPID C STIME TTY TIME CMD
mysql 89612 1 0 02:36 ? 00:00:01 /usr/sbin/mariadbd --wsrep-new-cluster --wsrep_start_position=00000000-0000-0000-0000-000000000000:-1
Configure the .env file on all nodes
login to node1 and get the DB_PASS details by running command below
cat /var/www/CURRENTNODEFQDN/.env | grep DB_PASS
Login to node 2 and node3. Modify the DB_PASS entry on /var/www/CURRENTNODEFQDN/.env
vi /var/www/CURRENTNODEFQDN/.env
This step ensures that the DB_PASS on node1 (.env), will be copied to node2 and node3.
Join node 2 to galera cluster
login as root by running command below
sudo -i
create log directory
mkdir /var/log/mariadb
chown mysql:mysql /var/log/mariadb
modify server config file by running command below
cat <<EOL >> "/etc/mysql/mariadb.conf.d/50-server.cnf"
log_warnings=2
log_error=/var/log/mysql/mariadb.err
general_log = 1
general_log_file = /var/log/mysql/mariadb.log
[mariabackup]
user=mariabackup
password='b@ckup123!'
databases-exclude=lost+found
EOL
configure mariadb galera cluster by editing the file /etc/mysql/mariadb.conf.d/60-galera.cnf
#
# * Galera-related settings
#
# See the examples of server wsrep.cnf files in /usr/share/mysql
# and read more at https://mariadb.com/kb/en/galera-cluster/
[galera]
# Mandatory settings
wsrep_on = ON
wsrep_cluster_name = "galera_cluster"
wsrep_cluster_address = "gcomm://NODE1IP,NODE2IP,NODE3IP" #configurethis
wsrep_provider=/usr/lib/galera/libgalera_smm.so
binlog_format = row
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
# Allow server to accept connections on all interfaces.
bind-address = 0.0.0.0
# Optional settings
wsrep_slave_threads = 1
innodb_flush_log_at_trx_commit = 0
wsrep_sst_auth = mariabackup:manager
wsrep_sst_method = mariabackup
wsrep_node_address = THISNODEIP #configurethis
wsrep_sst_receive_address= THISNODEIP #configurethis
sample configuration:
#
# * Galera-related settings
#
# See the examples of server wsrep.cnf files in /usr/share/mysql
# and read more at https://mariadb.com/kb/en/galera-cluster/
[galera]
# Mandatory settings
wsrep_on = ON
wsrep_cluster_name = "galera_cluster"
wsrep_cluster_address = "gcomm://192.168.112.204,192.168.112.205,192.168.112.206"
wsrep_provider=/usr/lib/galera/libgalera_smm.so
binlog_format = row
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
# Allow server to accept connections on all interfaces.
bind-address = 0.0.0.0
# Optional settings
wsrep_slave_threads = 1
innodb_flush_log_at_trx_commit = 0
wsrep_sst_auth = mariabackup:manager
wsrep_sst_method = mariabackup
wsrep_node_address = 192.168.112.205
wsrep_sst_receive_address= 192.168.112.205
restart mariadb service by running command below
systemctl restart mariadb.service
verify if cluster is running by running command below
ps -f -u mysql
Output should look like the following.
UID PID PPID C STIME TTY TIME CMD
mysql 89612 1 0 02:36 ? 00:00:01 /usr/sbin/mariadbd --wsrep-new-cluster --wsrep_start_position=00000000-0000-0000-0000-000000000000:-1
Run the command below to see if it joined successfully
mariadb -u root -e "show global status like 'wsrep_cluster_size';"
Output should look like the following
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 2 |
+--------------------+-------+
Repeat Step6 on node3
verify if cluster is running by running command below
ps -f -u mysql
Output should look like the following.
UID PID PPID C STIME TTY TIME CMD
mysql 89612 1 0 02:36 ? 00:00:01 /usr/sbin/mariadbd --wsrep-new-cluster --wsrep_start_position=00000000-0000-0000-0000-000000000000:-1
Run the command below to see if it joined successfully
mariadb -u root -e "show global status like 'wsrep_cluster_size';"
Output should look like the following
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+
Start Services
run this command on all nodes
systemctl status multiportal
systemctl start caddy
You may now access MultiPortal on any node URL http://nodefqdn/ and start with the configuration of users