Multiple PHP versions on one server: a PHP-FPM guide
Run multiple PHP versions on one server with PHP-FPM on Ubuntu or Debian: install side by side, set a version per site, handle CLI, cron and pitfalls.

Key takeaways
- With PHP-FPM, each PHP version runs as its own service with its own socket, so several versions coexist on one server without conflict.
- The web server picks a site's version by pointing it at that version's socket.
- Extensions and php.ini are installed and configured separately for each version.
- PHP 7.4, 8.0 and 8.1 are end of life; keep them only temporarily for legacy apps.
Running multiple PHP versions on one server is routine with PHP-FPM: each version (say 8.2, 8.3 and 8.4) is installed side by side, runs as its own service and listens on its own socket. Your web server (nginx or Apache) sends each site's requests to the right socket, so site A runs PHP 8.2 while site B runs PHP 8.4. The versions never step on each other, because each has its own configuration directory, extensions and binary.
This guide covers when you need more than one PHP version, how to install them by hand on Ubuntu 24.04 and Debian 12, how to assign a version to each site, how to handle the PHP CLI and cron, and how to do the same in ZoPanel with a few clicks.
When do you need multiple PHP versions?
Most hosting servers end up needing more than one, for very practical reasons:
- Legacy applications. A site written for PHP 7.4, an old WordPress theme or a custom module that breaks on PHP 8.x.
- Gradual upgrades. You want to move one site to the new version, test it, then move the next, instead of upgrading the whole server overnight.
- Newer requirements. A framework or plugin may require a newer PHP than your distribution ships.
- Shared hosting. Different customers need different things, and accounts migrated from cPanel or DirectAdmin often arrive on a mix of versions.
Which PHP versions are still supported?
According to PHP's supported versions page and its end-of-life list, at the time of writing (October 2026):
| Version | Released | Active support until | Security fixes until |
|---|---|---|---|
| 7.4 | 2019 | Ended | End of life 28 Nov 2022 |
| 8.0 | 2020 | Ended | End of life 26 Nov 2023 |
| 8.1 | 2021 | Ended | End of life 31 Dec 2025 |
| 8.2 | 8 Dec 2022 | 31 Dec 2024 | 31 Dec 2026 |
| 8.3 | 23 Nov 2023 | 31 Dec 2025 | 31 Dec 2027 |
| 8.4 | 21 Nov 2024 | 31 Dec 2026 | 31 Dec 2028 |
| 8.5 | 20 Nov 2025 | 31 Dec 2027 | 31 Dec 2029 |
The PHP in each distribution's own repository: Ubuntu 22.04 ships 8.1, Ubuntu 24.04 ships 8.3, Debian 12 ships 8.2 and Debian 13 ships 8.4. Distributions patch their own PHP packages for the life of that release, but for any other version you need an extra repository.
WordPress currently recommends PHP 8.3 or newer. PHP 8.2 stops getting security fixes at the end of 2026, so if your sites are still on 8.2, now is the time to plan the upgrade.
Installing multiple PHP versions manually
Step 1: Add a PHP repository
The two most widely used repositories are maintained by Ondřej Surý, who maintains PHP packaging in Debian: the ondrej/php PPA for Ubuntu and packages.sury.org for Debian. They are third-party repositories: you are trusting their maintainer with root on your server, so make that decision consciously.
On Ubuntu 24.04:
sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
On Debian 12, follow the repository's own steps one by one (install the signing keyring 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 update
Step 2: Install each version with PHP-FPM
Each version has its own package prefix. Install FPM and the extensions your sites need:
sudo apt install -y php8.2-fpm php8.2-mysql php8.2-curl php8.2-gd \
php8.2-mbstring php8.2-xml php8.2-zip php8.2-intl php8.2-opcache
sudo apt install -y php8.4-fpm php8.4-mysql php8.4-curl php8.4-gd \
php8.4-mbstring php8.4-xml php8.4-zip php8.4-intl php8.4-opcache
Each version now has its own service (php8.2-fpm, php8.4-fpm), its own config directory (/etc/php/8.2/, /etc/php/8.4/) and its own socket (/run/php/php8.2-fpm.sock, /run/php/php8.4-fpm.sock). Check them:
systemctl status php8.2-fpm php8.4-fpm --no-pager
ls -l /run/php/
Do not install libapache2-mod-php on a multi-version server: mod_php loads a single PHP version into Apache. Use PHP-FPM for every version.
Step 3: Assign a version to each site (nginx)
In each site's server block, point fastcgi_pass at the socket of the version you want:
# legacy.example.com on PHP 8.2
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
# new.example.com on PHP 8.4
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}
Test, then reload:
sudo nginx -t && sudo systemctl reload nginx
With Apache and mod_proxy_fcgi, the idea is the same inside the VirtualHost:
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>
Step 4: Give each site its own pool
The default www pool runs every site as the same user (www-data). If one site is hacked, the attacker can read every other site's files. On a server with more than one owner, create a pool per site running as its own user, for example /etc/php/8.2/fpm/pool.d/legacy.conf:
[legacy]
user = legacy
group = legacy
listen = /run/php/php8.2-legacy.sock
listen.owner = www-data
listen.group = www-data
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 30s
Check the syntax before reloading, then point nginx at the new socket:
sudo php-fpm8.2 -t && sudo systemctl reload php8.2-fpm
pm = ondemand means the pool keeps no worker processes when there are no requests, which matters once you have several versions and many sites.
PHP CLI, Composer and cron
This is where most multi-version setups go wrong. The php command points to one default version that has nothing to do with the version a site uses through FPM. The result: the cron job of a PHP 8.2 site runs under PHP 8.4 and fails.
- See the default:
php -v. - Change the server-wide default:
sudo update-alternatives --set php /usr/bin/php8.3. - Better: call the version explicitly in cron and scripts, so the default does not matter:
# crontab for a PHP 8.2 site
*/5 * * * * /usr/bin/php8.2 /var/www/legacy.example.com/artisan schedule:run
# Composer under the right version
php8.2 /usr/local/bin/composer install --no-dev
Common mistakes with multiple PHP versions
- Extension installed for one version only.
php8.3-redisdoes nothing for a site on 8.2. When you switch versions, install the extensions again. - Editing the wrong php.ini. Each version has its own
/etc/php/X.Y/fpm/php.iniand/etc/php/X.Y/cli/php.ini. Raisingupload_max_filesizefor 8.4 does not affect a site on 8.2. - RAM eaten by always-on pools. Every PHP-FPM pool keeps a master process in memory even with no visitors. Multiply by versions and sites and it adds up.
- Forgetting updates. Extra versions need regular
apt upgradelike every other package. - Keeping end-of-life versions too long. PHP 7.4 and 8.0 no longer get security fixes from the PHP project. If you must keep one, isolate that site, restrict its permissions and set a firm upgrade date.
Before moving a site to a newer version, test on a staging copy with errors logged and walk through the main flows. Static analysis such as PHPCompatibility for PHP_CodeSniffer catches removed functions early.
Multiple PHP versions with ZoPanel
ZoPanel does all of the above for you, on the Free plan too:
- Install versions. Administrators add versions under Runtimes. ZoPanel supports PHP 7.4, 8.0, 8.1, 8.2, 8.3 and 8.4. You can also choose them at install time:
curl -fsSL https://get.zopanel.net | sudo bash -s -- --php 8.3,8.2, where the first becomes the default. - Pick a version per site. When you create a website, choose the PHP version from the installed ones. Change it later on the PHP & config tab; the account's PHP-FPM pool is updated for you, with no nginx editing.
- A pool per account. Every hosting account has its own PHP-FPM pool per version, running as that account's user, inside the CPU and RAM limits of its package. One customer's code never shares a PHP process with another's.
- Idle pools sleep. A pool with no requests for the idle time (30 minutes by default) is stopped, then started again within a few hundred milliseconds on the next request; compiled code is kept on disk so that first page stays fast. Several versions across many sites therefore hold no RAM when nobody visits. See PHP performance.
- Per-site PHP settings.
upload_max_filesize,max_input_vars,date.timezoneand other options are set under Tools → PHP settings for this website, written to that site's.user.ini.
When you migrate from cPanel, each site's PHP version is read from the backup's ea-php/alt-php setting and mapped to the closest installed version. Details are in websites and PHP and the migration docs.
To be upfront: ZoPanel's supported list currently stops at 8.4. If your application requires PHP 8.5, check the latest release notes before you decide.
Conclusion
Running multiple PHP versions on one server is easy once three ideas click: each version is its own PHP-FPM service with its own socket, the web server chooses a version by pointing at a socket, and extensions, php.ini and the CLI are all separate per version. The rest is discipline: name the version explicitly in cron, isolate each site, and move off end-of-life versions on schedule.
If you would rather not manage pools and nginx config site by site, try ZoPanel: the Free plan covers 3 hosting accounts, 10 websites and 10 databases with no time limit, multiple PHP versions included. See pricing, or read how many WordPress sites fit on a 4 GB VPS to see how sleeping PHP pools save RAM.
Frequently asked questions
Can PHP 7.4 and PHP 8.4 run at the same time on one server?
Yes. With PHP-FPM, each version is a separate service with its own socket, and each site points at the socket of the version it needs. Bear in mind that PHP 7.4 has had no security fixes since 2022, so keep it only temporarily for code you cannot upgrade yet.
How do I check which PHP version a site uses?
Look at the web server config: the socket in fastcgi_pass (nginx) or SetHandler (Apache) tells you. In ZoPanel the version is shown on the site's PHP & config tab. Do not rely on php -v, which only reports the default CLI version.
Does switching PHP versions cause downtime?
Changing the socket and reloading nginx takes seconds and does not drop connections. The real risk is code that is incompatible with the new version, so test on staging first and make sure every extension is installed for the new version.
Do multiple PHP versions use more RAM?
Yes, if every pool runs all the time. Using pm = ondemand, or letting the panel stop idle pools, cuts that cost sharply, because only sites with visitors keep PHP processes running.
Install ZoPanel free
One command on a fresh Ubuntu or Debian server. Up and running in minutes.
Install in 5 minutesKeep reading

How to install a LEMP stack on Ubuntu 24.04, step by step
Install a LEMP stack on Ubuntu 24.04 (and Debian 12): firewall, nginx, MariaDB, PHP-FPM, server blocks, Let's Encrypt SSL and per-site isolation done right.

Best VPS specs for WordPress: how much CPU, RAM and disk you need
The best VPS specs for WordPress for 1, 10 or 100 sites: how to size CPU, RAM and disk from your traffic, with real measurements and the mistakes to avoid.

Deploy Laravel to a VPS: queues, scheduler and zero-downtime releases
How to deploy Laravel to a VPS on Ubuntu 24.04: PHP-FPM, nginx, .env, queue workers, the scheduler and zero-downtime releases, by hand or with ZoPanel.