Reader Stacks

Installing Multiple PHP Versions on Ubuntu

Ubuntu's default repositories only ship one PHP version at a time — the Ondřej Surý PPA is what actually enables running several versions side by side, switched per-project or per-CLI-session.

A server running several projects that each depend on a different PHP version — one legacy app still on 7.4, a newer one requiring 8.3 — needs more than one PHP version installed and available at once, something Ubuntu's default package repositories don't support directly.

1. Add the Ondřej Surý PPA

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

This third-party PPA (maintained by a Debian/Ubuntu PHP package maintainer) is the de facto standard source for installing multiple, current PHP versions on Ubuntu — Ubuntu's own default repositories intentionally only carry one PHP version per release, since that's what the OS itself depends on internally.

2. Install the versions needed

sudo apt install php7.4 php7.4-fpm php7.4-mysql php7.4-mbstring php7.4-xml
sudo apt install php8.3 php8.3-fpm php8.3-mysql php8.3-mbstring php8.3-xml

Each version installs into its own separate directory (/etc/php/7.4/, /etc/php/8.3/) with its own php.ini, its own extension set, and — critically — its own FPM pool listening on its own socket. They coexist without conflict because nothing about the installation is shared between versions.

3. Switching the CLI default version

sudo update-alternatives --config php

This presents a menu of installed PHP versions and sets which one php on the command line actually invokes — useful for running Composer or Artisan commands against a specific project, but it has no effect on which version a web server uses for a given site, which is configured separately.

4. Configuring Nginx to use a specific version per site

# /etc/nginx/sites-available/legacy-app
location ~ \.php$ {
    fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    # ...
}
# /etc/nginx/sites-available/new-app
location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    # ...
}

Because each PHP-FPM version runs its own pool with its own socket path, pointing each Nginx site config at the matching socket is what actually determines which PHP version serves that specific site — this is the real mechanism behind "multiple PHP versions on one server," more so than the CLI switch above.

5. Verifying which version is active where

php -v                          # current CLI default
sudo systemctl status php7.4-fpm php8.3-fpm  # confirm both FPM pools are running

A quick <?php phpinfo(); ?> file placed in a site's document root and loaded in a browser confirms which version is actually serving that specific site — the most reliable check when debugging a mismatch between expected and actual PHP version for a given project.

Topics: Deployment & Hosting