Running Different PHP Versions with Apache on Ubuntu

abstract business code coder

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 
# Enable PHP 7.4. Currently required for WordPress
        <FilesMatch \.php$>
            # From the Apache version 2.4.10 and above, use the SetHandler to run PHP as a fastCGI process server
            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.

Install the specific version packages

sudo apt install php8.0 php8.0-common php8.0-mysql \
php8.0-xml php8.0-xmlrpc php8.0-curl php8.0-gd \
php8.0-imagick php8.0-cli php8.0-dev php8.0-imap \
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

Then, when you set up the php-fpm socket in your Apache virtual host file, make sure to use the right version.

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: