The symlink makes __FILE__/__DIR__/realpath/getcwd report /home/<user>/public_html
(WordPress/frameworks), but $_SERVER['DOCUMENT_ROOT']/['SCRIPT_FILENAME'] are raw
env vars OLS sets to its /mnt/users view — apps that build/compare paths from
them would see /mnt/users. Added a tiny auto_prepend (cac-lsphp-normalize.php,
wired via a scan-dir ini) that realpath-canonicalises those two back to /home.
Customer sites have no auto_prepend by default, so no conflict.
Verified clean-room (committed image, fresh boot): DOCUMENT_ROOT and
SCRIPT_FILENAME both report /home/<user>/public_html through the shared OLS.
Now byte-for-byte 1:1 with cac-fpm/cac-litespeed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Customer concern: sites with /home/<user>/public_html baked into config or the
DB must keep working — a changed in-container docroot path would break WordPress
ABSPATH, hardcoded includes, cached absolute paths, etc., making the upgrade a
non-drop-in.
Fix: the sidecar now mounts the docroot at /home/$user (IDENTICAL to
cac-fpm/cac-litespeed) and the entrypoint symlinks /mnt/users/<user>/<domain> ->
/home/$user. OLS still serves from its bulk /mnt/users mount and sends lsphp
that path (no remap available), but the symlink resolves it to the real
/home/$user files AND PHP canonicalises it — so __FILE__/__DIR__/realpath/ABSPATH
all report /home/<user>/public_html.
Verified end-to-end through the shared OLS: a request reports
__FILE__=/home/homeuser/public_html/probe.php, ABSPATH=/home/homeuser/public_html/,
and stored /home paths resolve. True 1:1 drop-in.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code-review integration fixes:
- entrypoint-lsphp.sh: the shared-ols tier mounts the docroot at
/mnt/users/<user>/<domain> (NOT /home/$user). Discover the mount via glob
(one site per sidecar; wildcard-safe), create public_html + logs/php-fpm under
it (so OLS docRoot exists), point lsphp error_log there, and chown just those
dirs. Verified: sidecar creates public_html under the mount, runs as the
per-site user, OLS serves PHP (SAPI=litespeed) end-to-end.
- shared-ols vhconf.tpl: per-vhost logs -> /usr/local/lsws/logs/<vhname>.* (the
shared-ols container has no /home/<user>).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New slim per-site PHP backend that runs 'lsphp -b 0.0.0.0:9000' (detached
LSAPI) and nothing else — the LiteSpeed analogue of cac-fpm, sitting behind
a shared OpenLiteSpeed container. Built on the same litespeedtech prebuilt
base as cac-litespeed so the lsphp runtime/extensions are identical.
- Dockerfile.lsphp: base + lsphpNN-ldap parity, reuses shared lsphp-overrides.ini,
exposes only :9000, no webserver started (guaranteed by entrypoint, not by
stripping OLS binaries).
- entrypoint-lsphp.sh: same uid/user contract + /home/$user/logs layout +
ini drop-in mechanism as entrypoint-litespeed.sh; sizes PHP_LSAPI_CHILDREN
from container memory (detect-memory-lsphp.sh) with panel override precedence;
execs lsphp -b as the per-site user via setpriv (PID 1).
- detect-memory-lsphp.sh: LSAPI_CHILDREN sizing, no OLS daemon reserve.
- healthcheck-lsphp.sh: TCP :9000 + lsphp-alive (LSAPI isn't FastCGI).
- CI: Build-LSPHP-Images job, php81-85 matrix, OLS 1.8.4, cac-lsphp:phpNN.
Verified locally: builds php83+php85; sidecar runs lsphp as the per-site
user (uid 61045) as PID 1, healthcheck green, and a real shared OLS in front
serves PHP over LSAPI (HTTP 200, SAPI=litespeed) with identical docroot path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>