Commit Graph
13 Commits
Author SHA1 Message Date
shadowdaoandClaude Opus 5 8790b027a9 fix(lsphp): stop SIGPIPE+pipefail reporting the parity extension as missing
`entrypoint-lsphp.sh` decided whether cac_path_parity was loaded with

    printf '%s\n' "$LSPHP_INFO" | grep -q '^cac_path_parity support => enabled$'

under `set -euo pipefail`. `grep -q` exits on its first match; printf is still
writing the remaining ~40 KB of `lsphp -i`, takes SIGPIPE, exits 141, and
pipefail prefers 141 over grep's 0. The branch therefore evaluated FALSE
*because the extension was present* — present early enough to stop the reader —
and every affected container fell back to the auto_prepend normaliser that a
customer's own .user.ini silently displaces, i.e. the exact failure the
extension exists to remove. Measured on whp02 against the published
cac-lsphp:php83: 5/5 runs status=141 with pipefail, 0 without.

The race is decided by pipe capacity, which is why it reproduced on whp02 and
not on other daemons: while the payload fits the pipe the writer never blocks
and always finishes first. Forced over the limit it is deterministic — 3x the
same `lsphp -i` (122100 bytes) gives 141 every time in the built image.

Fixed by reading with here-strings, which are not pipelines at all, so there is
no second exit status for pipefail to adopt. Same grep/awk patterns; plumbing
only. Same class fixed everywhere it existed under pipefail:

  * entrypoint-lsphp.sh      parity probe, and the SCAN_DIR awk probe
  * entrypoint-litespeed.sh  SCAN_DIR probe (a bare assignment: 141 there does
                             not degrade, `set -e` kills PID 1), and ols_running
  * entrypoint-shared-ols.sh ols_running
  * render-shared-ols-config.sh  site.meta parsing (`sed | head -1`): measured
                             141 at 6000 duplicate keys, which under `set -e`
                             aborts the whole render
  * fpm-parity-check.sh      the `php-fpm -m` pre-flight, whose whole job is to
                             stop a harness fault being blamed on the extension

Also: the fallback used to announce "cac_path_parity extension not loadable in
this image" for every reason the branch was reached, including its own plumbing
breaking — a false diagnosis that sends operators to rebuild a good image whose
build gate passed. Verdicts now carry the evidence they rest on, and a probe
that produced nothing is reported as a probe failure that establishes nothing
about the image. Fail-open posture is unchanged: no probe failure is fatal.

Adds scripts/tests/lsphp-info-probe.test.sh, which runs the shipped probes
(extracted verbatim, so they cannot drift from what runs in production) under
`set -euo pipefail` against a realistic ~40 KB phpinfo body, and statically
outlaws the shape repo-wide. Against trunk it fails, naming all 9 offending
lines. Wired into CI as a new Shell-Checks job, because no existing gate ever
executed the entrypoint's branch logic — the .phpt suite and the Dockerfile's
own `lsphp -i | grep -q` probe (which has no pipefail) were both green for the
release whose entrypoint declared that same extension missing.

Verified: PHP 8.3 --no-cache build green, 10/10 .phpt, 9/9 FPM harness; the
built image logs `path parity = extension` and reports `Rewriting => active`
with .from/.to populated; ext-removed and probe-broken variants each produce
their own honest message and still start.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 15:23:56 -07:00
shadowdaoandClaude Opus 4.8 19db8f170a feat(shared-ols): shared OpenLiteSpeed tier image (webserver-only, fronts cac-lsphp sidecars)
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>
2026-06-10 01:22:14 -07:00
shadowdaoandClaude Opus 4.8 19092911a3 feat(cac-lsphp): detached lsphp (LSAPI) site image for the shared-ols tier
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>
2026-06-09 18:28:34 -07:00
shadowdaoandClaude Opus 4.7 55c28a0c11 Add cac-litespeed image family (OpenLiteSpeed, native LSAPI)
New paid-tier per-customer image built on litespeedtech/openlitespeed:1.8.4-lsphpNN.
Matrix: 8.1-8.5. Native LSAPI suexec to customer uid, server-level LSCache,
all WP/WooCommerce extensions (memcached, redis, imagick, mbstring, etc.) baked in.

Files:
- Dockerfile.litespeed (FROM prebuilt LiteSpeed base, layers wp-cli/composer/mariadb)
- configs/litespeed/{httpd_config,site-template,lsphp-overrides}.tpl
- scripts/{entrypoint,create-vhost,detect-memory}-litespeed.sh + install-lscache-wp.sh

CI: new Build-LiteSpeed-Images matrix job. OLS_VERSION pinned to 1.8.4 (only
release with prebuilt images for all 5 PHP versions on Docker Hub).

Spec: whp/docs/superpowers/specs/2026-06-01-cac-litespeed-design.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-02 07:32:47 -07:00
shadowdaoandClaude Opus 4.6 c78167871c Add shared httpd + PHP-FPM-only container architecture
Cloud Apache Container / Build-and-Push (74) (push) Successful in 2m22s
Cloud Apache Container / Build-and-Push (80) (push) Successful in 3m14s
Cloud Apache Container / Build-and-Push (82) (push) Has been cancelled
Cloud Apache Container / Build-and-Push (83) (push) Has been cancelled
Cloud Apache Container / Build-and-Push (84) (push) Has been cancelled
Cloud Apache Container / Build-and-Push (85) (push) Has been cancelled
Cloud Apache Container / Build-FPM-Images (74) (push) Has been cancelled
Cloud Apache Container / Build-FPM-Images (80) (push) Has been cancelled
Cloud Apache Container / Build-FPM-Images (81) (push) Has been cancelled
Cloud Apache Container / Build-FPM-Images (82) (push) Has been cancelled
Cloud Apache Container / Build-FPM-Images (83) (push) Has been cancelled
Cloud Apache Container / Build-FPM-Images (84) (push) Has been cancelled
Cloud Apache Container / Build-FPM-Images (85) (push) Has been cancelled
Cloud Apache Container / Build-Shared-httpd (push) Has been cancelled
Cloud Apache Container / Build-and-Push (81) (push) Has been cancelled
Separate Apache and PHP-FPM into distinct container roles to reduce
per-customer memory overhead on shared servers. Adds three new images:
- Dockerfile.fpm: PHP-FPM only (no Apache), listens on TCP port 9000
- Dockerfile.shared-httpd: Apache only (no PHP), with SSL and proxy_fcgi
- Existing Dockerfile unchanged for standalone mode

Key changes:
- detect-memory.sh: CONTAINER_ROLE env var (combined/fpm_only/httpd_only)
  controls the memory budget split
- create-php-config.sh: FPM_LISTEN env var for TCP port vs Unix socket,
  added /fpm-ping and /fpm-status health endpoints
- New entrypoints for each container role
- tune-mpm.sh for hot-adjusting Apache MPM settings
- shared-vhost-template.tpl with proxy_fcgi and SSL on port 443
- CI/CD builds all three image types in parallel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 10:08:00 -07:00
shadowdao a153385d8f Adding support for PHP 8.5
Cloud Apache Container / Build-and-Push (74) (push) Successful in 2m12s
Cloud Apache Container / Build-and-Push (80) (push) Successful in 1m46s
Cloud Apache Container / Build-and-Push (81) (push) Successful in 1m47s
Cloud Apache Container / Build-and-Push (82) (push) Successful in 1m44s
Cloud Apache Container / Build-and-Push (83) (push) Successful in 1m47s
Cloud Apache Container / Build-and-Push (84) (push) Successful in 1m46s
Cloud Apache Container / Build-and-Push (85) (push) Successful in 1m47s
2026-02-08 07:57:04 -08:00
shadowdao 9f8beb45b8 Switching builds to include PHP version to limit memory requirements on deploy.
Cloud Apache Container / Build-and-Push (74) (push) Failing after 56s
Cloud Apache Container / Build-and-Push (80) (push) Failing after 36s
Cloud Apache Container / Build-and-Push (81) (push) Failing after 56s
Cloud Apache Container / Build-and-Push (82) (push) Failing after 55s
Cloud Apache Container / Build-and-Push (83) (push) Failing after 40s
Cloud Apache Container / Build-and-Push (84) (push) Failing after 57s
improve build size and speed for images.
2025-07-16 07:55:03 -07:00
shadowdao b1ec63617a fix push target 2024-10-01 14:19:51 -07:00
shadowdao b38b80e6fc fix push target 2024-10-01 14:09:12 -07:00
shadowdao 49f2266974 fix push target 2024-10-01 14:07:22 -07:00
shadowdao ac5c70d26b fix push target 2024-10-01 14:03:29 -07:00
shadowdao 5108689aa4 fix branch 2024-10-01 14:00:12 -07:00
shadowdao 4ba4b7ae1e First attempt at creating CI with Gitea Actions 2024-10-01 13:57:01 -07:00