2026-06-02 07:32:47 -07:00
|
|
|
## cac-litespeed — OpenLiteSpeed customer container, LSAPI-native.
|
|
|
|
|
##
|
|
|
|
|
## Built on top of the LiteSpeed-maintained prebuilt image rather than
|
|
|
|
|
## installed-from-RPM on AlmaLinux 10. Rationale:
|
|
|
|
|
## - The EL10 RPM ships an empty /usr/local/lsws/cgid/ directory (the
|
|
|
|
|
## lscgid suexec helper is built by the upstream tarball install.sh,
|
|
|
|
|
## not packaged), which makes LSAPI unusable.
|
|
|
|
|
## - The prebuilt image is Ubuntu 24.04-based and includes lsphp +
|
|
|
|
|
## everything WP/WooCommerce needs out of the box (memcached, redis,
|
|
|
|
|
## imagick, mbstring, mysqlnd, intl, gd, soap, bcmath, gmp, sodium,
|
|
|
|
|
## opcache, ...) — saves us a dozen explicit installs and avoids the
|
|
|
|
|
## libonig.so.105 packaging bug entirely.
|
|
|
|
|
## - LiteSpeed Inc maintains it; OLS upgrades become a base-image bump.
|
|
|
|
|
##
|
|
|
|
|
## Tradeoff vs the rest of the CAC family: this image is Ubuntu-based,
|
|
|
|
|
## not AlmaLinux. The "cac" naming is now slightly misleading (it's no
|
|
|
|
|
## longer Cloud *Apache* Container, it's Cloud LiteSpeed Container) but
|
|
|
|
|
## the panel doesn't care and the customer-facing contract is identical.
|
|
|
|
|
|
|
|
|
|
## ARG before FROM is special — it can be used in the FROM line, but the
|
|
|
|
|
## value goes out of scope inside the image, so we re-declare ARG PHPVER
|
|
|
|
|
## after FROM for any RUN steps that need it.
|
|
|
|
|
ARG OLS_VERSION=1.8.5
|
|
|
|
|
ARG PHPVER=83
|
2026-10-21 09:43:45 -07:00
|
|
|
|
|
|
|
|
## ---- EMERGENCY ONLY: lsphp compiled from php.net source ----------------------
|
|
|
|
|
## Idle unless PHP_SRC_VERSION is set (then /lsphp-src-out stays empty and the
|
|
|
|
|
## overlay step below is a no-op). Same stage as Dockerfile.lsphp — see there and
|
|
|
|
|
## docs/lsphp-source-emergency.md.
|
|
|
|
|
FROM litespeedtech/openlitespeed:${OLS_VERSION}-lsphp${PHPVER} AS lsphp-src
|
|
|
|
|
ARG PHPVER=83
|
|
|
|
|
ARG CACHE_BUST=
|
|
|
|
|
ARG EXPECT_LSPHP_PKG=
|
|
|
|
|
ARG EXPECT_PHP_VERSION=
|
|
|
|
|
ARG PHP_SRC_VERSION=
|
|
|
|
|
ARG PHP_SRC_SHA256=
|
|
|
|
|
RUN --mount=type=bind,source=scripts,target=/mnt/scripts \
|
|
|
|
|
--mount=type=bind,source=keys/php-src,target=/usr/local/share/php-src-keys \
|
|
|
|
|
set -e; \
|
|
|
|
|
if [ -n "$PHP_SRC_VERSION" ]; then \
|
|
|
|
|
install -m 0755 /mnt/scripts/lsphp-apt-upgrade.sh /usr/local/sbin/lsphp-apt-upgrade.sh; \
|
|
|
|
|
fi; \
|
|
|
|
|
PHPVER="${PHPVER}" bash /mnt/scripts/lsphp-src-build.sh
|
|
|
|
|
|
2026-06-02 07:32:47 -07:00
|
|
|
FROM litespeedtech/openlitespeed:${OLS_VERSION}-lsphp${PHPVER}
|
|
|
|
|
ARG PHPVER=83
|
|
|
|
|
ENV PHPVER=${PHPVER}
|
|
|
|
|
|
|
|
|
|
## Tooling we layer on top of the base:
|
|
|
|
|
## - gettext-base: envsubst for runtime template rendering
|
|
|
|
|
## - sudo: install-lscache-wp.sh runs wp-cli as the customer user
|
|
|
|
|
## - composer: not in the base image (wp-cli is)
|
|
|
|
|
## - cron: customer crontab support (mirror cac:phpXX behaviour)
|
|
|
|
|
## - lsphp83-ldap: not in base image, useful for some WP plugins
|
|
|
|
|
##
|
2026-06-02 08:26:19 -07:00
|
|
|
## NOTE: mariadb-server + memcached were previously installed here for
|
|
|
|
|
## DEV-mode parity but bloated the PROD image by ~500MB. They are now
|
|
|
|
|
## installed at runtime by entrypoint-litespeed.sh ONLY when
|
|
|
|
|
## environment=DEV, mirroring the cac:phpNN pattern. The mysql CLI
|
|
|
|
|
## client (used by the DEV creds-bootstrap and by wp-cli) is already
|
|
|
|
|
## present in the litespeedtech/openlitespeed base via the mysql-client
|
|
|
|
|
## package, so no client-side install is needed at build time.
|
|
|
|
|
##
|
2026-06-02 07:32:47 -07:00
|
|
|
## All apt cache is cleaned in the same layer to keep image size down.
|
|
|
|
|
## lsphp${PHPVER}-ldap is the only extra ext we add (everything else WP needs
|
|
|
|
|
## ships in the prebuilt base). lsphp84 + lsphp85 don't ship imap or pspell
|
|
|
|
|
## from LiteSpeed — customers needing imap should pin to 8.3 or earlier.
|
2026-10-21 06:07:48 -07:00
|
|
|
##
|
|
|
|
|
## SECURITY UPDATES AT BUILD TIME: lsphp-apt-upgrade.sh also upgrades the OS and
|
|
|
|
|
## sweeps EVERY installed lsphp${PHPVER}* package to the LiteSpeed repo's current
|
|
|
|
|
## release, failing the build if the repo is unreachable — so a rebuild ships a
|
|
|
|
|
## PHP security fix as soon as LiteSpeed publishes the .deb, without waiting for
|
|
|
|
|
## a new litespeedtech/openlitespeed base tag. See the script header.
|
|
|
|
|
##
|
|
|
|
|
## CACHE_BUST: CI passes a per-run value so this layer can never be a cache hit
|
|
|
|
|
## (an ARG's first use in a RUN is part of that layer's cache key). Local builds:
|
|
|
|
|
## pass --build-arg CACHE_BUST=$(date +%s) or use --no-cache, or you may get the
|
|
|
|
|
## lsphp from your last build. EXPECT_* are resolved by CI from the repo index
|
|
|
|
|
## and asserted here; the same values become the image labels below.
|
|
|
|
|
ARG CACHE_BUST=
|
|
|
|
|
ARG EXPECT_LSPHP_PKG=
|
|
|
|
|
ARG EXPECT_PHP_VERSION=
|
|
|
|
|
COPY ./scripts/lsphp-apt-upgrade.sh /usr/local/sbin/lsphp-apt-upgrade.sh
|
|
|
|
|
RUN /usr/local/sbin/lsphp-apt-upgrade.sh "${PHPVER}" \
|
2026-06-02 07:32:47 -07:00
|
|
|
gettext-base sudo cron \
|
|
|
|
|
ca-certificates curl wget \
|
|
|
|
|
lsphp${PHPVER}-ldap && \
|
|
|
|
|
apt-get clean && \
|
|
|
|
|
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
|
|
|
|
|
|
2026-10-21 09:43:45 -07:00
|
|
|
## EMERGENCY PATH: overlay the php.net lsphp (no-op on normal builds) and prove
|
|
|
|
|
## it has the same extension/feature surface as the packaged one just installed
|
|
|
|
|
## — see scripts/lsphp-src-overlay.sh. Bind mounts: no extra image layer content.
|
|
|
|
|
ARG PHP_SRC_VERSION=
|
|
|
|
|
ARG LSPHP_SOURCE=litespeed-apt
|
|
|
|
|
RUN --mount=type=bind,from=lsphp-src,source=/lsphp-src-out,target=/lsphp-src-out,rw \
|
|
|
|
|
--mount=type=bind,source=scripts,target=/mnt/scripts \
|
|
|
|
|
install -m 0644 /mnt/scripts/lsphp-src-probe.php /usr/local/share/lsphp-src-probe.php && \
|
|
|
|
|
bash /mnt/scripts/lsphp-src-overlay.sh runtime "${PHPVER}" && \
|
|
|
|
|
rm -f /usr/local/share/lsphp-src-probe.php
|
|
|
|
|
|
2026-06-02 07:32:47 -07:00
|
|
|
## Composer (matches the wp-cli pattern in the existing CAC Dockerfile —
|
|
|
|
|
## phar download, no `php install` pipe since lsphp's CLI mode is fine).
|
|
|
|
|
RUN curl -fsSL -o /usr/local/bin/composer https://getcomposer.org/download/latest-stable/composer.phar && \
|
|
|
|
|
chmod +x /usr/local/bin/composer
|
|
|
|
|
|
|
|
|
|
## Our scripts + config templates layer in last (they change most often,
|
|
|
|
|
## keep them off the slow apt layer).
|
|
|
|
|
COPY ./scripts/entrypoint-litespeed.sh \
|
|
|
|
|
./scripts/create-vhost-litespeed.sh \
|
|
|
|
|
./scripts/detect-memory-litespeed.sh \
|
|
|
|
|
./scripts/install-lscache-wp.sh \
|
|
|
|
|
./scripts/log-rotate.sh \
|
|
|
|
|
/scripts/
|
|
|
|
|
RUN chmod +x /scripts/*
|
|
|
|
|
COPY ./configs/litespeed/ /etc/lsws-templates/
|
2026-10-21 07:21:47 -07:00
|
|
|
## php2shell mitigation (CVE-2026-109618/-109619). Named zz- so it sorts after
|
|
|
|
|
## every other scan-dir ini (incl. runtime-written 99-*) and wins. Remove once
|
|
|
|
|
## all images ship PHP >= 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12.
|
|
|
|
|
COPY ./configs/zz-php2shell-mitigation.ini /etc/lsws-templates/zz-php2shell-mitigation.ini
|
2026-06-02 07:32:47 -07:00
|
|
|
|
|
|
|
|
## Apply our production lsphp ini overrides. Ask lsphp for its scan dir
|
|
|
|
|
## directly (varies by PHP minor version: 8.3/8.4/8.5 each have their own
|
|
|
|
|
## /usr/local/lsws/lsphpNN/etc/php/8.M/mods-available/). Dockerfile RUN uses
|
|
|
|
|
## /bin/sh so we explicitly `bash -c` for safer scripting.
|
|
|
|
|
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"; \
|
2026-10-21 07:21:47 -07:00
|
|
|
cp /etc/lsws-templates/zz-php2shell-mitigation.ini "$SCAN_DIR/zz-php2shell-mitigation.ini"; \
|
2026-06-02 07:32:47 -07:00
|
|
|
echo "wrote overrides to $SCAN_DIR"'
|
|
|
|
|
|
|
|
|
|
## Disable the OLS WebAdmin port for customer-facing containers. Bind admin
|
|
|
|
|
## listener to loopback so it's unreachable even from the docker network.
|
|
|
|
|
RUN sed -i 's|^[[:space:]]*address[[:space:]]\+\*:| address 127.0.0.1:|' \
|
|
|
|
|
/usr/local/lsws/admin/conf/admin_config.conf 2>/dev/null || true
|
|
|
|
|
|
|
|
|
|
## Cron entry for log rotation (mirrors cac:phpXX).
|
|
|
|
|
RUN echo "15 */12 * * * root /scripts/log-rotate.sh" >> /etc/crontab
|
|
|
|
|
|
2026-10-21 06:07:48 -07:00
|
|
|
## Inspect without running the image:
|
|
|
|
|
## docker buildx imagetools inspect <ref> --format '{{json .Image.Config.Labels}}'
|
|
|
|
|
## Values come from CI's repo-index lookup and were asserted against the
|
|
|
|
|
## installed packages by lsphp-apt-upgrade.sh above ("unverified" = local build).
|
2026-10-21 09:43:45 -07:00
|
|
|
## Emergency (php.net) builds: see the same LABEL block in Dockerfile.lsphp.
|
|
|
|
|
LABEL org.whp.php-version="${PHP_SRC_VERSION:-${EXPECT_PHP_VERSION:-unverified}}" \
|
2026-10-21 06:07:48 -07:00
|
|
|
org.whp.lsphp-package-version="${EXPECT_LSPHP_PKG:-unverified}" \
|
2026-10-21 09:43:45 -07:00
|
|
|
org.whp.lsphp-source="${LSPHP_SOURCE}" \
|
2026-10-21 06:07:48 -07:00
|
|
|
org.whp.php-flavour="lsphp${PHPVER}"
|
|
|
|
|
|
2026-06-02 07:32:47 -07:00
|
|
|
EXPOSE 80 443
|
|
|
|
|
|
|
|
|
|
## Healthcheck: the entrypoint drops a static /healthz into the customer
|
|
|
|
|
## docroot at boot, so this passes even before any customer files exist.
|
|
|
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
|
|
|
|
CMD curl -fsSk https://127.0.0.1/healthz || exit 1
|
|
|
|
|
|
|
|
|
|
ENTRYPOINT ["/scripts/entrypoint-litespeed.sh"]
|