fix(cac-lsphp): mount docroot at /home/$user + symlink for true 1:1 compatibility
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>
This commit is contained in:
@@ -4,10 +4,10 @@
|
||||
## (matches the shared-vhost-template.tpl convention). One directive per line —
|
||||
## OLS PlainConf does NOT accept ';' separators.
|
||||
##
|
||||
## CRITICAL (feedback_ols_lsapi_no_script_filename_remap): docRoot here MUST be
|
||||
## the SAME absolute path the cac-lsphp sidecar has mounted, because OLS hands
|
||||
## lsphp exactly docRoot+URI as SCRIPT_FILENAME and lsphp opens it. Both are
|
||||
## /mnt/users/<user>/<domain>/public_html. The panel asserts this parity.
|
||||
## docRoot is /mnt/users/<user>/<domain>/public_html — the shared-ols container's
|
||||
## view (bulk /docker/users->/mnt/users mount). OLS sends lsphp exactly this path
|
||||
## (no remap); the cac-lsphp sidecar symlinks /mnt/users/<user>/<domain> -> its
|
||||
## real /home/<user> mount, so PHP canonicalises it to /home/<user>/public_html.
|
||||
|
||||
docRoot ~~DOCROOT~~
|
||||
enableScript 1
|
||||
|
||||
@@ -7,18 +7,21 @@
|
||||
## network (extProcessor type lsapi, address <this-container>:9000) exactly
|
||||
## like the shared httpd connects to a cac-fpm container's php-fpm on :9000.
|
||||
##
|
||||
## Structurally this is the LiteSpeed analogue of entrypoint-fpm.sh: same
|
||||
## `uid`/`user` contract, same /home/$user/{public_html,logs} layout, same
|
||||
## per-site ini drop-in mechanism as entrypoint-litespeed.sh. The only
|
||||
## difference from cac-litespeed is that OLS lives elsewhere, so this PID 1 is
|
||||
## lsphp itself rather than a webserver supervisor.
|
||||
## Structurally identical to cac-fpm/cac-litespeed: same `uid`/`user` contract,
|
||||
## the customer docroot mounted at /home/$user (so PHP sees /home/$user/public_html
|
||||
## EXACTLY like the standalone tiers — true 1:1 drop-in for WordPress ABSPATH,
|
||||
## config paths, and DB-stored absolute paths). The only difference is OLS lives
|
||||
## in a separate container, so this PID 1 is lsphp itself.
|
||||
##
|
||||
## IMPORTANT (see whp memory feedback_ols_lsapi_no_script_filename_remap):
|
||||
## OLS hands lsphp exactly its vhost docRoot path, so the shared-ols vhost
|
||||
## docRoot and THIS container's docroot mount MUST be the same absolute path.
|
||||
## The panel mounts the site at /mnt/users/<user>/<domain> in BOTH containers;
|
||||
## this entrypoint does not assume any particular path — it just runs lsphp,
|
||||
## which opens whatever absolute SCRIPT_FILENAME the webserver sends.
|
||||
## THE SYMLINK (see feedback_ols_lsapi_no_script_filename_remap): OLS has no
|
||||
## ProxyFCGISetEnvIf-style remap — it hands lsphp exactly its vhost docRoot path.
|
||||
## The shared-ols container serves from its bulk /docker/users->/mnt/users mount,
|
||||
## so its docRoot (and the SCRIPT_FILENAME it sends us) is
|
||||
## /mnt/users/<user>/<domain>/public_html. We create a symlink
|
||||
## /mnt/users/<user>/<domain> -> /home/$user so that path resolves to the real
|
||||
## /home/$user/public_html files. PHP canonicalises the symlink, so
|
||||
## __FILE__/__DIR__/realpath all report /home/$user/public_html (verified
|
||||
## 2026-06-10) — the customer never sees the /mnt/users path.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -32,7 +35,8 @@ if [ -z "${uid:-}" ] || [ -z "${user:-}" ]; then
|
||||
echo "FATAL: 'uid' and 'user' env vars are required (panel sets these from WHP_UID/WHP_USER)." >&2
|
||||
exit 1
|
||||
fi
|
||||
export user
|
||||
: "${domain:=localhost}"
|
||||
export user domain
|
||||
|
||||
LSPHP_BIN="/usr/local/lsws/lsphp${PHPVER}/bin/lsphp"
|
||||
if [ ! -x "$LSPHP_BIN" ]; then
|
||||
@@ -40,30 +44,24 @@ if [ ! -x "$LSPHP_BIN" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## ---- user ----
|
||||
## ---- user + directories (identical to entrypoint-litespeed.sh: docroot at
|
||||
## /home/$user, the customer's bind-mounted domain dir) ----
|
||||
if ! id -u "$user" >/dev/null 2>&1; then
|
||||
useradd -u "$uid" -m -s /bin/bash "$user"
|
||||
fi
|
||||
mkdir -p "/home/$user/public_html" "/home/$user/logs/php-fpm"
|
||||
|
||||
## ---- locate the customer docroot ----
|
||||
## Unlike cac-fpm/cac-litespeed (docroot at /home/$user), the shared-ols tier
|
||||
## mounts each site at /mnt/users/<user>/<domain> — the SAME absolute path the
|
||||
## shared-ols vhost uses as docRoot, because OLS hands lsphp exactly that path as
|
||||
## SCRIPT_FILENAME (feedback_ols_lsapi_no_script_filename_remap). The panel
|
||||
## mounts exactly ONE site dir here, so glob it (wildcard-safe: the on-disk dir
|
||||
## is wildcard.<domain> for wildcard sites, which the glob picks up verbatim).
|
||||
SITE_DIR=""
|
||||
for d in /mnt/users/"$user"/*/; do
|
||||
[ -d "$d" ] || continue
|
||||
SITE_DIR="${d%/}"
|
||||
break
|
||||
done
|
||||
if [ -z "$SITE_DIR" ]; then
|
||||
## No bind mount yet (e.g. hand-run for testing) — fall back to a sane path so
|
||||
## lsphp still starts; OLS will send the real docRoot at request time.
|
||||
SITE_DIR="/mnt/users/$user/site"
|
||||
fi
|
||||
mkdir -p "$SITE_DIR/public_html" "$SITE_DIR/logs/php-fpm"
|
||||
## ---- compatibility symlink for the OLS-sent path ----
|
||||
## OLS sends SCRIPT_FILENAME under /mnt/users/<user>/<safe-domain>/public_html
|
||||
## (the shared-ols container's view). Point that at our real /home/$user mount so
|
||||
## the path resolves. <safe-domain> matches the on-disk convention: wildcard
|
||||
## `*.foo.com` is stored as `wildcard.foo.com`.
|
||||
SAFE_DOMAIN="$domain"
|
||||
case "$domain" in
|
||||
\*.*) SAFE_DOMAIN="wildcard.${domain#\*.}" ;;
|
||||
esac
|
||||
mkdir -p "/mnt/users/$user"
|
||||
ln -sfn "/home/$user" "/mnt/users/$user/$SAFE_DOMAIN"
|
||||
|
||||
## ---- detached-lsphp pool sizing ----
|
||||
# shellcheck source=/dev/null
|
||||
@@ -90,7 +88,7 @@ if [ -n "$SCAN_DIR" ]; then
|
||||
mkdir -p "$SCAN_DIR"
|
||||
cat > "$SCAN_DIR/99-user-error-log.ini" <<EOF
|
||||
; rendered at container start by entrypoint-lsphp.sh
|
||||
error_log = ${SITE_DIR}/logs/php-fpm/error.log
|
||||
error_log = /home/${user}/logs/php-fpm/error.log
|
||||
log_errors = On
|
||||
EOF
|
||||
## Per-site opcache override (panel: Advanced Tuning → OpCache size); falls
|
||||
@@ -106,13 +104,12 @@ EOF
|
||||
fi
|
||||
|
||||
## ---- ownership ----
|
||||
## Own the docroot + logs so lsphp (running as $user) can read code and write
|
||||
## logs. Don't recurse the whole tree blindly — just ensure the dirs we created
|
||||
## and the log file are customer-owned (customer content may be large; a full
|
||||
## recursive chown every boot would be wasteful, and the files are already
|
||||
## customer-owned from the host side).
|
||||
touch "$SITE_DIR/logs/php-fpm/error.log"
|
||||
chown "$uid:$uid" "$SITE_DIR" "$SITE_DIR/public_html" "$SITE_DIR/logs" "$SITE_DIR/logs/php-fpm" "$SITE_DIR/logs/php-fpm/error.log" 2>/dev/null || true
|
||||
## Ensure the dirs we created + the log file are customer-owned so lsphp (running
|
||||
## as $user) can read code and write logs. Customer content is already
|
||||
## customer-owned from the host side, so we don't recurse the whole (potentially
|
||||
## large) tree on every boot.
|
||||
touch "/home/$user/logs/php-fpm/error.log"
|
||||
chown "$uid:$uid" "/home/$user" "/home/$user/public_html" "/home/$user/logs" "/home/$user/logs/php-fpm" "/home/$user/logs/php-fpm/error.log" 2>/dev/null || true
|
||||
|
||||
## ---- exec lsphp -b as the customer user (PID 1) ----
|
||||
## Bind port is unprivileged (9000), so no root port-bind step is needed — start
|
||||
|
||||
Reference in New Issue
Block a user