Websites & apps

Install multiple PHP versions on Ubuntu and Debian

Add Ondřej Surý's PHP repository, install PHP 8.2, 8.3 and 8.4 side by side with PHP-FPM, and switch the command-line PHP version with update-alternatives.

IntermediateLinux server5 min read

Ubuntu and Debian ship one PHP version per release. If one site needs PHP 8.2 while a newer app wants 8.4, you can install both from Ondřej Surý's packages, which the PHP community has maintained for many years. Each version gets its own PHP-FPM service and socket, so they run side by side without conflict. This guide installs several versions and shows how to pick the one the command line uses.

Before you start

  • A Linux VPS running Ubuntu 22.04 or 24.04, or Debian 12, with a sudo user.
  • Shell access over SSH: Connect to your Linux VPS with SSH.
  • A note of the PHP version your sites use today:
Bash
  php -v

Note: The extra repository supports a set of PHP versions for each OS release, and that set changes over time. If a version below is not available for your release, check the repository's own documentation for what it currently provides.

Add the repository

Ubuntu 22.04 and 24.04

On Ubuntu the packages come from a Launchpad PPA:

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

Press Enter when asked to confirm.

Debian 12

On Debian the packages come from packages.sury.org. First install the signing key package, then add the source:

Bash
sudo apt update
sudo apt install -y lsb-release ca-certificates curl
curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb
echo "deb [signed-by=/usr/share/keyrings/debsuryorg-archive-keyring.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list
sudo apt update

Check that apt can now see the versioned packages:

Bash
apt-cache policy php8.4-fpm

A Candidate: line with a version number means the package is available.

Install PHP versions side by side

Every package name includes the version, so you install each one explicitly. Install FPM and the common extensions for each version you need:

Bash
sudo apt install -y php8.2-fpm php8.2-cli php8.2-mysql php8.2-curl php8.2-gd php8.2-mbstring php8.2-xml php8.2-zip php8.2-intl
sudo apt install -y php8.3-fpm php8.3-cli php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip php8.3-intl
sudo apt install -y php8.4-fpm php8.4-cli php8.4-mysql php8.4-curl php8.4-gd php8.4-mbstring php8.4-xml php8.4-zip php8.4-intl

Warning: Do not install the plain php or libapache2-mod-php metapackages unless you use Apache with mod_php. On an Nginx or Apache event + PHP-FPM server, mod_php pulls in the prefork MPM and can change how Apache runs.

Extensions are per version. If an app needs redis or imagick, install them for the version that app uses, for example php8.3-redis.

Each version runs its own FPM service

Every version has a separate service, configuration folder and socket:

  • Service: php8.2-fpm, php8.3-fpm, php8.4-fpm
  • Config: /etc/php/8.3/fpm/php.ini and /etc/php/8.3/fpm/pool.d/
  • Socket: /run/php/php8.3-fpm.sock

Make sure they are running and start at boot:

Bash
sudo systemctl enable --now php8.2-fpm php8.3-fpm php8.4-fpm
systemctl status php8.4-fpm --no-pager
ls /run/php/

You should see one .sock file per version. Your web server chooses the version by pointing each site at the matching socket. For Nginx, see Use a different PHP version per website in Nginx.

If you do not need a version to run all the time, stop and disable its FPM service to save memory. Its CLI binary still works.

Switch the command-line PHP version

The php command is a symlink managed by update-alternatives. It usually points at the newest installed version. See all choices:

Bash
sudo update-alternatives --display php

Set the default to PHP 8.3:

Bash
sudo update-alternatives --set php /usr/bin/php8.3

Or pick from a menu:

Bash
sudo update-alternatives --config php

If you also build extensions with phpize or use php-config, switch those to the same version:

Bash
sudo update-alternatives --set phar /usr/bin/phar8.3
sudo update-alternatives --set phpize /usr/bin/phpize8.3
sudo update-alternatives --set php-config /usr/bin/php-config8.3

You can always call a specific version directly, without changing the default. This is the safest choice in cron jobs and deploy scripts:

Bash
php8.2 /var/www/legacy/artisan schedule:run
php8.4 /usr/local/bin/composer install

Tip: The CLI version and the web version are independent. A site served through php8.2-fpm keeps running PHP 8.2 whatever php -v says.

Check it works

Bash
php -v
php8.2 -v
php8.4 -m | grep -i mysql

The first line should show the default you chose, the second PHP 8.2, and the third should list mysqli, mysqlnd and pdo_mysql.

To check the web side, point a test site at a socket and load a page that prints PHP_VERSION. Remove the test file afterwards, because version details help attackers.

Troubleshooting

  • add-apt-repository: command not found: install software-properties-common first.
  • Unable to locate package php8.4-fpm: the repository was not added or apt update was skipped. On Debian, check /etc/apt/sources.list.d/php.list uses your release name, such as bookworm.
  • A site shows "missing extension" after switching versions: the extension is installed for the old version only. Install the matching php8.x-<name> package and restart that FPM service.
  • Composer or Artisan uses the wrong version: a script calls plain php. Use the versioned binary or set the CLI default with update-alternatives.
  • Nginx returns 502 after a change: the socket path in the site config does not match an existing file in /run/php/, or that FPM service is stopped.

Next steps

  • Move a site to a newer version step by step: Upgrade PHP to a newer version on your VPS.
  • Install the extensions your apps need: Install PHP extensions.
  • Running many sites on one server? A larger Linux VPS gives each FPM pool room to grow.
Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.