## ---- shared-ols append (do not edit below) ---- ## Server-level config for the SHARED OpenLiteSpeed tier. Appended to the ## stock httpd_config.conf AFTER render-shared-ols-config.sh strips the stock ## listeners, vhTemplate docker, AND the stock `extProcessor lsphp` + ## `scriptHandler` (so this server NEVER runs PHP locally — every site's PHP ## goes to its own detached cac-lsphp sidecar over LSAPI). Rendered with ## envsubst; only ${LSCACHE_ROOT} is substituted here. serverName shared-ols ## Real client IP behind HAProxy. HAProxy sets X-Forwarded-For (the real ## client) and X-Forwarded-Proto. Mode 1 = always use X-Forwarded-For as the ## client IP. HAProxy is the ONLY thing that ever connects to this tier (it's on ## client-net with no host-published ports) and it OVERWRITES X-Forwarded-For ## with %[src] (set-header, not add-header), so a client can't spoof it — mode 1 ## is safe here and matches the working standalone litespeed config. ## NOTE: mode 2 ("trusted IP only") does NOT mean "trust the proxy header" — it ## extracts the real IP ONLY when the connecting peer is in a TRUSTED access ## list, which this tier never configured. With mode 2 + no trusted IP, OLS kept ## HAProxy's container IP as REMOTE_ADDR for every request, so WP security ## plugins saw all tenants as one IP and blocking it locked everyone out. useIpInProxyHeader 1 ## LSCache enabled at MODULE scope for the whole tier (dedicated cache volume, ## ephemeral across rebuilds; OLS auto-keys a per-vhost subdir under storagePath). ## PUBLIC (anonymous) caching ONLY: checkPublicCache 1 lets OLS serve cacheable, ## non-logged-in responses that are EXPLICITLY marked by the LiteSpeed Cache WP ## plugin's X-LiteSpeed-Cache-Control headers (ignoreRespCacheCtrl=0 honors them). ## ## enableCache is 0 ON PURPOSE. At module scope enableCache 1 means "cache every ## cacheable-looking public response by default", INCLUDING ones that carry no ## cache header at all. That bit us on Divi: LSCWP's Divi compat calls ## litespeed_disable_all for ?et_fb= / ?et_pb_preview= / ?p=N&preview=true, which ## switches the plugin off for the request, so it sends NO header (and its own ## "Do Not Cache Query Strings" never runs) — and OLS stored the Visual Builder ## page under enableCache 1. With enableCache 0 only responses that opt in via ## X-LiteSpeed-Cache-Control: public are stored; a plugin-disabled request is ## simply not cached. Measured on OLS 1.8.4 (2026-09-21): headerless response = ## miss,hit under 1; not cached under 0; explicit `public` header cached under ## both. Matches the dedicated cac-litespeed tier (configs/litespeed/site-template.tpl). ## ## PRIVATE caching is intentionally OFF (enablePrivateCache 0 + checkPrivateCache 0). ## Logged-in / cookie-bearing pages must NEVER be cached at the tier. We previously ## left enablePrivateCache=1 assuming "no plugin -> nothing cached," but that was ## WRONG: with private storage + reqCookieCache on, OLS privately cached logged-in ## responses regardless of plugin, serving stale wp-admin (e.g. a "failed update" ## nag that persisted for the full privateExpireInSeconds TTL). Keeping private ## cache off guarantees logged-in pages are always served fresh. module cache { storagePath ${LSCACHE_ROOT} checkPrivateCache 0 checkPublicCache 1 maxCacheObjSize 10000000 maxStaleAge 200 qsCache 1 reqCookieCache 1 respCookieCache 1 ignoreReqCacheCtrl 0 ignoreRespCacheCtrl 0 enableCache 0 enablePrivateCache 0 } ## ---- end shared-ols server append ----