abstract business code coder

Running Different PHP Versions with Apache on Ubuntu

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

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
; 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 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

Posted

in

by

Tags:

Comments

9 responses to “Running Different PHP Versions with Apache on Ubuntu”

  1. Mick Avatar

    Jonathan, thank you for this post. It helped me set up PHP 7.4 just for one webapp that got broken after upgrading the system to Ubuntu 22 LTS and PHP to 8.1.

    1. Jonathan Avatar
      Jonathan

      I’m glad it was helpful Mick.

  2. Fabio Avatar
    Fabio

    Hello Jonathan,

    I followed your guide and it worked perfectly.

    Thank you for being so cool and use your time to write this article and share it with us.

    1. Jonathan Avatar

      It is my great pleasure Fabio.

  3. Karl Avatar

    I have both php7.4 and 8.1 all set up and everything looks good. Been using 7.4 the whole time and preparing to move to 8.1 based on site s/w reqts.
    # systemctl | grep php
    php7.4-fpm.service loaded active running The PHP 7.4 FastCGI Process Manager
    php8.1-fpm.service loaded active running The PHP 8.1 FastCGI Process Manager
    phpsessionclean.timer loaded active waiting Clean PHP session files every 30 mins

    I my /etc/apache2/sites-enabled server conf(s), I have the stanza
    <FilesMatch \.php$>
    SetHandler "proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost"
    </FilesMatch>

    And reloaded/restarted apache2. That stanza was there previously, pointing to php7.4

    Nevertheless, phpinfo() continues to show 7.4 as it always has. I tried stopping the php7.4-fpm.service which only breaks our site(s) with 404 error. Is there something that may be overriding our server.conf pointer to php8.1 fastcgi?

    1. Jonathan Avatar

      When you change the line to switch your server config file from 7.4 to 8.1, are you restarting the apache server, as well as the php7.4 and php8.4 fpm services?


      sudo service apache2 restart
      sudo service php7.4-fpm restart
      sudo service php8.1-fpm restart

      That’s about the only thing I can think of that might be causing this.

  4. Karl Avatar
    Karl

    Yes – I restarted everything. I discovered the issue. Since we run all sites with SSL, the server.conf configurations in /etc/apache2/sites-enabled all have parallel configurations server-le-ssl.conf that are not in /etc/apache2/sites-available. All I had to do was update the stanza in server-le-ssl.conf as well. My sites are now running perfectly under php81. It might be worth adding that note for folks running https to your excellent post. You may delete my comments if you feel it might confuse others.

    1. Jonathan Avatar

      Aha, that makes sense.

      What I usually do is keep the non ssl version of the server.conf simple, and redirect to the ssl secured url


      ServerName url.com
      Redirect / https://url.com

      Then I keep all my config settings in the server-ssl.conf version.

    2. Jonathan Avatar

      Also, no need to delete the comment, it adds value to the conversation 🙂

Leave a Reply

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