CloudLinux PHP Selector: A PHP Version and Extensions Per Account

How CloudLinux PHP Selector gives each account its own PHP version, extensions and php.ini values, what it needs on DirectAdmin, and the CLI to manage it.

Published
Reading time
5 min

On a shared server every account wants a different PHP. One customer runs a legacy shop that breaks on anything newer than 7.4, the next wants 8.4 for a fresh Laravel project, and a third needs imagick that nobody else does. PHP Selector is CloudLinux's answer: a row of PHP builds installed side by side, and a page in the control panel where each user picks their own version, extensions and php.ini values without touching anyone else's site. This post covers how it fits together, what it needs before it works, and how to drive it from the shell.

alt-php: the versions sit next to each other

CloudLinux ships its own PHP builds as alt-php packages, one per version from 5.6 up to 8.5. They install under /opt/alt/php8X/ (the 8.3 binary is /opt/alt/php83/usr/bin/php) and never replace the panel's own PHP, which the selector calls native. Install the whole set with:

bash
yum groupinstall alt-php
yum install alt-php83-imagick alt-php84-imagick

The group brings every version with a standard set of extensions. Extensions are separate packages named alt-phpNN-<extension>, so when a user cannot see imagick or redis in the panel, the usual reason is that the package is not installed for that version, not that the selector is broken.

Native stays the default until you change it. Users who never open the selector page keep running whatever the panel provides, which is exactly what you want on a server you are converting with live sites on it.

What it needs before it works

Two things, and both catch people out.

CageFS must be enabled for the user. PHP Selector works by placing the chosen interpreter and its php.ini inside the user's cage, so a user without CageFS keeps native PHP whatever they select. If the panel shows the page but nothing changes, run cagefsctl --list-enabled and see whether the user is in the list. Enabling it is covered in CageFS: what it does and how to enable it.

The PHP handler must be one the selector can hook. That means lsphp (mod_lsapi), suPHP or fcgid. The classic selector does not work with PHP-FPM on DirectAdmin, and CustomBuild's default is PHP-FPM, so a DirectAdmin server needs:

bash
cd /usr/local/directadmin/custombuild
./build set cloudlinux yes
./build set php1_mode lsphp
./build php n
./build rewrite_confs
cagefsctl --force-update

mod_lsapi is the right handler for a shared server anyway; the reasons are in mod_lsapi: the fastest PHP handler for Apache. The final cagefsctl --force-update copies the rebuilt binaries into the CageFS skeleton, and you should repeat it whenever you add or update an alt-php package.

The admin side: defaults and locked options

In DirectAdmin open Admin Level → Extra Features → CloudLinux Manager → Selector → PHP. cPanel and Plesk have the same screen inside their LVE Manager plugin. Here you set the default version every account starts on, native or a specific alt-php; enable or disable individual versions so 5.6 is only offered when you decide it is; set the default extension list per version; and set php.ini options, marking the ones users may not change. Locking disable_functions and an upper memory_limit is the usual reason to use that last part.

The same defaults from the command line:

bash
cloudlinux-selector get --json --interpreter php
cloudlinux-selector set --interpreter php --default-version 8.3

Keep the default on a version that is still receiving upstream security fixes. The old versions exist for the customers who need them, not as the starting point for new accounts.

The user side: Select PHP Version

A DirectAdmin user opens Advanced Features → Select PHP Version (in cPanel it is under Software). The version dropdown is at the top; choose one and click Set as current. Below it, the Extensions tab is a grid of checkboxes for that version, and the Options tab holds the php.ini values a user is allowed to change: memory_limit, upload_max_filesize, post_max_size, max_execution_time, display_errors, date.timezone and so on.

Changes apply within seconds and only to that account. The settings live in a per-user php.ini inside the cage, so a site that breaks after a change is fixed by switching back on the same page. There is nothing to restart.

One detail worth telling customers: inside a caged shell or cron job, the php command is the selected version. A cron line such as php /home/bob/domains/example.com/public_html/cron.php therefore matches the website, which is not true of a plain DirectAdmin server where you have to spell out /usr/local/php83/bin/php. The full path /opt/alt/php83/usr/bin/php still works if a script must pin a version regardless of what the user selects.

Doing it from the shell

Support work goes faster with the CLI, and it is scriptable:

bash
cloudlinux-selector set --interpreter php --current-version 8.3 --user bob
cloudlinux-selector enable-extensions --interpreter php --version 8.3 --user bob --extensions imagick,redis
cloudlinux-selector set --interpreter php --version 8.3 --user bob --options 'memory_limit=512M,upload_max_filesize=64M'
cloudlinux-selector get --json --interpreter php --user bob

The last command prints the user's selected version, enabled extensions and options as JSON. Loop it over your users when you need to know who is still on 7.4 before an end-of-life date.

Native or alt: where to put people

Leave native as the panel's current build and keep it as the default for accounts that never ask. Enable alt-php 8.2 to 8.5 so anyone can move forward on their own. Keep 7.4, 8.0 and 8.1 enabled only because CloudLinux's HardenedPHP backports security fixes to them, which makes them a safer bridge than the upstream builds; how far that protection goes is in HardenedPHP: running old PHP versions without the security debt. Disable anything older unless a named customer depends on it.

If a user reports a missing extension after switching, it is nearly always the extension checkbox for the new version, since the list is per version. If the site ignores the selection entirely, check CageFS and the handler in that order. On a VPSPioneer managed VPS running CloudLinux we set the handler, CageFS and the default version up as part of the service, so the selector page simply works when your customers open it.

#cloudlinux#php#php-selector#directadmin

Keep reading

More from CloudLinux

All guides

CloudLinux

How to Install CloudLinux on a DirectAdmin Server

Convert a DirectAdmin server on AlmaLinux 9 to CloudLinux with cldeploy, switch CustomBuild to lsphp, set up CageFS and PHP Selector, and verify with cldiag.

4 min read →

CloudLinux

What CloudLinux Does for Shared Hosting Stability (and Why It Matters)

How CloudLinux keeps one busy account from slowing a shared server: LVE limits, CageFS, PHP Selector, what a 508 error means and how to stay within limits.

6 min read →

CloudLinux

CageFS: What It Does and How to Enable It on CloudLinux

Why every CloudLinux server should run CageFS, what it hides from users, how to initialise and enable it, and how to fix the usual breakages.

4 min read →