Feature

Multi-PHP Version Management: Run PHP 8.1 to 8.5 with Per-User Isolation

March 16, 2026

Back to Blog

Multi-PHP Version Management: Run PHP 8.1 to 8.5 Side by Side

Panelica lets you run five PHP versions simultaneously — each with independent extensions, configuration, and per-user PHP-FPM pools. Different sites can use different PHP versions on the same server with complete isolation.

5
PHP Versions (8.1–8.5)
50+
Manageable Extensions
Per-User
FPM Pool Isolation
1-Click
Version Switching

1. Five PHP Versions, One Server

Panelica ships with PHP 8.1, 8.2, 8.3, 8.4, and 8.5 — all compiled from source and installed under /opt/panelica/services/php/. Each version has its own binary, configuration directory, extensions, and PHP-FPM socket. They run completely independently.

/opt/panelica/services/php/ ├── 8.1/ │ ├── bin/php, bin/php-fpm │ ├── etc/php.ini, php-fpm.conf │ ├── etc/conf.d/ ← Extension configs │ └── lib/php/extensions/ ← Compiled .so files ├── 8.2/ ... ├── 8.3/ ... ├── 8.4/ ... └── 8.5/ ... Each version = independent binary + config + extensions

Switching a domain's PHP version is a one-click operation in the panel. Behind the scenes, Panelica updates the Nginx upstream to point to the correct PHP-FPM socket and reloads the configuration. Zero downtime.

2. Per-User PHP-FPM Pool Isolation

This is where Panelica fundamentally differs from cPanel and Plesk. Instead of running all sites through a shared PHP-FPM master process, Panelica creates a separate PHP-FPM pool for each user, for each PHP version.

Process Isolation

Each pool runs as the site owner's Linux user — not www-data, not nobody. A PHP vulnerability in one site cannot access another user's files because the process literally runs as a different Unix user.

Resource Limits

Independent pm.max_children, pm.start_servers, and pm.min/max_spare_servers per pool. One runaway WordPress plugin can't consume all PHP workers on the server.

Security Sandbox

open_basedir restricts PHP file access to the user's home directory and /tmp. Combined with disable_functions for dangerous system calls. Each pool is a security sandbox.

Independent Restart

Restart PHP-FPM for a single user without affecting anyone else on the server. Debugging a PHP issue? Restart that one pool. Everyone else keeps running.

Systemd Service Pattern: panelica-php-fpm-{version}-user@{username}.service — each pool is a systemd instantiated service, managed independently, with its own PID file and socket.

The pool configuration is generated at /opt/panelica/etc/php-fpm-users/{user}/{version}/pool.d/pool.conf and includes security hardening: open_basedir, disable_functions, upload_tmp_dir restrictions, and file permission enforcement.

3. Extension Management

Panelica manages 50+ PHP extensions per version through a GUI toggle interface. Extensions are managed via conf.d/ directory symlinks — enabling an extension creates a symlink, disabling removes it. PHP-FPM reloads automatically.

Core Extensions

json, spl, ctype, date, filter, hash, pcre, reflection, standard — always available, compiled into PHP.

Web & Database

curl, gd, imagick, openssl, zip, xml, mysqli, pdo_mysql, pdo_pgsql, sqlite3 — toggle on/off per version.

Caching & Performance

OPcache, APCu, Redis, Memcached — essential for WordPress and Laravel performance. Enable with one click.

PECL Extensions

Install PECL extensions asynchronously — the panel compiles them in the background and notifies you when ready. No SSH, no pecl install commands.

Async PECL Installation: When you install a PECL extension, Panelica creates a background job that compiles the extension, installs it, and creates the ini configuration. You can monitor progress through the panel — no terminal needed.

4. php.ini Configuration Per Domain

Global php.ini settings apply server-wide, but Panelica also supports per-domain overrides for critical settings:

SettingGlobal DefaultPer-Domain Override
memory_limit256MUp to plan limit
max_execution_time300sUp to plan limit
upload_max_filesize128MPer-domain configurable
post_max_size128MPer-domain configurable
max_input_vars3000Per-domain configurable
max_file_uploads50Per-domain configurable

Per-domain limits are stored in a domain_php_limits table with a unique constraint on (domain_id, php_version) — each domain can have different settings for each PHP version it uses.

Settings are validated with php -l syntax checking before applying, and PHP-FPM reloads only after validation passes. No more broken sites from a typo in php.ini.

5. Bulk Version Change

Upgrading PHP across multiple sites? Panelica's bulk version change endpoint lets you switch all sites (or a filtered subset) to a new PHP version in a single API call. The operation returns a detailed report showing which domains succeeded, which failed, and why.

API Example: POST /api/v1/php/bulk-change-version with {"source_version": "8.2", "target_version": "8.4"} — migrates all PHP 8.2 sites to 8.4. Response includes per-domain status with old/new versions.

6. System PHP & CLI

Panelica uses wrapper scripts (not symlinks) for system PHP commands at /usr/local/bin/. This is a deliberate architectural choice:

Why Wrapper Scripts, Not Symlinks? When PHP is symlinked, it reads Ubuntu's /etc/php/X.Y/cli/conf.d/ directory — which contains references to system extensions that aren't installed in Panelica's isolated PHP. This causes "Unable to load dynamic library" errors. Wrapper scripts set PHP_INI_SCAN_DIR to Panelica's conf.d directory, ensuring PHP loads the correct extensions.

Version-specific CLI commands (php81, php82, php83, php84, php85) let you run PHP scripts with any installed version directly from the command line.

Composer is also managed as a wrapper script using Panelica's own composer.phar binary — not Ubuntu's outdated packaged version (2.2.x) which throws deprecation notices with PHP 8.4+.

7. PHP Statistics Dashboard

The PHP management page shows real-time statistics: total installed versions, active PHP-FPM services, domains per version, most-used version, and default system version. Per-version detail pages show the list of domains using that version with their individual resource configurations.

8. cPanel vs Plesk vs Panelica PHP Comparison

FeaturecPanel (MultiPHP)PleskPanelica
PHP versions available5.6–8.3 (EA4)7.1–8.38.1–8.5 (latest)
PHP-FPM isolationShared pool per versionShared poolPer-user per-version pool
Process runs asnobody/www-datawww-dataSite owner's Linux user
open_basedir per userGlobal settingPer-domainPer-pool enforced
Extension managementEasyApache GUIGUI (limited)GUI + async PECL install
Per-domain php.ini.htaccess onlyLimitedFull per-domain overrides
Bulk version changeNoNoYes — API + GUI
Independent pool restartNo — restarts allNoYes — per user, per version
Version statisticsNoBasicFull dashboard with per-version domain list
Cgroups v2 integrationNoNoYes — PHP-FPM inside user cgroup slice

9. Security Considerations

Panelica's PHP isolation goes beyond just open_basedir:

  • Cgroups v2 integration: PHP-FPM pools run inside the user's cgroup slice — CPU, memory, and I/O limits are enforced at the kernel level, not just PHP's internal limits.
  • disable_functions: Dangerous functions like exec, system, passthru, shell_exec, proc_open are disabled per pool. Individual domains can have customized function blacklists.
  • Unix socket permissions: Each PHP-FPM socket is owned by www-data with mode 0660 — only Nginx and the socket owner can connect. No cross-user socket access.
  • Systemd hardening: PHP-FPM services use Type=simple with proper PID file management. No root escalation paths.
5-Layer Isolation Stack: PHP-FPM is Layer 4 of Panelica's 5-layer isolation architecture (Cgroups v2 → Linux Namespaces → SSH Chroot → PHP-FPM Sandboxing → Unix Permissions). Each layer independently prevents cross-user access — even if one layer fails, four others protect your sites.

Run Multiple PHP Versions with Real Isolation

Per-user pools. Per-domain configs. Cgroups v2 enforcement. No shared-nothing compromises.

Start Free Trial

Panelica — Where PHP isolation means actual Linux process isolation, not just an open_basedir directive.

Share: