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:
php -vNote: 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:
sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt updatePress 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:
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 updateCheck that apt can now see the versioned packages:
apt-cache policy php8.4-fpmA 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:
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-intlWarning: 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.iniand/etc/php/8.3/fpm/pool.d/ - Socket:
/run/php/php8.3-fpm.sock
Make sure they are running and start at boot:
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:
sudo update-alternatives --display phpSet the default to PHP 8.3:
sudo update-alternatives --set php /usr/bin/php8.3Or pick from a menu:
sudo update-alternatives --config phpIf you also build extensions with phpize or use php-config, switch those to the same version:
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.3You can always call a specific version directly, without changing the default. This is the safest choice in cron jobs and deploy scripts:
php8.2 /var/www/legacy/artisan schedule:run
php8.4 /usr/local/bin/composer installTip: 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
php -v
php8.2 -v
php8.4 -m | grep -i mysqlThe 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: installsoftware-properties-commonfirst.Unable to locate package php8.4-fpm: the repository was not added orapt updatewas skipped. On Debian, check/etc/apt/sources.list.d/php.listuses your release name, such asbookworm.- 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 withupdate-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.
