This is the last part of my series on getting Apache 2 server that runs both PHP 7 and 5 with a custom compiling of PHP 5.
The last step to getting PHP 5 and 7 running is to custom compile PHP 5. For this we will need to setup a build environment.
apt install build-essential gcc make
Then we will need some libraries.
apt install apache2-dev build-essential gcc make \
libxml2-dev libsqlite3-dev zlib1g-dev libbz2-dev libcurl4-openssl-dev \
libgmp-dev libonig-dev libjpeg-dev libgd-dev libmcrypt-dev
If compiling on x86, there are two problems that will be encountered. The libraries curl and gmp both install to x86-specific directories. We need links from the main include directory.
ln -s /usr/include/x86_64-linux-gnu/curl /usr/local/include/curl
ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/local/include/gmp.h
On ARM the paths look like this.
ln -s /usr/include/arm-linux-gnueabihf/curl /usr/include/curl
ln -s /usr/include/arm-linux-gnueabihf/gmp.h /usr/include/gmp.h
Now we need the source code for PHP 5. They can be found on the download releases page. I am interested in the last PHP 5 release which is 5.6.40.
tar xvfz php-5.6.40.tar.gz
The configuration is one I use, but if you are compiling your own version of PHP you will likely have some idea of what other PHP packages you want included.
Highlighted in yellow are lines to tell the configuration that we want to install PHP 5 in /usr/local/php5, and we want the configuration files located in /etc/php/5.4. Feel free to modify these paths, but take note of them as they are used latter in the setup. In green are lines important to getting FPM.
Once setup, simply make and install.
make -j 16
My system has a 16-thread CPU and the build only takes a minute. Adjust the value according to your CPU thread count as PHP builds just fine in parallel.
Next we need to configure PHP 5.
cp php.ini-production /etc/php/5.6/php.ini
cp sapi/fpm/php-fpm.conf /etc/php/5.6/php-fpm.conf
This will copy the default configuration files to the PHP 5 configuration directory. There are a couple of small changes needed in the FPM configuration.
First, the PID line needs un-commented and changed like this:
;pid = run/php-fpm.pid → pid = /run/php5-fpm.pid
The listening socket needs to change from a IP socket to a Unix socket:
listen = 127.0.0.1:9000 → listen = /run/php5-fpm.sock
Then the owner lines need to be enabled.
;listen.owner = www-data → listen.owner = www-data
;listen.group = www-data → listen.group = www-data
;listen.mode = 0660 → listen.mode = 0660
Now we need to create a service to run FPM for PHP 5 and start it.
cat << EOT >> /lib/systemd/system/php5-fpm.service
Description=The PHP 5 FastCGI Process Manager
ExecStart=/usr/local/php5/sbin/php-fpm --nodaemonize --fpm-config /etc/php/5.6/php-fpm.conf
ExecReload=/bin/kill -USR2 $MAINPID
systemctl enable php5-fpm.service
systemctl start php5-fpm.service
Verify the service is running:
root@php75:~# systemctl status php5-fpm.service
● php5-fpm.service - The PHP 5 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php5-fpm.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2021-11-16 00:14:32 UTC; 2s ago
Main PID: 220157 (php-fpm)
Tasks: 3 (limit: 38336)
├─220157 php-fpm: master process (/etc/php/5.6/php-fpm.conf)
├─220158 php-fpm: pool www
└─220159 php-fpm: pool www
If the service started we can now use it the same was as the distribution PHP-FPM. Let’s create another virtual host for this:
cat <<EOT >> /var/www/html/php5/index.php
<?php phpinfo(); ?>
cat <<EOT >> /etc/apache2/sites-available/php5.conf
systemctl reload apache2
Again, modify /etc/hosts on the host machine to have php5.php7_5 point to the container IP address. Now if you go to http://php5.php7_5 you should see the PHP information page for PHP 5.6 rather than PHP 7. Both http://php5.php7_5 and http://php7.php7_5 should work.
The take away lessons I learned from this:
- Build the other version(s) of PHP with configuration parameters to install them in separate locations. This will allow many versions of PHP to be available.
- Copy over the default PHP-FPM configuration and make changes to reflect how you want it to run.
- Use a Unix socket instead of a TCP/IP socket for FastCGI.
- Each version of PHP you want to add to Apache must be running as a FastCGI service.
- A default PHP handler can be added to the top level of the Apache configuration, and virtual hosts can override this version with their own.
It took me about 2 full days of experimenting to get this setup working, but maybe this information will prove useful to someone else. Also, I’m sure I’ll forget what I did and I might need this in the future.
After getting the container working I tested this setup on a Raspberry Pi and had it working there as well. I have a large micro SD card on order to build a backup server for DrQue.net, and when it arrives I should be able to fully test this setup for DrQue.net itself. With PHP 8 now released, I might add a third PHP handler so I can get my PHP code into this decade. For now, however, I will live with just being able to run PHP 5 and 7 together.