Skip to content

Instantly share code, notes, and snippets.

@cPFence
Last active February 10, 2026 11:09
Show Gist options
  • Select an option

  • Save cPFence/d829366b95f8abd4d4ac2501b7be425d to your computer and use it in GitHub Desktop.

Select an option

Save cPFence/d829366b95f8abd4d4ac2501b7be425d to your computer and use it in GitHub Desktop.
#!/bin/bash
# Written by: cPFence Team / https://cpfence.app/
#
# Description:
# This script is designed to automate the optimization and configuration of OpenLiteSpeed
# running inside a Docker container or directly on the host. It backs up the existing
# configuration file, applies updates to critical server settings such as worker processes,
# CPU affinity, memory buffer sizes, and external application configurations for PHP-LSAPI.
# MD5 checksum validation is added to detect changes and prevent redundant updates.
#
# Usage:
# Simply configure the global variables below to match your desired settings and run the script.
# The script will handle the rest, including backups, applying updates, and restarting the server.
#
# Note for Enhance Control Panel (CP) users:
# If you are using Enhance CP, you will need to set up a cron job to run this script every minute.
# This ensures your settings are maintained, as Enhance CP may override them. Setting up the cron
# job guarantees the script re-applies your configurations regularly to prevent any unwanted changes.
#
# Example Cron Job:
# * * * * * /path/to/your/ols_optimize.sh
#
# Disclaimer:
# This script is provided "as is" without any warranties of any kind, express or implied.
# It is recommended to thoroughly test this script in a non-production environment prior to
# deployment on any live or critical systems. cPFence and Linkers Gate LLC are not liable for
# any damage or data loss resulting from the use of this script.
#
# License: Copyright (C) 2023 - 2024 Linkers Gate LLC.
# Global Variables (User configurable)
HTTPD_WORKERS="16"
CPU_AFFINITY="1"
ENABLE_LVE="0"
IN_MEM_BUF_SIZE="512M"
MAX_CONNECTIONS="100000"
MAX_SSL_CONNECTIONS="100000"
SND_BUF_SIZE="512k"
RCV_BUF_SIZE="512k"
TOTAL_IN_MEM_CACHE_SIZE="512M"
MAX_MMAP_FILE_SIZE="64M"
TOTAL_MMAP_CACHE_SIZE="512M"
# AIO settings mapping (numbers correspond to options in the OpenLiteSpeed admin panel)
USE_AIO="3" # 3 = io_uring (Refer to the OLS admin panel for other options and their corresponding numbers)
AIO_BLOCK_SIZE="3" # 3 = 512K (Check the OLS admin panel for other block size options and their respective numbers)
PHP_LSAPI_CHILDREN="500"
LSAPI_AVOID_FORK="0"
LSPHP_MAX_CONNS="500"
LSPHP_AUTOSTART="2"
# Using Enhance v12 option (set to 'on' if running directly on the host)
Using_Enhance_v12="off" # Options: "on" or "off"
### DO NOT EDIT BELOW THIS LINE ###
CONTAINER_NAME="openlitespeed"
CONFIG_PATH="/usr/local/lsws/conf/httpd_config.conf"
BACKUP_DIR="/usr/local/lsws/conf/"
BACKUP_FILE="httpd_config_backup-$(date +"%d%m%y-%H%M%S").conf"
MD5_FILE="/usr/local/src/ols_config_md5sum.txt"
# Check if Using_Enhance_v12 is on or off and adjust the docker command accordingly
if [ "$Using_Enhance_v12" = "on" ]; then
docker_cmd=""
else
docker_cmd="docker exec $CONTAINER_NAME "
fi
# welcome message
display_welcome()
{
echo "**********************************************************************************************"
echo "* cPFence Web Security *"
echo "* OpenLiteSpeed Optimization Script *"
echo "* Copyright (C) 2023 - 2024 Linkers Gate LLC. *"
echo "**********************************************************************************************"
}
display_welcome
# Step 1: Calculate the current MD5 hash of the config file
CURRENT_MD5=$(${docker_cmd}md5sum $CONFIG_PATH | awk '{print $1}')
# Step 2: Check if the MD5 file exists and compare hashes
if test -f "$MD5_FILE"; then
STORED_MD5=$(cat $MD5_FILE)
if [ "$CURRENT_MD5" == "$STORED_MD5" ]; then
echo "No changes detected in the configuration. Exiting..."
exit 0
else
echo "Configuration has changed, applying updates..."
fi
else
echo "No MD5 file found, applying updates..."
fi
# Step 3: Backup the current configuration
${docker_cmd}cp -a $CONFIG_PATH $BACKUP_DIR$BACKUP_FILE
echo "Backup created: $BACKUP_DIR$BACKUP_FILE"
# Step 4: Function to add or replace config values in specific sections
update_or_add_config() {
SECTION=$1
PARAMETER=$2
VALUE=$3
# Find the section first, then add or replace the parameter in that section
${docker_cmd}grep -q "$SECTION" $CONFIG_PATH
if [ $? -eq 0 ]; then
# Check if the parameter exists within the section
${docker_cmd}sed -n "/$SECTION/,/^[^ ]/p" $CONFIG_PATH | grep -q "$PARAMETER"
if [ $? -eq 0 ]; then
# Parameter exists, replace it within the section
${docker_cmd}sed -i "/$SECTION/,/^[^ ]/ s/\($PARAMETER\s*\).*/\1$VALUE/" $CONFIG_PATH
echo "Updated $PARAMETER to $VALUE in $SECTION"
else
# Parameter doesn't exist, append it to the section
${docker_cmd}sed -i "/$SECTION/a\\ $PARAMETER $VALUE" $CONFIG_PATH
echo "Added $PARAMETER with value $VALUE to $SECTION"
fi
else
echo "Section $SECTION not found."
fi
}
# Step 5: Handle serverName and related settings if missing
${docker_cmd}grep -q "serverName" $CONFIG_PATH
if [ $? -ne 0 ]; then
${docker_cmd}sed -i "1i serverName\n" $CONFIG_PATH
echo "Added serverName block at the top of the file."
fi
# Add missing httpdWorkers, cpuAffinity, and enableLVE
update_or_add_config "serverName" "httpdWorkers" "$HTTPD_WORKERS"
update_or_add_config "serverName" "cpuAffinity" "$CPU_AFFINITY"
update_or_add_config "serverName" "enableLVE" "$ENABLE_LVE"
update_or_add_config "serverName" "inMemBufSize" "$IN_MEM_BUF_SIZE"
# Step 6: Update tuning settings
update_or_add_config "tuning" "maxConnections" "$MAX_CONNECTIONS"
update_or_add_config "tuning" "maxSSLConnections" "$MAX_SSL_CONNECTIONS"
update_or_add_config "tuning" "sndBufSize" "$SND_BUF_SIZE"
update_or_add_config "tuning" "rcvBufSize" "$RCV_BUF_SIZE"
update_or_add_config "tuning" "totalInMemCacheSize" "$TOTAL_IN_MEM_CACHE_SIZE"
update_or_add_config "tuning" "maxMMapFileSize" "$MAX_MMAP_FILE_SIZE"
update_or_add_config "tuning" "totalMMapCacheSize" "$TOTAL_MMAP_CACHE_SIZE"
# Correct useAIO and AIOBlockSize mappings to 3
update_or_add_config "tuning" "useAIO" "$USE_AIO"
update_or_add_config "tuning" "AIOBlockSize" "$AIO_BLOCK_SIZE"
# Step 7: Update external processor settings for lsphp (Correct env values)
${docker_cmd}sed -i "s/env\s*PHP_LSAPI_CHILDREN=.*/env PHP_LSAPI_CHILDREN=$PHP_LSAPI_CHILDREN/" $CONFIG_PATH
${docker_cmd}sed -i "s/env\s*LSAPI_AVOID_FORK=.*/env LSAPI_AVOID_FORK=$LSAPI_AVOID_FORK/" $CONFIG_PATH
# Step 8: Correctly target maxConns in extprocessor lsphp only
${docker_cmd}sed -i "/extprocessor lsphp {/,/}/ s/maxConns\s*.*/maxConns $LSPHP_MAX_CONNS/" $CONFIG_PATH
# Update autoStart for lsphp
update_or_add_config "extprocessor lsphp" "autoStart" "$LSPHP_AUTOSTART"
# Step 9: Save the new MD5 hash of the config file
${docker_cmd}md5sum $CONFIG_PATH | awk '{print $1}' > $MD5_FILE
# Step 10: Restart OpenLiteSpeed to apply the changes
${docker_cmd}/usr/local/lsws/bin/lswsctrl restart
echo "OpenLiteSpeed restarted with updated configuration."
exit 0
@matrixino
Copy link

matrixino commented Feb 10, 2026

Just wanted to report a bug. You should use the lshttpd systemd unit to restart lsws. If you use lswsctrl you will break the ols service running, because by default the lsws_env file in /usr/local/lsws/bin uses the /tmp pidfile. But Enhance use a different pidfile as defined in their unit files (/var/run/openlitespeed.pid). So the restart won't find the correct process pid and attempt to start a new OLS instance, causing major error or even ols crash.
If this kind of restart is usend also in some of your CPfence scripts, you should change it there too.

@cPFence
Copy link
Author

cPFence commented Feb 10, 2026

Just wanted to report a bug. You should use the lshttpd systemd unit to restart lsws. If you use lswsctrl you will break the ols service running, because by default the lsws_env file in /usr/local/lsws/bin uses the /tmp pidfile. But Enhance use a different pidfile as defined in their unit files (/var/run/openlitespeed.pid). So the restart won't find the correct process pid and attempt to start a new OLS instance, causing major error or even ols crash. If this kind of restart is usend also in some of your CPfence scripts, you should change it there too.

Yes, that script was written and tested before v12 was released. On Enhance v12 servers you should only use systemd to reload or restart OLS/LS. This is already how we handle it in cPFence 3.3.31 and newer, since Enhance v12 was introduced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment