2026年11月12日
2026年11月12日
Run Multiple PHP Versions on a VPS (Per-Site PHP-FPM)
This article is a localized edition of the Japanese original. Read the Japanese original
When you run several sites on one VPS, you may want new sites on a newer PHP while an older site only works on an older version. With PHP-FPM, each version runs as its own process, and the web server configuration chooses which version each site uses.
This article shows how to install PHP 8.2 and 8.4 on an Ubuntu 24.04 VPS and route each site to a version with Nginx or Apache (as of October 2026; the steps were tested in an Ubuntu 24.04 container).
Things to know first
How the routing works
- PHP-FPM runs as a separate service for each version (
php8.2-fpm,php8.4-fpm), and each listens on its own socket (/run/php/php8.2-fpm.sockand so on). - For each site, the web server is configured with the socket it should pass PHP requests to. That is how site A runs on 8.2 and site B on 8.4.
- The command-line
php(used by WP-CLI and cron) is switched separately from the web server.
Splitting versions by file extension (such as .php81) or switching with phpenv, a development tool, is not suitable for production websites.
Support periods for each PHP version
According to the official PHP site (Supported Versions on php.net), the support periods as of October 2026 are as follows.
| Version | Security fixes until |
|---|---|
| PHP 8.2 | December 31, 2026 |
| PHP 8.3 | December 31, 2027 |
| PHP 8.4 | December 31, 2028 |
| PHP 8.5 | December 31, 2029 |
WordPress recommends PHP 8.3 or later (wordpress.org requirements page, as of October 2026). Treat running an old version alongside as a bridge until the old site moves to a newer version, and migrate before support ends.
Step 1: Install multiple PHP versions
Ubuntu 24.04's standard repositories include only PHP 8.3. Other versions are usually installed from the packages (PPA) distributed by Ondřej Surý. Use it with the understanding that it is an external repository, not an official Ubuntu one.
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
On Debian, use packages.sury.org from the same maintainer. The setup steps are in https://packages.sury.org/php/README.txt. Note that, as of October 2026, the PPA page says the PPA is being merged into packages.sury.org, so check the current guidance when you set it up.
Install PHP-FPM for each version you need, plus the extensions WordPress commonly uses. Extensions must be installed separately for each version.
# PHP 8.4 (for new sites)
sudo apt install php8.4-fpm php8.4-mysql php8.4-curl php8.4-gd php8.4-intl \
php8.4-mbstring php8.4-xml php8.4-zip
# PHP 8.2 (for old sites)
sudo apt install php8.2-fpm php8.2-mysql php8.2-curl php8.2-gd php8.2-intl \
php8.2-mbstring php8.2-xml php8.2-zip
Confirm that both PHP-FPM services are running and their sockets exist.
systemctl status php8.2-fpm php8.4-fpm --no-pager
ls /run/php/
# Shows php8.2-fpm.sock, php8.4-fpm.sock, etc.
Configuration files are also separate per version (/etc/php/8.2/fpm/php.ini, /etc/php/8.4/fpm/php.ini, and so on). To change upload_max_filesize or memory_limit, edit the file for the version the site uses and restart that version's PHP-FPM.
Step 2a: Choose the version per site in Nginx
In Nginx, put the socket of the version you want in fastcgi_pass in each site's server block.
# /etc/nginx/sites-available/old.example.com (site running on PHP 8.2)
server {
listen 80;
server_name old.example.com;
root /var/www/old;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
}
For a site on PHP 8.4, use fastcgi_pass unix:/run/php/php8.4-fpm.sock;. Enable the configuration, check the syntax, then reload.
sudo ln -s /etc/nginx/sites-available/old.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Step 2b: Choose the version per site in Apache
In Apache, enable the modules that pass requests to PHP-FPM instead of mod_php, and specify the socket with SetHandler in each VirtualHost.
sudo a2enmod proxy_fcgi setenvif
# /etc/apache2/sites-available/old.example.com.conf (site running on PHP 8.2)
<VirtualHost *:80>
ServerName old.example.com
DocumentRoot /var/www/old
<FilesMatch "\.php$">
SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
For a site on PHP 8.4, set the socket to /run/php/php8.4-fpm.sock. Enable the configuration, check the syntax, then reload.
sudo a2ensite old.example.com
sudo apache2ctl configtest
sudo systemctl reload apache2
- Running
a2enconf php8.4-fpmsets the server-wide default version. Sites withSetHandlerinside theirVirtualHostuse that setting instead. - If
libapache2-mod-php8.x(mod_php) is installed and enabled, requests may not reach PHP-FPM. Disable it, for example witha2dismod php8.3.
Step 3 (optional): Separate PHP-FPM pools per site
With the default www pool, every site runs as the same user (www-data). To run each site as its own user, add a pool.
; /etc/php/8.2/fpm/pool.d/oldsite.conf
[oldsite]
user = oldsite
group = oldsite
listen = /run/php/php8.2-oldsite.sock
listen.owner = www-data
listen.group = www-data
pm = ondemand
pm.max_children = 5
Create the oldsite user (sudo useradd -r oldsite) and make the site's files readable by that user. Then check the configuration with sudo php-fpm8.2 -t and apply it with sudo systemctl restart php8.2-fpm. Change the socket in the web server configuration to /run/php/php8.2-oldsite.sock.
Step 4: Versions for command-line php and WP-CLI
Which version the command-line php points to is decided by update-alternatives.
# List installed versions
update-alternatives --list php
# Make 8.4 the default php
sudo update-alternatives --set php /usr/bin/php8.4
php -v
# Run a specific version
php8.2 -v
To run WP-CLI (installed at /usr/local/bin/wp) with a specific version, run it through that version's php.
cd /var/www/old
php8.2 /usr/local/bin/wp core version
If cron runs WordPress commands or PHP scripts, write the version explicitly, such as php8.2, so changing the default version does not affect them.
Step 5: Check each site’s version
In the WordPress admin area, open "Site Health" under "Tools" (Tools → Site Health), go to the "Info" tab, and check the PHP version in the "Server" section. Confirm that each site runs on the version you intended.
If something does not work, check the following:
502 Bad Gateway(Nginx) or503 Service Unavailable(Apache): whether the socket path is correct and that version's PHP-FPM is running (ls /run/php/,systemctl status php8.2-fpm)- WordPress reports that the MySQL extension is unavailable, or images cannot be processed: whether you installed that version's extensions (for example
php8.2-mysql,php8.2-gd) - PHP-FPM error log:
/var/log/php8.2-fpm.logand similar
Removing old versions
After moving old sites to a newer version, remove the version you no longer use. First confirm that no site uses that version's socket.
grep -rn "php8.2" /etc/nginx/ /etc/apache2/ 2>/dev/null
sudo apt purge 'php8.2-*'
sudo apt autoremove
Summary
- With several PHP-FPM versions installed, each version runs as its own service with its own socket
- Specify the socket (version) per site with
fastcgi_passin Nginx orSetHandlerinside theVirtualHostin Apache - Extensions and
php.iniare separate per version. After changing settings, restart that version's PHP-FPM - Set the default command-line version with
update-alternatives, and name the version explicitly, such asphp8.2, for WP-CLI and cron - Security fixes for PHP 8.2 end on December 31, 2026. Use an old version alongside only as a bridge until migration
Related articles
- How to switch the PHP version for WordPress
- Installing and configuring PHP-FPM
- Running WordPress with Nginx and PHP-FPM
- How to set up Apache with PHP-FPM
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)