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.