Files
cloud-apache-container/scripts/create-vhost-litespeed.sh
jknapp 87f154cdc8
All checks were successful
Cloud Apache Container / Build-and-Push (74) (push) Successful in 1m19s
Cloud Apache Container / Build-and-Push (80) (push) Successful in 2m35s
Cloud Apache Container / Build-and-Push (81) (push) Successful in 1m16s
Cloud Apache Container / Build-and-Push (82) (push) Successful in 1m29s
Cloud Apache Container / Build-and-Push (83) (push) Successful in 2m2s
Cloud Apache Container / Build-and-Push (84) (push) Successful in 2m15s
Cloud Apache Container / Build-and-Push (85) (push) Successful in 2m22s
Cloud Apache Container / Build-FPM-Images (74) (push) Successful in 2m30s
Cloud Apache Container / Build-FPM-Images (80) (push) Successful in 1m14s
Cloud Apache Container / Build-FPM-Images (81) (push) Successful in 2m6s
Cloud Apache Container / Build-FPM-Images (82) (push) Successful in 2m20s
Cloud Apache Container / Build-FPM-Images (83) (push) Successful in 3m20s
Cloud Apache Container / Build-FPM-Images (84) (push) Successful in 2m19s
Cloud Apache Container / Build-FPM-Images (85) (push) Successful in 2m41s
Cloud Apache Container / Build-LiteSpeed-Images (81) (push) Successful in 43s
Cloud Apache Container / Build-LiteSpeed-Images (82) (push) Successful in 1m16s
Cloud Apache Container / Build-LiteSpeed-Images (83) (push) Successful in 29s
Cloud Apache Container / Build-LiteSpeed-Images (84) (push) Successful in 56s
Cloud Apache Container / Build-LiteSpeed-Images (85) (push) Successful in 2m2s
Cloud Apache Container / Build-Shared-httpd (push) Successful in 51s
refactor(litespeed): drop setUIDMode for shared lsphp + cut opcache 128→32M
OLS runs as the customer user end-to-end (server-level user/group set by
create-vhost-litespeed.sh), so lsphp inherits that uid without per-request
suEXEC. Eliminates the per-httpd-worker lsphp instance fan-out — one shared
lsphp parent now serves all httpd workers via the shared socket.

Combined with opcache.memory_consumption 128→32M, brain-jar measured shmem
dropped from ~880 MiB → 32 MiB and memory.current from ~1.1 GiB → 67 MiB
at the 1.5 GiB cap. No new oom_kills since the change.

Safe because cac-litespeed is one-customer-per-container — the container
boundary is the privsep boundary.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-02 20:06:56 -07:00

93 lines
4.3 KiB
Bash

#!/usr/bin/env bash
## create-vhost-litespeed.sh — sets up OLS config for one customer site.
##
## Approach: keep the stock LiteSpeed-shipped httpd_config.conf VERBATIM
## (it has all the cgid/lscgid plumbing that lscgid needs to actually
## create its IPC socket), and just APPEND our listeners + vhTemplate.
## The custom vhost template lives at conf/templates/site.conf and points
## at /home/${user}/public_html. envsubst renders our user/domain into
## both files at container start.
##
## Expects in env: user, domain, serveralias (optional).
set -euo pipefail
TPL_DIR=${TPL_DIR:-/etc/lsws-templates}
LSWS_CONF=/usr/local/lsws/conf
## Ensure the conf dir has stock config to append to. On first boot with
## a fresh image this is a no-op (image ships with conf/ populated). With
## a future volume mount of conf/, the upstream entrypoint pattern would
## copy from .conf/* — keep parity:
if [ -z "$(ls -A -- "$LSWS_CONF/" 2>/dev/null)" ]; then
cp -R /usr/local/lsws/.conf/* "$LSWS_CONF/"
fi
## Build the serveralias suffix for vhDomain. Empty for none, else
## ",alias1,alias2" prepended to the comma list.
vhost_map_aliases=""
if [ -n "${serveralias:-}" ]; then
for alias in $(echo "$serveralias" | tr ',' ' '); do
[ -z "$alias" ] && continue
vhost_map_aliases="${vhost_map_aliases},${alias}"
done
fi
export vhost_map_aliases user domain
## --- prep the stock httpd_config.conf before appending ours ---
## Stock ships with `listener HTTP {*:80}`, `listener HTTPS {*:443}`, and
## a `vhTemplate docker` mapped to /var/www/vhosts/$VH_NAME/html — these
## conflict with our ports and would shadow our siteVH vhost. Strip them
## and the demo `virtualHost Example`, but KEEP `listener Default` (it's
## bound to 8088 — harmless internally, removing risks unrelated breakage).
## Always restart from a stock copy so re-runs are idempotent (otherwise
## a second sed pass on already-stripped config corrupts it).
cp /usr/local/lsws/.conf/httpd_config.conf "$LSWS_CONF/httpd_config.conf"
## Strip the stock blocks we replace. Use awk: easier than sed range-deletes
## to skip a NAMED block of arbitrary length terminated by a top-level `}`.
## extProcessor lsphp is stripped because the stock one hard-codes
## PHP_LSAPI_CHILDREN=10 regardless of container size — our appended
## extProcessor scales it from detect-memory-litespeed.sh.
awk '
BEGIN { skip = 0 }
/^listener HTTP \{/ || /^listener HTTPS \{/ || /^vhTemplate docker \{/ || /^extProcessor lsphp\{/ || /^extProcessor lsphp \{/ { skip = 1; next }
skip && /^\}/ { skip = 0; next }
!skip { print }
' "$LSWS_CONF/httpd_config.conf" > "$LSWS_CONF/httpd_config.conf.new"
mv "$LSWS_CONF/httpd_config.conf.new" "$LSWS_CONF/httpd_config.conf"
## Server-level user/group → customer. Without this, OLS runs as nobody and
## either can't read customer files (no setUIDMode) or has to lscgid-spawn a
## per-uid lsphp for every httpd worker (the setUIDMode 2 pathway). With OLS
## itself running as ${user}, a single shared lsphp parent serves all httpd
## workers, LSAPI children-mode actually engages, and shmem stops fanning out.
## OLS still starts as root (PID 1 binds 80/443) then drops privs after bind.
sed -i \
-e "s|^user[[:space:]].*|user ${user}|" \
-e "s|^group[[:space:]].*|group ${user}|" \
"$LSWS_CONF/httpd_config.conf"
## --- append our listeners + vhTemplate ---
SENTINEL="## ---- cac-litespeed append (do not edit below) ----"
{
echo ""
echo "$SENTINEL"
envsubst '${user} ${domain} ${vhost_map_aliases} ${PHPVER} ${LSAPI_CHILDREN}' < "$TPL_DIR/httpd_config.tpl"
} >> "$LSWS_CONF/httpd_config.conf"
## --- write our vhost template to /usr/local/lsws/conf/templates/site.conf ---
envsubst '${user}' < "$TPL_DIR/site-template.tpl" \
> "$LSWS_CONF/templates/site.conf"
## --- per-vhost config file the vhTemplate will reference ---
## OLS creates conf/vhosts/$VH_NAME/ at template-instantiation time, but
## we pre-create it to satisfy the configFile path and write a minimal
## vhconf.conf (empty body — all real config is inline in the template's
## virtualHostConfig{} block).
mkdir -p "$LSWS_CONF/vhosts/siteVH"
echo "## auto-generated; real vhost config is in templates/site.conf" \
> "$LSWS_CONF/vhosts/siteVH/vhconf.conf"
## Permissions: OLS reads conf/ as lsadm. Don't break that.
chown -R lsadm:nogroup "$LSWS_CONF" 2>/dev/null || true