Addresses the local code-review on the OLS-tier images:
- [HIGH] ols-htaccess-watcher.sh: the debounce drain read ALL inotify events
unfiltered, so on a busy multi-tenant server it never timed out and the
restart was STARVED (rewrite changes silently never applied). Now coalesces
with a hard DEBOUNCE-bounded window. Verified under continuous noise.
- [HIGH] render-shared-ols-config.sh: built httpd_config.conf in-place across
several appends, so a concurrent OLS restart (watcher) or parallel render
could read a half-written config and 503 the whole tier. Now flock-serialized,
built in a temp file and atomically moved into place; refuses to publish empty.
- [MED] render + entrypoint: replaced recursive chown of the whole conf tree
(O(N-sites) on every single-site change / boot) with a targeted chown of just
the file written.
- [MED] render: parse site.meta with sed instead of sourcing it (do not execute
panel-written data as shell).
- [cleanup] removed the unused configs/shared-ols/vhconf.tpl (the panel copy is
the single source; the image never read it).
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>
One OLS container fronting many tenants' detached cac-lsphp sidecars — the
OLS analogue of shared-httpd. Runs NO PHP locally; every site's PHP goes to
its own sidecar over LSAPI (extProcessor type lsapi, address <sidecar>:9000).
Key design fact (established by PoC): OLS has NO top-level 'include' directive,
so render-shared-ols-config.sh assembles httpd_config.conf from the panel's
per-site files (vhconf.conf + site.meta) at boot and on every change — the
'include' OLS lacks. Per-site detail uses the OLS-native configFile +
vhost-scoped extprocessor model. LSCache is module-level (a configFile-loaded
vhost rejects a bare cache{} block); the WP LiteSpeed plugin controls
cacheability via X-LiteSpeed-Cache-Control headers.
- Dockerfile.shared-ols: litespeed base + inotify-tools/envsubst/openssl,
admin bound to loopback, :80/:443 self-signed, healthz HEALTHCHECK.
- entrypoint-shared-ols.sh: cert + health vhost + render + watcher, then
daemon-mode OLS supervision (reused from cac-litespeed so self-restarts
don't kill PID 1).
- render-shared-ols-config.sh: strip stock (incl local lsphp) + append base +
per-site stanzas + listeners with all maps + catch-all health vhost.
- ols-htaccess-watcher.sh: inotify debounce+floor -> lswsctrl restart (spec 5.3).
- configs/shared-ols/{httpd_config_base,vhconf}.tpl.
- CI: Build-Shared-OLS job.
Verified locally end-to-end: zero-site boot healthy on :443; add site via the
panel contract -> Host-routed to the right sidecar (SAPI=litespeed); real
client IP + HTTPS behind X-Forwarded headers; LSCache miss->hit; .htaccess
change triggers graceful restart; unknown Host hits health catch-all (200).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>