In a web server very old applications must coexist with new ones. Usually old applications are no more mantained and still require old versions of
mysql, while recent apps claim to use the latest features of your
php and database servers. In addition you may want to switch from
mariaDB, which is going to quickly supersede its progenitor program.
That said, how to build a web server which mounts on the same apache a variety of
php/mysql/mariadb configurations? Let's consider a simple case and suppose to have an
apache 2.4.x already installed and two database server, let's say
mariadb-5.5, listening on two different IPs. We would like to have two separate
php versions available, let's say 5.3.x and 5.4.x, living together and connecting to
mariadb respectively. Of course this procedure can be modified as you like for any number of configurations you like.
I will show how to achieve this goal by configuring
php in the usual
mod_php manner and by means of
apache module which starts
php requests as a CGI program, delivering very similar performance as
mod_php. I will show how to select the proper
php.ini file as well.
So, in the following I'm going to call old and new servers in this way:
You may want to take a look to the installation/configuration/upgrade/migration guides I wrote an howto for both the old
mysql and the new
When compiling your
php, it has to find the
mysql/mariadb installation folder, so you need to share it so that it will be available in the
apache web server. Let's suppose that you have the two database servers already installed according to this scheme (actually these should be folders shared by the servers which host the databases):
mysql-5.5 -> /usr/local/mysql mariadb-5.6 -> /usr/local/mariadb
apache/php configuration: php-5.3 and mod_php
This is the usual method to install
php in case you need a single
This is how I configure my
php as module:
./configure \ --with-mysql=/usr/local/mysql \ --with-mysqli=/usr/local/mysql/bin/mysql_config \ < --other-config-options \ > --prefix=/usr/local/php-5.3 \ --with-apxs2=/usr/local/apache/bin/apxs
The last line builds the apache's php_module. Note that php is going to be built against mysql, which is installed in /usr/local/mysql.
Now you have to tell apache to assign to mod_php all requests for .php files. And you have to do it inside each VirtualHost which is going to mount mod_php, so that apache will know if a certain VirtualHost is going to use mod_php or mod_fcgid.
That said, save a file like this in your apache conf dir:
# file mod_php-5.3 <IfModule mod_php5.c> <FilesMatch \.php$> AddHandler php5-script .php </FilesMatch> </IfModule>
This file has to be included by any VirtualHost which needs mod_php:
<VirtualHost *:80> DocumentRoot "/path/to/document/root" ServerName www.yourdomain.net Include "/path/to/mod_php-5.3" </VirtualHost>
apache/php configuration: php-5.4 and mod_fcgid
This module is not bundled into apache, so you must install it separately. If your apache's apxs program is not in your path you have to set the APXS environment variable to the apxs location.
APXS=/usr/local/apache/bin/apxs ./configure.apxs make make install
Now you have to prepare your VirtualHosts for mod_fcgid. Apache wants to know what to do with .php extensions.
Configuring and installing php as cgi
This is how you may want to configure php to look for mariadb libraries. Of course you don't have to compile the apache module here, otherwise it will overwrite the old php-5.3 module:
#!/bin/sh ./configure \ --with-mysql=/usr/local/mariadb \ --with-mysqli=/usr/local/mariadb/bin/mysql_config \ <--other-config-options \> --prefix=/usr/local/php-5.4
The configuration is looking for mariadb in the /usr/local/mariadb folder. Of course, expecially in case of many different db server are needed, this directory is mounted from the remote (virtual) mariadb server.
At this point you should edit your php.ini and set
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's ; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok ; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting ; this to 1 will cause PHP CGI to fix it's paths to conform to the spec. A setting ; of zero causes PHP to behave as before. Default is 1. You should fix your scripts ; to use SCRIPT_FILENAME rather than PATH_TRANSLATED. cgi.fix_pathinfo=1
This would be a good choice, as remainded in the commented text.
Preparing apache for mod_fgid
Create a text file like this in you apache conf dir:
# file mod_fcgid_php-5.4 <IfModule fcgid_module> AddHandler fcgid-script .php Options +ExecCGI FcgidWrapper /usr/local/bin/php-wrapper .php FcgidInitialEnv PHPRC "/path/to/php.ini" </IfModule>
This file tells apache to assign to fcgid each request for .php files, to consider such files as cgi scripts and to call a wrapper executable file, which in turn sets some environment variables and execute php-cgi. The last line selects the proper php.ini file (using mod_fcgid you can't adjust the php config via apache's php_value/php_flag).
This is the content of my wrapper file /usr/local/bin/php-wrapper
#!/bin/sh # Set desired PHP_FCGI_* environment variables. # Example: # PHP FastCGI processes exit after 500 requests by default. PHP_FCGI_MAX_REQUESTS=10000 export PHP_FCGI_MAX_REQUESTS # Replace with the path to your FastCGI-enabled PHP executable exec /usr/local/php-5.4/bin/php-cgi
remember to give +x priviledges to the wrapper file:
chmod +x /usr/local/bin/php-wrapper
Now you may want to configure a bit your mod_fgcid directly acting on the main config file httpd.conf:
# FcgidMaxRequestsPerProcess should be <= PHP_FCGI_MAX_REQUESTS # The example PHP wrapper script overrides the default PHP setting. FcgidMaxRequestsPerProcess 10000 # Uncomment the following line if cgi.fix_pathinfo is set to 1 in # php.ini: FcgidFixPathinfo 1
Finally you have to include the fcgid_php-5.4 file in each VirtualHost which needs to load php as cgi
<VirtualHost *:80> DocumentRoot "/path/to/document/root" ServerName www.example.net Include "/path/to/mod_fcgid_php-5.4" </VirtualHost>