Developers often require the ability to run multiple PHP versions in their development environment. This article provides a step-by-step guide on setting up a LAMP stack (Linux, Apache, MariaDB, PHP) with multiple PHP instances on Ubuntu/Kubuntu 23.10 Linux in the year 2024.

This guide covers the installation of LAMP for development or testing purposes. It is not a guide for setting up a LAMP for a production server, it does not deal at all with aspects such as security on a production server, etc.

In order to have multiple versions of PHP running simultaneously on Apache, you need the fcgid apache module, which helps us run PHP scripts using FASTCGI. At the same time, it can then run these scripts using different PHP versions. And we do this by creating a virtual host for each PHP version.

Install PHP 7.4, 8.2, 8.3

Prerequisites

Before beginning the installation process, ensure that your Ubuntu/Kubuntu system is up to date by running the following command:

sudo apt update

Installing Apache


Start by installing Apache version 2:

sudo apt install -y apache2 apache2-utils
Note: It is possible that our system is already running the latest Apache 2, then nothing is installed and everything is fine.

Check if the Apache service is running:

systemctl status apache2

Verify in your browser:

 

Since we'll be doing development, we'll set the rights and ownership for the server root folder right away (user: jan, group: jan):

sudo chown jan:jan /var/www/ -R

Installing MariaDB


Proceed with the installation of MariaDB:

sudo apt install mariadb-server mariadb-client

As with Apache, we can check if the service is running:

systemctl status mariadb

Now we will perform the initial setup of MariaDB, mainly setting the password for the root user. Run the following command and follow the questions:

sudo mysql_secure_installation

For example:

Switch to unix_socket authentication? ... Y
Change the root password? ... Y
Remove anonymous users? ... Y
Disallow root login remotely? ... Y
Remove test database and access to it? ... Y
Reload privilege tables now? ... Y

Installing Multiple PHP Versions

And now we will install multiple instances of PHP. There will be two oddities:

1) to avoid conflicting PHP libraries, we will uninstall all the PHP libraries already installed.

Be careful to do this step only if you are not using old PHP instances
sudo apt-get remove 'php*'
sudo apt-get purge 'php*'

2) Add a new specific repository to our system that will allow us to install the latest PHP versions

sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update && sudo apt upgrade

After that, let's move on, install the apache module fcgid:

sudo apt install libapache2-mod-fcgid

And proceed to install PHP versions (along with PHP we list various modules here, go through the list of modules and you can delete the modules that are listed here and you don't need them)

PHP 7.4

sudo apt install php7.4 libapache2-mod-php7.4 php7.4-common php7.4-mysql php7.4-cli php7.4-opcache php7.4-readline php7.4-phpdbg php7.4-fpm php7.4-cgi libphp7.4-embed php7.4-xml php7.4-xmlrpc php7.4-curl php7.4-gd php7.4-dev php7.4-imap php7.4-mbstring php7.4-soap php7.4-zip php7.4-intl php7.4-ssh2 -y
Caution - for version 7.4 or 8.3 it is possible that the repository information is not ready for our system (repository ppa:ondrej/php), so we need to change this information

Open and edit following file: /etc/apt/sources.list.d/ondrej-ubuntu-php-mantic.sources

Change string "mantic" to "jammy"

then update the repository information:

sudo apt update

And then we can install version 7.4 or 8.3.

So we run the PHP 7.4 installation again (don't run it if everything was fine before).

And let's see an example of another problem, it may be that some library is in conflict, e.g:

The following packages have unmet dependencies: php7.4-intl : Depends on: libicu70 (>= 70.1-1~).

In such cases, you have to search the Internet for a solution and resolve the conflicts separately, in our case for the library: php7.4-intl we resolve them by reinstalling libicu70:

wget http://ftp.osuosl.org/pub/ubuntu/pool/main/i/icu/libicu70_70.1-2_amd64.deb
sudo dpkg -i libicu70_70.1-2_amd64.deb

And now, for the third time, install PHP 7.4 (don't do it if you managed to install it successfully before).

PHP 8.2

sudo apt install php8.2 libapache2-mod-php8.2 php8.2-common php8.2-mysql php8.2-cli php8.2-opcache php8.2-readline php8.2-phpdbg php8.2-fpm php8.2-cgi libphp8.2-embed php8.2-xml php8.2-xmlrpc php8.2-curl php8.2-gd php8.2-dev php8.2-imap php8.2-mbstring php8.2-soap php8.2-zip php8.2-intl php8.2-ssh2 -y

PHP 8.3

sudo apt install php8.3 libapache2-mod-php8.3 php8.3-common php8.3-mysql php8.3-cli php8.3-opcache php8.3-readline php8.3-phpdbg php8.3-fpm php8.3-cgi libphp8.3-embed php8.3-xml php8.3-xmlrpc php8.3-curl php8.3-gd php8.3-dev php8.3-imap php8.3-mbstring php8.3-soap php8.3-zip php8.3-intl php8.3-ssh2 -y

We can check if all PHP instances are installed:

ls -la /var/run/php/

The fpm service takes care of running all PHP instances. Before we start it or check its status, let's modify the user so that PHP scripts have the ownership and rights of the same user who creates folders on the server and uploads files to them.

Open and edit the following files, replace all occurrences of "www-data" in these files with the user (and group) name, in our case it is "jan":

/etc/php/7.4/fpm/pool.d/www.conf
/etc/php/8.2/fpm/pool.d/www.conf
/etc/php/8.3/fpm/pool.d/www.conf

Now start the fpm services (restart them if they are running):

sudo systemctl restart php7.4-fpm
sudo systemctl restart php8.2-fpm
sudo systemctl restart php8.3-fpm

By running the following command we can check the status of the service (e.g. for PHP 8.3)

sudo systemctl status php8.3-fpm

Let's enable some necessary apache modules:

sudo a2enmod actions fcgid alias proxy_fcgi rewrite

Restart Apache:

sudo systemctl restart apache2

Create Virtual Hosts

Now we will create virtual hosts, for all PHP versions we will create our own file in the folder:

/etc/apache2/sites-available/

we create the following files:

site74.test.conf
site82.test.conf
site83.test.conf

Each of them will contain the following instructions (PHP 8.3 example):

<VirtualHost *:80>
    ServerAdmin Site
    ServerName  site83.test
    ServerAlias www.site83.test
    DocumentRoot /var/www/site83.test
    <Directory /var/www/site83.test/>
            Options FollowSymLinks MultiViews
            AllowOverride All
            Order allow,deny
            allow from all
            Require all granted
    </Directory>
    <FilesMatch \.php>
        SetHandler "proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://localhost/"
    </FilesMatch>
</VirtualHost>

Once we have these files created and saved, then we enable all the pages:

sudo a2ensite site74.test.conf
sudo a2ensite site82.test.conf
sudo a2ensite site83.test.conf

And reload apache:

sudo systemctl reload apache2

To make sure that our system knows the names of our test pages, we will modify

/etc/hosts

and add this line:

127.0.0.1 localhost site74.test site82.test site83.test

In /var/www/ folder

create the following subfolders for our test domains:

mkdir /var/www/site74.test
mkdir /var/www/site82.test
mkdir /var/www/site83.test

We create them without sudo, using a user that also runs PHP scripts, in our case jan and insert a PHP file index.php into each of them, which will contain:

<?php
echo phpinfo();
?>

Every time we make a change to the settings (e.g. php.ini, etc.) we restart both apache and fpm

sudo systemctl restart php8.3-fpm
sudo systemctl restart apache2

Then enter the following URLs into the address bar one by one:

site74.test

site82.test

site83.test

Conclusion

By following these steps, you can successfully set up a LAMP stack with multiple PHP instances on Ubuntu/Kubuntu 23.10 Linux in 2024. This configuration allows developers to work on different PHP versions simultaneously for their development needs.