Installing a Web, Email & MySQL Database Cluster on Debian 8.4 Jessie with ISPConfig 3.1

This tutorial describes the installation of a clustered web, email, database and DNS server to be used for redundancy, high availability and load balancing on Debian 8 with the ISPConfig 3 control panel. MySQL Master/Master replication will be used to replicate the MySQL client databases between the servers, Unison will be used to Sync the /var/www (websites) and the Mails will be synced with Dovecot.


1 General note

In this setup, there will be one master server (which runs the ISPConfig control panel interface) and one slave server which mirrors the web (apache), email (postfix and dovecot), dns (bind) and database (MySQL or MariaDB) services of the master server.

To install the clustered setup, we need two servers with a Debian 8.4 minimal install and the same ISPConfig version.

In my example I use the following hostnames and IP addresses for the two servers:

Master Server

Hostname: server1.example.tld
IPv6-Address: 2001:db8::1

Slave server

Hostname: server2.example.tld
IPv6-Address: 2001:db8::2

Wherever these hostnames or IP addresses occur in the next installation steps you will have to change them to match the IP's and hostnames of your servers.

All commands must be run as the root user. If you need to make changes in MySQL login into MySQL with the root-password for MySQL:

mysql -u root -p

2 Install the Master Server

First we need to install ISPConfig on the Master-Server. If you have already installed ISPConfig on this Server, you can skip the installation (ensure, that the existing installation is up-to-date).

Install ISPConfig on the Master-Server according to The Perfect Server - Debian 8.4 Jessie (Apache2, BIND, Dovecot, ISPConfig 3.1).

Add the Slave Server to the /etc/hosts file

vi /etc/hosts

so it looks like:       localhost   server1.example.tld server1
2001:db8::1 server1.example.tld server1 server2.example.tld
2001:db8::2 server2.example.tld # The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters ff02::3 ip6-allhosts

3 Prepare the Slave Server

Run steps 1 - 19 from The Perfect Server - Debian 8.4 Jessie (Apache2, BIND, Dovecot, ISPConfig 3.1).

Do not install ISPConfig on server2 yet.

Add the Master Server to the /etc/hosts file

vi /etc/hosts

so it looks like:       localhost   server1.example.tld
2001:db8::1 server1.example.tld server2.example.tld server2
2001:db8::2 server2.example.tld server2 # The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters ff02::3 ip6-allhosts

4 Keyless Login from Server1 to Server2

On server2:

We allow temporarily the root-login into server2 with a password. Open /etc/sshd_config:

vi /etc/ssh/sshd_config

and change

PermitRootLogin without-password


PermitRootLogin yes

afterwards, restart the ssh-daemon:

service ssh restart

On server1:

Create a private/public key pair:


Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): <-- ENTER
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): <-- ENTER
Enter same passphrase again: <-- ENTER
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/
The key fingerprint is:
f3:d0:62:a7:24:6f:f0:1e:d1:64:a9:9f:12:6c:98:5a [email protected]
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|           .     |
|          +      |
|       + *       |
|      E S +      |
|     o O @ .     |
|    .   B +      |
|       o o       |
|        .        |

It is important that you do not enter a passphrase otherwise the mirroring will not work without human interaction so simply hit ENTER!

Next, we copy our public key to server2.example.tld:

ssh-copy-id -i /root/.ssh/ [email protected]

The authenticity of host ' (' can't be established.
ECDSA key fingerprint is 25:d8:7a:ee:c2:4b:1d:92:a7:3d:16:26:95:56:62:4e.
Are you sure you want to continue connecting (yes/no)? <-- yes (you will see this only if this is the first time you connect to server2)
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys

[email protected]'s password: <- enter root password from server2

Now try logging into the machine:

ssh [email protected]

And check /root/.ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting.

cat /root/.ssh/authorized_keys

ssh-dss AAAAB3NzaC1kc3MAAACBAPhiAexgEBexnw0rFG8lXwAuIsca/V+lhmv5lhF3BqUfAbL7e2sWlQlGhxZ8I2UnzZK8Ypffq6Ks+lp46yOs7MMXLqb7JBP9gkgqxyEWqOoUSt5hTE9ghupcCvE7rRMhefY5shLUnRkVH6hnCWe6yXSnH+Z8lHbcfp864GHkLDK1AAAAFQDddQckbfRG4C6LOQXTzRBpIiXzoQAAAIEAleevPHwi+a3fTDM2+Vm6EVqR5DkSLwDM7KVVNtFSkAY4GVCfhLFREsfuMkcBD9Bv2DrKF2Ay3OOh39269Z1rgYVk+/MFC6sYgB6apirMlHj3l4RR1g09LaM1OpRz7pc/GqIGsDt74D1ES2j0zrq5kslnX8wEWSHapPR0tziin6UAAACBAJHxgr+GKxAdWpxV5MkF+FTaKcxA2tWHJegjGFrYGU8BpzZ4VDFMiObuzBjZ+LrUs57BiwTGB/MQl9FKQEyEV4J+AgZCBxvg6n57YlVn6OEA0ukeJa29aFOcc0inEFfNhw2jAXt5LRyvuHD/C2gG78lwb6CxV02Z3sbTBdc43J6y [email protected]

Disallow root-login with a password. Open /etc/sshd_config:

vi /etc/ssh/sshd_config

and change

PermitRootLogin yes


PermitRootLogin without-password

afterwards, restart the ssh-daemon:

service ssh restart

Logout from server2:


Connection to closed.

We are now back on server1.

Share this page:

Suggested articles

17 Comment(s)

Add comment


From: Slayer

Nice job! thx

From: Saeid

Thank you,Thats very helpful article. Good explanation and clear instruction.I assume it will be same if I want to implement that on Ubuntu 16.04 LTS server, right?That would be greate if you confirm it's working fine if I alter my current single server setup of ISPConfig to be changed to cluster based system.Thanks again...

From: Ilko

Hi do you know a tutorial to add load balancer on the system which shares the load between the 2 servers?

From: Hias

Very good tutorial! Can u tell me, what to do, in cause of failover IPs?

From: Butty Pierre-André

hi ! great Tuto, on Step 6 with Download ISPConfig 3.1, an Type Error with the line :

tar xfvz xfz ISPConfig-3.1-beta.tar.gz, the second xfz is too.

From: Pierre-André Butty

hi !

i mean instead of "tar xfvz xfz ISPConfig-3.1-beta.tar.gz" on step 6 with upload of ISPConfig 3.1 only "tar xfvz ISPConfig-3.1-beta.tar.gz" ist ok.


From: Edijs Zatevahins

Thank you. But what means (commenting out all existing conflicting options):

How i know which one's is conflicting options?

From: Zoltan Laczko

And what about PHP session files sync?

From: Jeff S

For the section 5.5, which server is this step being perfomed on?


5.5 MySQL Master-Master-Replication

Create the MySQL-User for the replication and grant the privileg in MySQL:

CREATE USER 'slaveuser1'@'server1.example.tld' IDENTIFIED BY 'slave_user_password';CREATE USER 'slaveuser1'@'' IDENTIFIED BY 'slave_user_password';CREATE USER 'slaveuser1'@'2001:db8::1' IDENTIFIED BY 'slave_user_password';GRANT REPLICATION SLAVE ON *.* TO 'slaveuser1'@'server1.example.tld'; GRANT REPLICATION SLAVE ON *.* TO 'slaveuser1'@'';GRANT REPLICATION SLAVE ON *.* TO 'slaveuser1'@'2001:db8::1';QUIT;

From: stone1555

Can someone clarify on which server section 5.5 and 6 commands are to be run?

From: Peter

It is creating a Slave(second server) user to the 1st (master) server.

CREATE USER 'slaveuser1'@'server1.example.tld'

So its on the first, master server or server1.example.tld...

From: Mounaam


last char is missing for server2 in below line

> relay-log-index          = slave-relay-log.inde

Best regards,Mounaam

From: Marc

In chapter 5.4 it's important to note that by importing the sql from server1 to the slave you overwrite your MySQL credentials.

I had different SQL passwords for root on both servers and of course the login didn't work on the slave after overwriting it.

From: Alex

Is there a reason why we don't install webinterface on server 2? 

So If I shutdown the ISPConfig server 1 how can I see the interface?

From: Florian Leo

And where is mentioned that you would need some sort of SQL-DB installed first?

From: npalokan

I am not quite sure about high availability. Lets imagine that my server1 goes down, server2 keeps going fully functional. If I have website that's in my servers has A record thats pointing to server1 IP-address. In this situation when I am trying to access my site, it's not available, because server1 is down. And if I am not using low TTL, I cannot even change dns IP manually, so it's getting spread around fast enough. Even if you give two a records (both server IP's) it's only working on every two requests (round-robin rule), you know it's not good solution either in this situation.As my opinion it would be great if server1 dns uses it's own IP in A-records etc... and server2 uses it's own. Of course this still needs low TTL, but even with that, it would be much more high available than this current solution.Or is there something I just don't understand corretly :/

From: Tobias


i don not really understand, why i have to do 5.1-5.4 a mysql Master-Slave Cluster and on position 5.5 a master-master cluster.

Is 5.5. alternative?


Thanks a lot