#!/usr/bin/env bash ## entrypoint-litespeed.sh — PID 1 for cac-litespeed:phpNN. ## Built on litespeedtech/openlitespeed:1.8.x-lsphp83 prebuilt base. Native ## LSAPI (no FPM proxy), one customer per container. ## ## Process supervision: starts OLS via `openlitespeed -n` (no-daemon + ## crash-guard, per OLS source: lshttpdmain.cpp). SIGTERM is forwarded. ## crond runs in the background for customer crontabs; OLS itself is the ## process we wait on (if OLS dies, the container exits and Docker ## restarts it per its restart policy). set -euo pipefail : "${PHPVER:=83}" : "${environment:=PROD}" : "${LSCACHE_AUTOINSTALL:=1}" export CONTAINER_ROLE="litespeed_only" export PHPVER environment LSCACHE_AUTOINSTALL ## ---- env validation ---- 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 : "${domain:=localhost}" export user domain ## ---- user + directories ---- if ! id -u "$user" >/dev/null 2>&1; then ## Ubuntu's useradd; mirror what the AL10 entrypoints do with adduser useradd -u "$uid" -m -s /bin/bash "$user" fi mkdir -p "/home/$user/public_html" ## Log dirs mirror cac:phpNN exactly — apache/ for web server access+error, ## php-fpm/ for PHP errors. OLS isn't Apache and lsphp isn't php-fpm, but ## the customer-facing paths stay identical so log-gathering, analytics, ## and the customer's "where do I find my access log?" mental model all ## just work without per-image-family special cases. mkdir -p "/home/$user/logs/apache" "/home/$user/logs/php-fpm" mkdir -p "/home/$user/lscache" mkdir -p /tmp/lshttpd/swap chmod 1777 /tmp/lshttpd ## ---- memory + lsphp pool sizing ---- # shellcheck source=/dev/null source /scripts/detect-memory-litespeed.sh echo "Container memory: ${CONTAINER_MEMORY_MB}MB | LSAPI_CHILDREN=${LSAPI_CHILDREN} | memSoft=${LSAPI_MEM_SOFT}M memHard=${LSAPI_MEM_HARD}M | PHPVER=${PHPVER}" ## ---- self-signed cert (idempotent) ---- mkdir -p /usr/local/lsws/conf/cert if [ ! -f /usr/local/lsws/conf/cert/self.crt ]; then openssl req -x509 -newkey rsa:2048 -nodes -days 3650 \ -keyout /usr/local/lsws/conf/cert/self.key \ -out /usr/local/lsws/conf/cert/self.crt \ -subj "/CN=${domain}" 2>/dev/null fi ## ---- render httpd_config + vhconf from templates ---- /scripts/create-vhost-litespeed.sh ## ---- point PHP error_log at the same customer-visible path that ## cac:phpNN uses for php-fpm errors. Drop-in compat: customer code that ## was tailing /home/$user/logs/php-fpm/error.log on the old image will ## see lsphp's PHP errors in the exact same file on the new image. ## Rendered as a tiny ini in lsphp's scan dir; PHP merges it after the ## production-tuning overrides at startup. SCAN_DIR=$(/usr/local/lsws/lsphp${PHPVER}/bin/lsphp -i 2>/dev/null | awk -F'=> ' '/^Scan this dir/ {print $2; exit}') if [ -n "$SCAN_DIR" ]; then cat > "$SCAN_DIR/99-user-error-log.ini" </dev/null || true chown -R "$user:$user" "/home/$user" chmod 755 "/home/$user" ## logs/apache and logs/php-fpm are written by OLS (running as the customer ## via setUIDMode 2) so they need to be customer-owned, not nobody. The ## chown -R above already covers them since they're under /home/$user. ## ---- drop healthz so docker HEALTHCHECK passes before customer files ## Always rewrite as customer; suexec lsphp will read it as that uid too. sudo -u "$user" sh -c "echo ok > /home/$user/public_html/healthz" ## ---- DEV: local mariadb + memcached for parity with cac entrypoints ---- if [ "$environment" = "DEV" ]; then echo "Starting Dev Deployment (litespeed)" mkdir -p "/home/$user/_db_backups" ## mariadb-server + memcached are NOT baked into the image (saves ~500MB ## on PROD pulls). Install them at runtime, but only once per container — ## the command -v guard means a restart of an already-bootstrapped ## container skips the apt step and DEV boot stays ~1.5s like PROD. ## First-boot in DEV adds ~30-60s for the apt install; acceptable ## tradeoff per the design spec. if ! command -v mysqld >/dev/null 2>&1; then echo "DEV first boot: installing mariadb-server + memcached..." apt-get update -qq DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ mariadb-server memcached apt-get clean rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* fi mkdir -p /run/mysqld && chown mysql:mysql /run/mysqld nohup mysqld --user=mysql &>/dev/null & if [ ! -f "/home/$user/mysql_creds" ]; then sleep 10 mysql_user=$(openssl rand -hex 7) mysql_password=$(openssl rand -hex 12) mysql_db="devdb_$(openssl rand -hex 3)" mysql -e "CREATE DATABASE $mysql_db;" mysql -e "CREATE USER '$mysql_user'@'localhost' IDENTIFIED BY '$mysql_password';" mysql -e "GRANT ALL PRIVILEGES ON *.* TO '$mysql_user'@'localhost' WITH GRANT OPTION;" mysql -e "FLUSH PRIVILEGES;" { echo "MySQL User: $mysql_user" echo "MySQL Password: $mysql_password" echo "MySQL Database: $mysql_db" } > "/home/$user/mysql_creds" cat "/home/$user/mysql_creds" fi /usr/bin/memcached -d -u "$user" fi ## ---- user crontab ---- if [ ! -f "/home/$user/crontab" ]; then { echo "# User crontab for $user" echo "# Add your cron jobs here" } > "/home/$user/crontab" chown "$user:$user" "/home/$user/crontab" fi crontab -u "$user" "/home/$user/crontab" service cron start >/dev/null 2>&1 || /usr/sbin/cron ## ---- LSCache plugin (background, non-fatal) ---- ( /scripts/install-lscache-wp.sh "$user" >>/var/log/lscache-install.log 2>&1 || true ) & ## ---- start OLS in foreground with crash-guard ---- ## openlitespeed -n = no-daemon + supervisor. Trap forwards SIGTERM cleanly. OLS_PID="" trap '[ -n "$OLS_PID" ] && kill -TERM "$OLS_PID" 2>/dev/null; wait "$OLS_PID" 2>/dev/null || true' TERM INT /usr/local/lsws/bin/openlitespeed -n & OLS_PID=$! ## Stream OLS + customer logs to PID-1 stdout so `docker logs` works. touch /usr/local/lsws/logs/error.log /usr/local/lsws/logs/access.log touch "/home/$user/logs/apache/error_log" "/home/$user/logs/apache/access_log" touch "/home/$user/logs/php-fpm/error.log" chown "$user:$user" "/home/$user/logs/apache/error_log" \ "/home/$user/logs/apache/access_log" \ "/home/$user/logs/php-fpm/error.log" tail -F /usr/local/lsws/logs/error.log \ /usr/local/lsws/logs/access.log \ "/home/$user/logs/apache/error_log" \ "/home/$user/logs/apache/access_log" \ "/home/$user/logs/php-fpm/error.log" 2>/dev/null & wait "$OLS_PID"