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>
This commit is contained in:
@@ -117,6 +117,47 @@ jobs:
|
|||||||
repo.anhonesthost.net/cloud-hosting-platform/cac-litespeed:php${{ matrix.phpver }}
|
repo.anhonesthost.net/cloud-hosting-platform/cac-litespeed:php${{ matrix.phpver }}
|
||||||
${{ matrix.phpver == '85' && 'repo.anhonesthost.net/cloud-hosting-platform/cac-litespeed:latest' || '' }}
|
${{ matrix.phpver == '85' && 'repo.anhonesthost.net/cloud-hosting-platform/cac-litespeed:latest' || '' }}
|
||||||
|
|
||||||
|
Build-LSPHP-Images:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
# Same PHP matrix as cac-litespeed (81–85): cac-lsphp is the detached
|
||||||
|
# backend for the shared-ols tier and shares the litespeed prebuilt
|
||||||
|
# base, which only ships lsphp for 8.1+. Keep this matrix in lockstep
|
||||||
|
# with Build-LiteSpeed-Images.
|
||||||
|
phpver: [81, 82, 83, 84, 85]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to Gitea
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: repo.anhonesthost.net
|
||||||
|
username: ${{ secrets.CI_USER }}
|
||||||
|
password: ${{ secrets.CI_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and Push lsphp Image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
file: ./Dockerfile.lsphp
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: true
|
||||||
|
build-args: |
|
||||||
|
PHPVER=${{ matrix.phpver }}
|
||||||
|
OLS_VERSION=1.8.4
|
||||||
|
# OLS_VERSION pinned to 1.8.4 to match Build-LiteSpeed-Images — same
|
||||||
|
# prebuilt base, same lsphp binaries. Bump both together.
|
||||||
|
tags: |
|
||||||
|
repo.anhonesthost.net/cloud-hosting-platform/cac-lsphp:php${{ matrix.phpver }}
|
||||||
|
${{ matrix.phpver == '85' && 'repo.anhonesthost.net/cloud-hosting-platform/cac-lsphp:latest' || '' }}
|
||||||
|
|
||||||
Build-Shared-httpd:
|
Build-Shared-httpd:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
62
Dockerfile.lsphp
Normal file
62
Dockerfile.lsphp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
## cac-lsphp — per-site DETACHED lsphp (LSAPI) backend for the shared-ols tier.
|
||||||
|
##
|
||||||
|
## The LiteSpeed analogue of cac-fpm: a slim, single-tenant PHP backend that
|
||||||
|
## runs `lsphp -b 0.0.0.0:9000` (detached LSAPI mode) and NOTHING ELSE — no
|
||||||
|
## webserver. The shared OpenLiteSpeed container (shared-ols) sits in front and
|
||||||
|
## reaches this over the docker network via an extProcessor of type lsapi,
|
||||||
|
## address <this-container>:9000 — structurally identical to how shared-httpd
|
||||||
|
## reaches a cac-fpm container's php-fpm on :9000.
|
||||||
|
##
|
||||||
|
## Built on the SAME LiteSpeed prebuilt base as cac-litespeed so the lsphp
|
||||||
|
## binary + extension set are byte-for-byte the runtime customers already get
|
||||||
|
## on the litespeed tier (memcached, redis, imagick, mbstring, mysqlnd, intl,
|
||||||
|
## gd, soap, bcmath, gmp, sodium, opcache, ... + lsphpNN-ldap added below).
|
||||||
|
## We do NOT strip the bundled OpenLiteSpeed binaries: the "no webserver"
|
||||||
|
## guarantee comes from the ENTRYPOINT (it only ever execs lsphp), and deleting
|
||||||
|
## OLS files from the upstream image risks breaking lsphp's shared libs for no
|
||||||
|
## real benefit. Only :9000 is EXPOSEd, and OLS is never started.
|
||||||
|
##
|
||||||
|
## See the design spec + PoC: whp docs/superpowers/plans/2026-06-09-ols-lsphp-tier.md
|
||||||
|
## and the LSAPI path-parity finding (feedback_ols_lsapi_no_script_filename_remap).
|
||||||
|
|
||||||
|
ARG OLS_VERSION=1.8.4
|
||||||
|
ARG PHPVER=83
|
||||||
|
FROM litespeedtech/openlitespeed:${OLS_VERSION}-lsphp${PHPVER}
|
||||||
|
ARG PHPVER=83
|
||||||
|
ENV PHPVER=${PHPVER}
|
||||||
|
|
||||||
|
## Match the cac-litespeed extension surface exactly: the only ext the prebuilt
|
||||||
|
## base lacks is lsphpNN-ldap. setpriv (util-linux) is already on the Ubuntu
|
||||||
|
## base; we add nothing else the sidecar doesn't need. All apt cache cleaned in
|
||||||
|
## the same layer to keep the image small.
|
||||||
|
RUN apt-get update && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
lsphp${PHPVER}-ldap && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
|
||||||
|
|
||||||
|
## Scripts + the SHARED production lsphp ini (reused verbatim from the litespeed
|
||||||
|
## image — same runtime, same tuning). Scripts layer last (they change most).
|
||||||
|
COPY ./scripts/entrypoint-lsphp.sh \
|
||||||
|
./scripts/detect-memory-lsphp.sh \
|
||||||
|
./scripts/healthcheck-lsphp.sh \
|
||||||
|
/scripts/
|
||||||
|
RUN chmod +x /scripts/entrypoint-lsphp.sh /scripts/detect-memory-lsphp.sh /scripts/healthcheck-lsphp.sh
|
||||||
|
|
||||||
|
## Apply production lsphp ini overrides into lsphp's scan dir (path varies by
|
||||||
|
## PHP minor version; ask lsphp directly — same idiom as Dockerfile.litespeed).
|
||||||
|
COPY ./configs/litespeed/lsphp-overrides.ini /etc/lsws-templates/lsphp-overrides.ini
|
||||||
|
RUN bash -c 'set -e; \
|
||||||
|
SCAN_DIR=$(/usr/local/lsws/lsphp${PHPVER}/bin/lsphp -i 2>/dev/null | awk -F"=> " "/^Scan this dir/ {print \$2; exit}"); \
|
||||||
|
mkdir -p "$SCAN_DIR"; \
|
||||||
|
cp /etc/lsws-templates/lsphp-overrides.ini "$SCAN_DIR/99-prod-overrides.ini"; \
|
||||||
|
echo "wrote overrides to $SCAN_DIR"'
|
||||||
|
|
||||||
|
EXPOSE 9000
|
||||||
|
|
||||||
|
## TCP-connect + lsphp-alive check (LSAPI isn't FastCGI, so no cgi-fcgi ping).
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
|
||||||
|
CMD /scripts/healthcheck-lsphp.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/scripts/entrypoint-lsphp.sh"]
|
||||||
75
scripts/detect-memory-lsphp.sh
Normal file
75
scripts/detect-memory-lsphp.sh
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
## detect-memory-lsphp.sh — sibling of detect-memory-litespeed.sh for the
|
||||||
|
## cac-lsphp DETACHED sidecar (lsphp -b, no local webserver).
|
||||||
|
##
|
||||||
|
## Computes PHP_LSAPI_CHILDREN from the container memory cap. Identical worker
|
||||||
|
## arithmetic to detect-memory-litespeed.sh, with ONE difference: there is no
|
||||||
|
## OpenLiteSpeed daemon in this container (OLS runs in the shared-ols tier), so
|
||||||
|
## the ~40 MB OLS_RESERVE is dropped — every MB above the OS reserve goes to
|
||||||
|
## lsphp workers. Sourced by entrypoint-lsphp.sh.
|
||||||
|
|
||||||
|
## ---- container memory detection (mirrors detect-memory-litespeed.sh) ----
|
||||||
|
CONTAINER_MEMORY_BYTES=""
|
||||||
|
|
||||||
|
if [ -f /sys/fs/cgroup/memory.max ]; then
|
||||||
|
val=$(cat /sys/fs/cgroup/memory.max 2>/dev/null)
|
||||||
|
if [ "$val" != "max" ] && [ -n "$val" ]; then
|
||||||
|
CONTAINER_MEMORY_BYTES=$val
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$CONTAINER_MEMORY_BYTES" ] && [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then
|
||||||
|
val=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes 2>/dev/null)
|
||||||
|
if [ -n "$val" ] && [ "$val" -lt 8589934592000 ] 2>/dev/null; then
|
||||||
|
CONTAINER_MEMORY_BYTES=$val
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$CONTAINER_MEMORY_BYTES" ] && [ -f /proc/meminfo ]; then
|
||||||
|
mem_kb=$(awk '/^MemTotal:/ {print $2}' /proc/meminfo)
|
||||||
|
if [ -n "$mem_kb" ]; then
|
||||||
|
CONTAINER_MEMORY_BYTES=$((mem_kb * 1024))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$CONTAINER_MEMORY_BYTES" ]; then
|
||||||
|
CONTAINER_MEMORY_BYTES=$((512 * 1024 * 1024))
|
||||||
|
fi
|
||||||
|
|
||||||
|
CONTAINER_MEMORY_MB=$((CONTAINER_MEMORY_BYTES / 1024 / 1024))
|
||||||
|
|
||||||
|
## ---- budget split (all non-OS memory is the lsphp workers' to use) ----
|
||||||
|
OS_RESERVE_MB=50
|
||||||
|
DEV_OVERHEAD_MB=0
|
||||||
|
if [ "${environment:-PROD}" = "DEV" ]; then
|
||||||
|
DEV_OVERHEAD_MB=125
|
||||||
|
fi
|
||||||
|
|
||||||
|
AVAILABLE_MB=$((CONTAINER_MEMORY_MB - OS_RESERVE_MB - DEV_OVERHEAD_MB))
|
||||||
|
if [ "$AVAILABLE_MB" -lt 60 ]; then
|
||||||
|
AVAILABLE_MB=60
|
||||||
|
fi
|
||||||
|
|
||||||
|
## ---- LSAPI children ----
|
||||||
|
## Same ~130 MB/worker estimate as cac-litespeed (see detect-memory-litespeed.sh
|
||||||
|
## for the vantagehealth/brain-jar OOM history that set this). Detached lsphp
|
||||||
|
## has the SAME per-worker shmem-RSS profile as in-container lsphp — splitting
|
||||||
|
## the webserver out doesn't change lsphp's memory model, only removes the OLS
|
||||||
|
## daemon footprint from the budget.
|
||||||
|
LSPHP_WORKER_ESTIMATE_MB=${LSPHP_WORKER_ESTIMATE_MB:-130}
|
||||||
|
|
||||||
|
calc_lsapi_children=$((AVAILABLE_MB / LSPHP_WORKER_ESTIMATE_MB))
|
||||||
|
if [ "$calc_lsapi_children" -lt 2 ]; then
|
||||||
|
calc_lsapi_children=2
|
||||||
|
fi
|
||||||
|
if [ "$calc_lsapi_children" -gt 50 ]; then
|
||||||
|
calc_lsapi_children=50
|
||||||
|
fi
|
||||||
|
|
||||||
|
## Per-site override precedence — the WHP panel (site-pool-env.php) passes the
|
||||||
|
## customer's override as LSAPI_CHILDREN and/or FPM_MAX_CHILDREN; either wins
|
||||||
|
## over the calculated default. entrypoint-lsphp.sh exports the result as
|
||||||
|
## PHP_LSAPI_CHILDREN (the name lsphp -b reads).
|
||||||
|
LSAPI_CHILDREN=${LSAPI_CHILDREN:-${FPM_MAX_CHILDREN:-$calc_lsapi_children}}
|
||||||
|
|
||||||
|
export CONTAINER_MEMORY_MB LSAPI_CHILDREN
|
||||||
106
scripts/entrypoint-lsphp.sh
Normal file
106
scripts/entrypoint-lsphp.sh
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
## entrypoint-lsphp.sh — PID 1 for cac-lsphp:phpNN.
|
||||||
|
##
|
||||||
|
## The per-site PHP backend for the SHARED OpenLiteSpeed tier. Runs lsphp in
|
||||||
|
## DETACHED LSAPI mode (`lsphp -b <addr:port>`) and nothing else — no
|
||||||
|
## webserver. The shared-ols container connects to this over the docker
|
||||||
|
## 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.
|
||||||
|
##
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
: "${PHPVER:=83}"
|
||||||
|
: "${environment:=PROD}"
|
||||||
|
export CONTAINER_ROLE="lsphp_only"
|
||||||
|
export PHPVER environment
|
||||||
|
|
||||||
|
## ---- env validation (same contract as entrypoint-fpm / entrypoint-litespeed) ----
|
||||||
|
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
|
||||||
|
|
||||||
|
LSPHP_BIN="/usr/local/lsws/lsphp${PHPVER}/bin/lsphp"
|
||||||
|
if [ ! -x "$LSPHP_BIN" ]; then
|
||||||
|
echo "FATAL: lsphp binary not found at $LSPHP_BIN (PHPVER=$PHPVER)." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
## ---- user + directories (mirror entrypoint-litespeed.sh paths) ----
|
||||||
|
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"
|
||||||
|
|
||||||
|
## ---- detached-lsphp pool sizing ----
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source /scripts/detect-memory-lsphp.sh
|
||||||
|
|
||||||
|
## LSAPI tuning (spec §5.1). PHP_LSAPI_CHILDREN MUST equal the shared-ols vhost
|
||||||
|
## maxConns — the WHP panel writes both from the single fpm_max_children value,
|
||||||
|
## so they can't drift. LSAPI_MAX_IDLE is THE RAM win: idle children exit, so an
|
||||||
|
## idle site's footprint collapses toward baseline (ondemand-like).
|
||||||
|
export PHP_LSAPI_CHILDREN="${PHP_LSAPI_CHILDREN:-$LSAPI_CHILDREN}"
|
||||||
|
export PHP_LSAPI_MAX_REQUESTS="${PHP_LSAPI_MAX_REQUESTS:-500}"
|
||||||
|
export LSAPI_MAX_IDLE="${LSAPI_MAX_IDLE:-30}"
|
||||||
|
export LSAPI_EXTRA_CHILDREN="${LSAPI_EXTRA_CHILDREN:-5}"
|
||||||
|
export LSAPI_AVOID_FORK="${LSAPI_AVOID_FORK:-0}"
|
||||||
|
LSPHP_BIND="${LSPHP_BIND:-0.0.0.0:9000}"
|
||||||
|
|
||||||
|
echo "Container memory: ${CONTAINER_MEMORY_MB}MB | PHP_LSAPI_CHILDREN=${PHP_LSAPI_CHILDREN} | LSAPI_MAX_IDLE=${LSAPI_MAX_IDLE} | PHPVER=${PHPVER} | bind=${LSPHP_BIND}"
|
||||||
|
|
||||||
|
## ---- per-site ini drop-ins (identical mechanism to entrypoint-litespeed.sh) ----
|
||||||
|
## error_log → the same customer-visible path cac:phpNN / cac-litespeed use, so
|
||||||
|
## "where's my PHP error log?" is answered identically across all site types.
|
||||||
|
SCAN_DIR=$("$LSPHP_BIN" -i 2>/dev/null | awk -F'=> ' '/^Scan this dir/ {print $2; exit}')
|
||||||
|
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 = /home/${user}/logs/php-fpm/error.log
|
||||||
|
log_errors = On
|
||||||
|
EOF
|
||||||
|
## Per-site opcache override (panel: Advanced Tuning → OpCache size); falls
|
||||||
|
## back to the baked lsphp-overrides.ini defaults when unset.
|
||||||
|
if [ -n "${OPCACHE_MEMORY_MB:-}" ] || [ -n "${OPCACHE_MAX_FILES:-}" ]; then
|
||||||
|
{
|
||||||
|
echo "; rendered at container start by entrypoint-lsphp.sh"
|
||||||
|
echo "; per-site override from WHP whp.sites.opcache_*_override"
|
||||||
|
[ -n "${OPCACHE_MEMORY_MB:-}" ] && echo "opcache.memory_consumption = ${OPCACHE_MEMORY_MB}"
|
||||||
|
[ -n "${OPCACHE_MAX_FILES:-}" ] && echo "opcache.max_accelerated_files = ${OPCACHE_MAX_FILES}"
|
||||||
|
} > "$SCAN_DIR/99-user-opcache.ini"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
## ---- ownership ----
|
||||||
|
touch "/home/$user/logs/php-fpm/error.log"
|
||||||
|
chown -R "$user:$user" "/home/$user"
|
||||||
|
chmod 755 "/home/$user"
|
||||||
|
|
||||||
|
## ---- exec lsphp -b as the customer user (PID 1) ----
|
||||||
|
## Bind port is unprivileged (9000), so no root port-bind step is needed — start
|
||||||
|
## directly as $user. Prefer setpriv (util-linux, on the Ubuntu base); fall back
|
||||||
|
## to runuser. exec so lsphp becomes PID 1 and receives Docker's signals
|
||||||
|
## directly (clean stop/restart, matches the php-fpm container's lifecycle).
|
||||||
|
echo "entrypoint-lsphp: exec $LSPHP_BIN -b $LSPHP_BIND as $user (uid=$uid)"
|
||||||
|
if command -v setpriv >/dev/null 2>&1; then
|
||||||
|
exec setpriv --reuid "$uid" --regid "$uid" --init-groups "$LSPHP_BIN" -b "$LSPHP_BIND"
|
||||||
|
elif command -v runuser >/dev/null 2>&1; then
|
||||||
|
exec runuser -u "$user" -- "$LSPHP_BIN" -b "$LSPHP_BIND"
|
||||||
|
else
|
||||||
|
exec sudo -u "$user" -E "$LSPHP_BIN" -b "$LSPHP_BIND"
|
||||||
|
fi
|
||||||
17
scripts/healthcheck-lsphp.sh
Normal file
17
scripts/healthcheck-lsphp.sh
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
## healthcheck-lsphp.sh — liveness for the detached-lsphp sidecar.
|
||||||
|
##
|
||||||
|
## LSAPI is not FastCGI, so the cac-fpm `cgi-fcgi ... | grep pong` ping doesn't
|
||||||
|
## apply here. Minimum viable check (spec §5.1 fallback): the LSAPI listener is
|
||||||
|
## accepting TCP connections on :9000 AND at least one lsphp process is alive.
|
||||||
|
## A bound-but-wedged listener with no lsphp would fail the pgrep; a crashed
|
||||||
|
## listener fails the connect.
|
||||||
|
|
||||||
|
PORT="${LSPHP_HEALTH_PORT:-9000}"
|
||||||
|
|
||||||
|
# bash /dev/tcp connect test (bash is present on the litespeedtech base).
|
||||||
|
exec 3<>"/dev/tcp/127.0.0.1/${PORT}" 2>/dev/null || exit 1
|
||||||
|
exec 3>&- 3<&-
|
||||||
|
|
||||||
|
pgrep -x lsphp >/dev/null 2>&1 || exit 1
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user