Currently PHP developers face a great problem with PHP version - most OS repos already have outdated versions (CentOS has 5.4 which has passed its end of life!), but just swapping out versions is just not an option - especially with the version requirements of different frameworks / libraries. Furthermore, usually to have more than one version meant recompiling, and keeping up with updates - and no one wants that. Here's how to setup a server (virtual of physical), with ISPConfig3 hosting panel, multiple PHP versions, latest Apache and Mariadb in less than a half hour, with zero compiling. You can then manage your virtual hosts and their PHP version from a nice UI.
Part 1: Assumptions of what you have and where you want to go
First, assumptions! Here is what I assume you have already done:
- Installed a minimal CentOS7 to a working condition
- Have an IP or hostname for that machine
- You can SSH into the machine, and become root
- You can access the internet
- Have run yum update right before you start
- SELINUX IS DISABLED (read: the steps required for SELinux to run have not been included)
And this is where we want to go:
- Apache 2.4.18 (not 2.4.6 which comes in CentOS base and has known vulnerabilities)
- PHP 5.4 in mod_php, FastCGI, and FPM mode
- PHP 5.6 in FastCGI and FPM mode
- PHP 7.0 in FastCGI and FPM mode
- Use firewalld to manage your firewall
- ISPConfig 3 panel to manage virtual hosts, databases, and PHP versions
Conventions / Sample data:
- Server hostname is test.hexblot.com
- MariaDB root password will be testerson
- FPM port for PHP5.4 will be 9000
- FPM port for PHP5.6 will be 9006
- FPM port for PHP7.0 will be 9007
Still here? Great! Onto the works.
Part 2: Prep our environment
First, we need to get some repos in for extra packages, and setup our firewall (you can do the firewall bit at the end, I just like to get the generic things out of the way early):
yum install epel-release wget firewalld
Now let's get our firewall configured. We will allow traffic from http (port 80), https (port 443) and port 8080 (for our panel). We'll also remove the dhcp client for IPv6, since we want static IPs all around.
systemctl start firewalld systemctl enable firewalld firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --permanent --add-port=8080/tcp firewall-cmd --permanent --remove-service=dhcpv6-client firewall-cmd --reload
You can look at your fine work by using
firewall-cmd --list-all
With our firewall ready, let's get the extra repositories we'll need for our later steps:
First, the IUS repo by Rackspace -
wget https://centos7.iuscommunity.org/ius-release.rpm
Then the safe repository by Remi -
wget http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
And get them installed:
rpm -ivh ius-release.rpm remi-release-7.rpm
All set, on to the meat of things.
Part 3: Apache
Very vanilla things here, just install the packages from the IUS repo and start/enable the service. Most of the configuration will be done by ISPConfig later on.
yum install httpd24u mod24u_ssl mo24u_session mod_fcgid mod_xsendfile systemctl start httpd systemctl enable httpd
Part 4: MariaDB 10.1
To get the latest and greatest, both in terms of performance and least vulnerabilities, we choose MariaDB 10.1, again from the IUS repo. The trick here is that CentOS comes bundled with the mariadb-libspackage, which conflicts with any other version. Hence, we'll swap it out using the very helpful yum-replace-plugin provided by the IUS repo.
yum install yum-plugin-replace yum replace mariadb-libs -replace-with=mariadb101u-libs
yum install mariadb101u mariadb101u-server
At this point, I'd recommend you create a configuration file optimized for your server and usage before first starting MariaDB. Changing the config file later on is bound to cause issues! A good generator tool by Percona is available here. Paste the generated configuration at /etc/my.cnf , and then start MariaDB:
systemctl start mariadb systemctl enable mariadb
Depending on a number of factors, starting MariaDB can take a while, be patient.
Be sure to run
mysql_secure_installation
to disable anonymous access to your databases!! Just remember the root password you set (in this example, testerson was used).
Part 5: PHP 5.4 (CentOS repos)
Not much really. This will simply install the required packages, and we're ready to go.
yum install php php-bcmath php-cli php-common php-gd php-intl php-mbstring php-mysqlnd php-pdo php-pear php-soap php-xml php-xmlrpc php-fpm
Reload Apache to get mod_php and fcgi mode to work:
systemctl restart httpd
And start the FPM process
systemctl start php-fpm systemctl enable php-fpm
Do note that currently you need special configuration to send bit to FPM - this will be handled by ISPConfig later on though, so no need to do anything yet.
Part 6: PHP 5.6 (Remi-safe repos)
Here's where it starts getting interesting. Remi-safe repo provides alternate version of PHP and support packages, in a no-conflict mode by using the php version as a prefix to everything. This means that your FPM service will be php56-php-fpm , your php.ini will be different, and your cli will be php56 .
yum install php56-php-bcmath php56-php-cli php56-php-common php56-php-fpm php56-php-gd php56-php-intl php56-php-mbstring php56-php-mcrypt php56-php-mysqlnd php56-php-opcache php56-php-pdo php56-php-pear php56-php-pecl-uploadprogress php56-php-soap php56-php-xml php56-php-xmlrpc
Again, feel free to add more php56-php-* packages to enhance your PHP5.6 functionality.
One thing to pay attention to at this point is that we cannot start our FPM process, since it will conflict with the already installed PHP (they both start at the same port). To fix that, use your favorite command line editor, and edit /opt/remi/php56/root/etc/php-fpm.d/www.conf so that
listen = 127.0.0.1:9000
is changed to something like
listen = 127.0.0.1:9006
You can use any port number with the following limitations:
- 9000 is currently used by our PHP5.4 process
- 9010 is the base port that ISPConfig will use (each site gets its own pool, starting at 9010. Next site will be at 9011, and so on)
After you save your changes, you can move on to start the PHP56 FPM service
systemctl start php56-php-fpm systemctl enable php56-php-fpm
And you're done with this part.
Part 7: PHP 7.0 (Remi-safe repos)
As with before, we'll be installing PHP7.0 in no-conflict mode. This means that your FPM service will be php70-php-fpm, your php.ini will be different, and your cli will be php70.
yum install php70-php-bcmath php70-php-cli php70-php-common php70-php-fpm php70-php-gd php70-php-intl php70-php-json php70-php-mbstring php70-php-mcrypt php70-php-mysqlnd php70-php-opcache php70-php-pdo php70-php-pear php70-php-pecl-uploadprogress php70-php-pecl-zip php70-php-soap php70-php-xml php70-php-xmlrpc
As with PHP56, we need to change the port for our FPM service. This time, the configuration file we need is located at /etc/opt/remi/php70/php-fpm.d/www.conf . Open the file in your favorite editor, and change:
listen = 127.0.0.1:9000
to:
listen = 127.0.0.1:9007
Same port restrictions as with PHP56 (you cannot obviously use 9006 or any port you chose in the previous step - needs to be a different port). Save and start/enable:
systemctl start php70-php-fpm systemctl enable php70-php-fpm
And you're done once more.
Part 8: Installing ISPConfig
Installation of ISPConfig is quite straight forward:
- Download the ISPConfig package from http://www.ispconfig.org/ispconfig/download/ . At the time of writing, latest version was 3.0.5.4p9. Assuming that's still the case, you can use the direct download link to get the package
wget http://downloads.sourceforge.net/project/ispconfig/ISPConfig%203/ISPConfig-3.0.5.4p9/ISPConfig-3.0.5.4p9.tar.gz
- Extract the contents of the downloaded file
tar zxvf ISPConfig-3.0.5.4p9.tar.gz
- Run the installer
php -q ispconfig3_install/install/install.php
- Select options as desired. For this example, we'll be using the following options (I am not including all of them):
- Language: en
- Installation mode: expert
- Fully Qualified hostname (FQDN): your hostname or IP if you don't have one
- MySQL server hostname: localhost
- MySQL root username: root
- MySQL root password: whatever you chose in Part4
- MySQL database to create: dbispconfig
- MySQL charset: utf8
- ISPConfig mysql username: ispconfig
- ISPConfig mysql database password: accept the generated hash
- Shall this server join an existing ISPConfig multiserver setup? N
- Configure mail? N (unless you have followed a guide for adding email capabilities to the system)
- Configure JailKit? N (unless you have followed a guide for adding jailkit)
- Configure FTP server? N (unless you have followed a guide for adding an FTP server
- Configure Apache Server? Y
- Configure Firewall? N
- Install ISPConfig Web Interface? Y
- ISPConfig Port? 8080
- Enable SSL? Y - accept defaults for the CSR of your self-signed certificate, or fill up any data you want. Just make sure NOT to include a challenge password.
- Installation complete! ( you'll get a warning about date() and setting a timezone in php.ini , which is beyond the scope of this tutorial, and can be ignored ).
Part 9: Configuring Additional PHP version in ISPConfig
Congratulations for reaching this far! Now on to configuring ISPConfig to be able to use all the nice stuff we just installed.
First off , head to your panel to login - you should be able to see the interface at https://your-hostname.com:8080 - in our example, https://test.hexblot.com:8080 and login with the default credentials ( username admin, password admin ).
First things first - change the admin account credentials!
- Go to the System tab from the top horizontal menu
- Click on CP Users from the left side menu
- Change the username and password of the admin userPersonally, I also uncheck most of the modules there, since I do not use them (eg dns, dashboard, mail, help, vm)
Now, on to configuring additional PHP versions!
- Go to the System tab from the top horizontal menu if you aren't already there (which you really should!)
- Click on Additional PHP Versions from the left side menu
- Click on Add new PHP version
- Add control panel identification data in the Name tab
- Server should already be selected - if this were a multiserver setup, you could select another server.
- Client should be left blank, unless you want this PHP version to be only available for a specific client
- PHP Name is what you'll see in the panel to refer to this PHP version. Type in PHP5.6
- Switch to the FastCGI Settings tab (no need to click save, the panel auto saves when moving between tabs).Here type:
- Path to the PHP FastCGI binary : /opt/remi/php56/root/usr/bin/php-cgi
- Path to the php.ini directory : /opt/remi/php56/root/etc
- Switch to the PHP-FPM Settings tab. Here type:
- Path to the PHP-FPM init script : php56-php-fpm
- Path to the php.ini directory : /opt/remi/php56/root/etc
- Path to the PHP-FPM pool directory : /opt/remi/php56/root/etc/php-fpm.d
- Click Save - you are done with PHP5.6! (Don't try until we're done with Part10, since FPM won't properly work until then!)
- Repeat the process for PHP7 with the following settings:
- Name tab
- Name: PHP70
- FCGI tab
- Path to the PHP FCGI binary: /opt/remi/php70/root/usr/bin/php-cgi
- Path to the php.ini directory: /etc/opt/remi/php70
- PHP FPM tab
- Path to the PHP-FPM init script: php70-php-fpm
- Path to the php.ini directory: /etc/opt/remi/php70
- Path to the PHP-FPM pool directory: /etc/opt/remi/php70/php-fpm.d
- Name tab
- All done with PHP7!
You should now be able to go to the Sites horizontal tab, and click on Add New Website, and under PHP see Fast CGI and PHP FPM ( with proper version options - default is 5.4, and the rest have the names we've given them ).
But wait? I chose PHP FPM with version PHP 5.6 and nothing happened!!! What's going on? Read on!
Part 10: Fixing a CentOS 7 specific misbehavior of ISPConfig
For some reason (probably earlier version compatibility), ISPConfig under CentOS7 will always try to reload the base php-fpm service instead of the one selected. This is an override for reasons unknown to me, and my simple patch for that has been accepted for ISPConfig 3.1. It's so simple that we'll apply it right now!
Use your favorite text editor to edit the file /usr/local/ispconfig/server/mods-available/web_module.inc.php
Comment out lines 255 and 267, changing both from
$initcommand = 'systemctl restart php-fpm.service';
to
// $initcommand = 'systemctl restart php-fpm.service';
This is an inefficient but simple way around the issue, but will do the job just fine. A better way would be to comment out the blocks that do the whole override thing, and the easiest way to describe that is to show you the diff for it here .
Either way works, and ISPConfig will happily work after this with your FPM versions!
If, understandably, you don't like waiting about you can manually trigger this process by running
/usr/local/ispconfig/server/server.sh