Running multiple instances of Apacheby Arnold Daniels on 03/26/2007
Life as a shared hosting provider hasn’t become easier after PHP decided that they would allow compatibility breakage between mayor versions. Some providers managed to keep there customers satisfied while only supporting PHP 4, but lots of new projects are PHP 5 only and the problem will become even bigger when PHP 6 is released.
Usually a daemon (a service for you windows folks) is started once, with only one instance running. The same goes for Apache. However when we look closely at the apache config, we see that variables which prevent apache from being started twice, the pid file, lockfile and ip/port, can be configured. When starting apache, the config file can be specified, which allows to run multiple instances of apache (on different ip’s).
Now we can simply change the IP address of a domain in the DNS, to switch is from PHP 4 to PHP 5. The same trick can also be used easily switch the plan of an account from basic (only static html pages) to gold (php and perl support) to platinum (php, perl, ruby and jsp support), without having to move the account to another server.
Back to PHP, lets go trough the steps of setting up the server to run PHP 4 next to PHP 5.
NOTE: This tutorial assumes you are working on an Ubuntu or Debian linux system.
Step 1 – Building php
First we need build PHP 4 and PHP 5 in a way that the paths and filenames won’t conflict. I won’t go into details about building PHP, but you will need to add the following to configure for PHP 5:
./configure '--libdir=/usr/lib/php5' \ '--includedir=/usr/include/php5' \ '--program-suffix=5' \ '--with-exec-dir=/usr/lib/php5/libexec' \ '--with-config-file-path=/etc/php5/'
Step 2 – Create additional apache configuration files
Because all instances will have more of less the same configuration we will include apache2.conf for the common configuration and use a macro to setup the differences. If you haven’t installed mod-macro already, please install it (apt-get install libapache2-mod-macro) and enable it (a2enmod macro).
We want to specify the IP-address per instance, so please remove the content of /etc/apache2/ports.conf. Also remove the symlinks of all modules that should not be loaded in all instances (like php5_module) from /etc/apache2/mods-enabled.
Create a file called /etc/apache2/apache2-instance.macro and enter your per instance configuration, eg:
<Macro SetupInstance $instance $ip> LockFile /var/lock/apache2/$instance.accept.lock PidFile /var/run/apache2/$instance.pid ErrorLog /var/log/apache2/$instance/error.log Listen $ip:80 </Macro>
Include /etc/apache2/apache2.conf Include /etc/apache2/apache2-instance.macro Use SetupInstance "apache2-php4" "192.168.1.50"
LoadModule php4_module /usr/lib/apache2/modules/libphp4.so <IfModule mod_php4.c> AddType application/x-httpd-php .php .phtml .php3 AddType application/x-httpd-php-source .phps </IfModule>
Also create apache2-php5.conf. Do not forget to create /var/log/apache2/apache2-php4 and /var/log/apache2/apache2-php5.
Step 3 – Changing the scripts
When you run ‘apache2ctl start’, the script will display “no listening sockets available, shutting down” and exit. This is expected, though we do want to start apache, so we need to change the script.
Copy the /usr/sbin/apache2ctl to /usr/sbin/apache2-php4ctl and /usr/sbin/apache2-php5ctl. Edit apache2-php4ctl and change HTTPD to
HTTPD='/usr/sbin/apache2 -f /etc/apache2/apache2-php4/apache2.conf'
Do the same for apache2-php5.
There’s another script that has to be changed, which is located in /etc/init.d. Copy /etc/init.d/apache2 to /etc/init.d/apache2-php4 and /etc/init.d/apache2-php5 and move the file to /etc/init.d/apache2.org.
Edit /etc/init.d/apache2-php4 and set
The script tries to find the PID by getting the name of the pidfile from the config, but that won’t work because we’re using a macro. So simply set
PIDFILE='/var/run/apache2/apache2-php4.pid' if [ -e "$PIDFILE" ] ; then PID=`cat "$PIDFILE"` fi
Comment out everything from ‘for i in $AP_CONF’ to ‘done’. Make the same changes for /etc/init.d/apache2-php5.
Last create a new /etc/init.d/apache2 script (mind the execute privs) with the following content:
#!/bin/sh ./apache2-php4 $@ ./apache2-php5 $@
Simply restart your server and you’re up and running. You might want to stray a bit from this example to match your own configuration, but anyhow I hope this have given you some ideas.