I’ve been using Apache as my default local development web server since I started writing PHP code back in 2006. Back then, Nginx was barely 2 years old, and every web server was running Apache, so it just made sense. Over the years I’ve come to prefer Nginx on my web servers, but I still prefer Apache locally, because I find it easier to use and configure.
I’ve generally always been able to use the most recent stable version of PHP with Apache for all my web projects. However, the speed at which PHP versions are currently being released means that in some cases (mostly WordPress-related) I can’t always run the latest version locally.
So in this post, I’m going to detail how to install the latest stable version of the current PHP release (currently 8.1) alongside the latest stable version of the previous PHP release (7.4) using Apache on Ubuntu.
Initial Set Up and PHP 8.1
The most stable way to install multiple PHP versions on a Debian or Ubuntu system is to use the PPA repositories for Debian or Ubuntu that Ondřej Surý maintains. Ondřej has been maintaining these official PPAs for Debian since PHP 5, so I highly recommend supporting his work.
Installing the repository as a PPA on your Debian-based system is done using the add-apt-repository
command:
sudo add-apt-repository ppa:ondrej/php -y
While not required, it’s also a good idea to install the repository for the Apache2 version Ondřej provides.
sudo add-apt-repository ppa:ondrej/apache2 -y
Finally, update your system to make sure you’re getting the software from the newly added repositories.
sudo apt update && apt upgrade
Then, if you install PHP and all the required modules and PHP packages, PHP 8.1 will be installed as your default PHP version.
sudo apt install php libapache2-mod-php php-common php-mysql \
php-xml php-xmlrpc php-curl php-gd \
php-imagick php-cli php-dev php-imap \
php-mbstring php-soap php-zip -y
If you need to add any specific PHP config settings to your install, I recommend doing this in a custom user.ini file, which you can create like here:
/etc/php/8.1/apache2/conf.d/user.ini
Switch the entire server to using PHP 7.4
Now that your system is running the latest PHP version, you can install other versions. It’s usually a good idea to install the most stable previous major version back, in this case, PHP 7.4. Note that this command is the same as the previous one, just with the specific version number.
sudo apt install php7.4 libapache2-mod-php7.4 php7.4-common php7.4-mysql \
php7.4-xml php7.4-xmlrpc php7.4-curl php7.4-gd \
php7.4-imagick php7.4-cli php7.4-dev php7.4-imap \
php7.4-mbstring php7.4-soap php7.4-zip -y
This will allow you to have both versions installed, but only PHP 8.1 is active. To switch your active PHP version over to PHP 7.4, you run these update-alternatives
commands.
sudo update-alternatives --set php /usr/bin/php7.4
sudo update-alternatives --set phar /usr/bin/phar7.4
sudo update-alternatives --set phar.phar /usr/bin/phar.phar7.4
sudo update-alternatives --set phpize /usr/bin/phpize7.4
sudo update-alternatives --set php-config /usr/bin/php-config7.4
If you want your PHP 8.1 custom settings available to PHP 7.4, you can copy the user.ini file.
sudo cp /etc/php/8.1/apache2/conf.d/user.ini /etc/php/7.4/apache2/conf.d/user.ini
To switch back to PHP 8.1, simply run the update-alternatives
commands, but change the version number to 8.1.
Run PHP 8.1 and PHP 7.4 on the same server
Sometimes, you might want to be able to have PHP 8.1 as the default, but enable PHP 7.4 for a specific site. This is possible using the FastCGI Process Manager for PHP, aka php-fpm
. Effectively what you do is install php-fpm
for 7.4, and then you can configure your site’s Apache virtual host file to set the PHP version.
First, install the required packages for PHP 7.4.
sudo apt-get install libapache2-mod-fcgid php7.4 php7.4-fpm php7.4-mysql php7.4-common php7.4-xml php7.4-xmlrpc php7.4-curl php7.4-gd php7.4-imagick php7.4-mbstring php7.4-soap php7.4-zip -y
Then, start php7.4-fpm
.
sudo systemctl start php7.4-fpm
Check the status by running this command.
sudo systemctl status php7.4-fpm
You should see something like this:
jonathan@jonathan-Desktop:~$ sudo systemctl status php7.4-fpm
● php7.4-fpm.service - The PHP 7.4 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php7.4-fpm.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2022-08-15 19:28:43 SAST; 1min 4s ago
Docs: man:php-fpm7.4(8)
Process: 65626 ExecStartPost=/usr/lib/php/php-fpm-socket-helper install /run/php/php-fpm.sock /etc/php/7.4/fpm/pool.d/www.conf 74 (code=exited, status=0/SUCCESS)
Main PID: 65623 (php-fpm7.4)
Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
Tasks: 3 (limit: 19041)
Memory: 10.4M
CPU: 43ms
CGroup: /system.slice/php7.4-fpm.service
├─65623 "php-fpm: master process (/etc/php/7.4/fpm/php-fpm.conf)" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
├─65624 "php-fpm: pool www" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ">
└─65625 "php-fpm: pool www" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ">
Aug 15 19:28:43 jonathan-Desktop systemd[1]: Starting The PHP 7.4 FastCGI Process Manager...
Aug 15 19:28:43 jonathan-Desktop systemd[1]: Started The PHP 7.4 FastCGI Process Manager.
Next, enable the FastCGI proxy.
sudo a2enmod actions alias proxy_fcgi fcgid
If everything worked, you should see something like this:
jonathan@jonathan-Desktop:~$ sudo a2enmod actions alias proxy_fcgi fcgid
Enabling module actions.
Module alias already enabled
Considering dependency proxy for proxy_fcgi:
Enabling module proxy.
Enabling module proxy_fcgi.
Enabling module fcgid.
To activate the new configuration, you need to run:
systemctl restart apache2
Restart Apache to make sure everything is set up correctly.
sudo systemctl restart apache2
The last step is to go into your site’s Apache virtual host file, and add a PHP 7.4 block to the VirtualHost block:
sudo nano /etc/apache2/sites-enabled/sitename-ssl.conf
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"
</FilesMatch>
This tells Apache to use php7.4-fpm for this site. Once you’ve saved that file, restart Apache.
sudo systemctl restart apache2
If you’re setting this up for a local development environment, you might have set the Apache user to your home user, in order for Apache to read the files for any local sites. If this is the case, you might need to update the www.conf file for the php7.4-fpm pool, and set the users to the same system user.
sudo nano /etc/php/7.4/fpm/pool.d/www.conf
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
user = jonathan
group = jonathan
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
user = jonathan
group = jonathan
Finally, you’ll need to set a custom user.ini for the php7.4-fpm process (or alternatively copy one of your existing user.ini files).
sudo nano /etc/php/7.4/fpm/conf.d/user.ini
And restart php7.4-fpm for these changes to take effect.
sudo service php7.4-fpm restart
Install Additional PHP versions
With php-fpm, you can install additional PHP versions, and simply enable them per site. Let’s install PHP 8.0 via fpm.
Install the specific version packages
sudo apt-get install libapache2-mod-fcgid php8.0 php8.0-fpm php8.0-mysql php8.0-common php8.0-xml php8.0-xmlrpc php8.0-curl php8.0-gd php8.0-imagick php8.0-mbstring php8.0-soap php8.0-zip -y
Start the specific php-fpm service
sudo systemctl start php8.0-fpm
Set the PHP pool user
sudo nano /etc/php/8.0/fpm/pool.d/www.conf
Finally set the PHP file handler in the site’s Apache virtual host file, making sure to use the right php-fpm version.
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.0-fpm.sock|fcgi://localhost"
</FilesMatch>
Remove Custom PPAs
If you ever need to rest your system, you can remove the custom PPAs
sudo add-apt-repository --remove ppa:ondrej/apache2 -y
sudo add-apt-repository --remove ppa:ondrej/php -y
Don’t forget to update your system to make sure the repository lists are updated.
sudo apt update && apt upgrade
Leave a Reply