Jump to content
View in the app

A better way to browse. Learn more.

AlphaGNU

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

How to Add Custom PHP 8.4 / 8.5 Support to CWP on AlmaLinux 9.x

Featured Replies

Full tutorial with GUI integration, fixed OpenSSL support, external modules, and a working custom PHP builder.

This guide explains how to properly add PHP 8.4 and PHP 8.5 to Control Web Panel (CWP) on EL9-based systems.
Unlike older CWP releases, CWP does not provide official PHP 8.4/8.5 packages yet — but with the steps below you can fully integrate them into and you can also fix the PHP 8.3 OpenSSL problem based on this:

the CWP PHP Selector GUI
Apache / Nginx vhosts
external PECL modules
system services
CSF/Monit integration

This article provides everything: file paths, scripts, corrections, and the build steps.

⚙️ Step 1 — Extend the CWP GUI to Support PHP 8.4 and 8.5

CWP reads available PHP versions from:

/usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/versions.ini

Add the new PHP versions like:

[8.3]
version[]=8.3.28
version[]=8.3.27
version[]=8.3.25
version[]=8.3.21
version[]=8.3.20
version[]=8.3.19
version[]=8.3.17
version[]=8.3.16
version[]=8.3.15
version[]=8.3.14
version[]=8.3.13
version[]=8.3.12
version[]=8.3.11
version[]=8.3.10
version[]=8.3.9
version[]=8.3.8
version[]=8.3.7
version[]=8.3.6
version[]=8.3.4
version[]=8.3.3
version[]=8.3.2
version[]=8.3.1
version[]=8.3.0

[8.4]
version[]=8.4.14
version[]=8.4.13
version[]=8.4.12
version[]=8.4.11
version[]=8.4.10
version[]=8.4.9
version[]=8.4.8
version[]=8.4.7
version[]=8.4.6
version[]=8.4.4
version[]=8.4.3
version[]=8.4.2
version[]=8.4.1
version[]=8.4.0

[8.5]
version[]=8.5.0

This makes the versions selectable in the GUI.

If you don't want to make previous PHP 8.4 versions optional under 8.4.14, you can leave them out of the list.

⚙️ Step 2 — Create 8.4.ini and 8.5.ini GUI Templates

Location:

/usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/

Create these files based on the sample and content of 8.3.ini:

8.4.ini
8.5.ini

Both must contain a corrected OpenSSL section:

[openssl]
default=1
option="--with-openssl=/usr"
info-file=openssl.txt

(Older CWP templates use deprecated OpenSSL paths that break EL9 builds. The corrected version above is mandatory. And similarly, the OpenSSL section in the 8.3.ini file must be corrected.)

These files provide the GUI-driven configure flags that our builder script will later use.

⚙️ Step 3 — Create External Modules for PHP 8.4 and 8.5

Create these directories:

/usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/external_modules/8.4
/usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/external_modules/8.5

Populate each directory with the updated scripts:

  • apcu.sh

  • imagick.sh

  • memcache.sh

  • memcached.sh

  • mailparse.sh

  • mongodb.sh

  • redis.sh

  • ssh2.sh

  • uploadprogress.sh

  • xdebug.sh

  • yaz.sh

  • sodium.sh

  • sourceguardian.sh

  • sqlsrv.sh

  • ioncube.sh
    (With proper loader URL handling: stable for 8.4, beta for 8.5.)

👉 Here is the ZIP file with all corrected module scripts to this post for download:

External_Modules

⚙️ Step 4 — Install the Custom Builder Script

Place the builder script in:

/root/build-php-fpm84-el9.sh

This script:

reads the GUI-generated configure template
enforces OpenSSL 3.x for EL9
builds PHP cleanly under /opt/alt/php-fpm84/usr/
installs FPM service, ini files, sockets
compiles all external modules
integrates CSF and Monit
logs every step

You can rewrite this script to install PHP 8.3.28 or PHP 8.5.0 by changing just a few variables.

Here is the corrected PHP compiler script located in /root/build-php-fpm84-el9.sh file:

#!/bin/bash
set -euo pipefail
set -x

# --- Basic variables ---
PHPMAJOR="84"                  # php-fpm84
PHPVER="8.4.14"                # PHP version
FPMDIR="/opt/alt/php-fpm${PHPMAJOR}"
CONFBASE="/usr/local/cwp/.conf/php-fpm_conf"

arch=$(uname -m)
if [[ "$arch" == "x86_64" ]]; then
    platform="x86-64"
    libdir="/usr/lib64"
else
    platform="x86"
    libdir="/usr/lib"
fi

# --- Packages for Build (EL9) ---
dnf -y install \
  krb5-devel glibc-common gnutls-devel \
  libargon2 libargon2-devel libbsd-devel \
  perl libzip libzip-devel pcre2 pcre2-devel \
  libavif libavif-devel \
  uw-imap-devel \
  openssl-devel

# If there is any old CWP OpenSSL hack left, don't use it.:
if [ -d /usr/local/opensslso ]; then
  echo "WARN: /usr/local/opensslso exists, but we DO NOT USE for compiling PHP (OpenSSL 1.1 hack)."
fi

# --- Force OpenSSL 3.x ---
export PKG_CONFIG_PATH=/usr/lib64/pkgconfig
export OPENSSL_CFLAGS="-I/usr/include"
export OPENSSL_LIBS="-L/usr/lib64"
export LDFLAGS="-lssl -lcrypto"

# --- CWP pre-conf, if exists (e.g.: pcre2, & other libs) ---
if [ -e "${CONFBASE}/php${PHPMAJOR}_pre.conf" ]; then
    bash "${CONFBASE}/php${PHPMAJOR}_pre.conf"
fi

# --- PHP SOURCE DOWNLOAD: CWP CDN → OFFICIAL php.net ---
try_cwp=$(wget -q -S --spider "http://static.cdn-cwp.com/files/php/php-${PHPVER}.tar.gz" -O - 2>&1 | sed -ne '/Content-Length/{s/.*: //;p}')
try_official=$(wget -q -S --spider "https://www.php.net/distributions/php-${PHPVER}.tar.gz" -O - 2>&1 | sed -ne '/Content-Length/{s/.*: //;p}')

try_cwp=${try_cwp:-0}
try_official=${try_official:-0}

if [ "$try_cwp" -ge 8000000 ]; then
    PHPSOURCE="http://static.cdn-cwp.com/files/php/php-${PHPVER}.tar.gz"
elif [ "$try_official" -ge 8000000 ]; then
    PHPSOURCE="https://www.php.net/distributions/php-${PHPVER}.tar.gz"
else
    echo "Could not download PHP version ${PHPVER}"
    exit 1
fi

# --- Build directory ---
rm -rf /usr/local/src/php-build
mkdir -p /usr/local/src/php-build
cd /usr/local/src/php-build

wget -q "${PHPSOURCE}" -O "php-${PHPVER}.tar.gz"

tar -xvf "php-${PHPVER}.tar.gz"
cd "php-${PHPVER}"

# --- Configure: CWP's own php84.conf, but already wired to OpenSSL 3.x from env ---
if [ ! -x "${CONFBASE}/php${PHPMAJOR}.conf" ]; then
    chmod +x "${CONFBASE}/php${PHPMAJOR}.conf" 2>/dev/null || true
fi

# IMPORTANT: LDFLAGS + PKG_CONFIG_PATH already exported
bash "${CONFBASE}/php${PHPMAJOR}.conf"

# --- Compiling ---
if command -v nproc >/dev/null 2>&1; then
    make -j"$(nproc)"
else
    make
fi

make install

# --- PHP.ini + FPM scaffolding ---
mkdir -p "${FPMDIR}/usr/php/php.d"
mkdir -p "${FPMDIR}/usr/var/sockets"
mkdir -p "${FPMDIR}/usr/etc/php-fpm.d"
mkdir -p "${FPMDIR}/usr/etc/php-fpm.d/users"

rsync php.ini-production "${FPMDIR}/usr/php/php.ini"

sed -i 's/^short_open_tag.*/short_open_tag = On/' "${FPMDIR}/usr/php/php.ini"
sed -i 's/^;cgi.fix_pathinfo=.*/cgi.fix_pathinfo=1/' "${FPMDIR}/usr/php/php.ini"
sed -i 's/.*mail.add_x_header.*/mail.add_x_header = On/' "${FPMDIR}/usr/php/php.ini"
sed -i 's@.*mail.log.*@mail.log = /usr/local/apache/logs/phpmail.log@' "${FPMDIR}/usr/php/php.ini"

echo "include=${FPMDIR}/usr/etc/php-fpm.d/users/*.conf" > "${FPMDIR}/usr/etc/php-fpm.d/users.conf"
echo "include=${FPMDIR}/usr/etc/php-fpm.d/*.conf" > "${FPMDIR}/usr/etc/php-fpm.conf"

cat > "${FPMDIR}/usr/etc/php-fpm.d/cwpsvc.conf" <<EOF
[cwpsvc]
listen = ${FPMDIR}/usr/var/sockets/cwpsvc.sock
listen.owner = cwpsvc
listen.group = cwpsvc
listen.mode = 0640
user = cwpsvc
group = cwpsvc
pm = ondemand
pm.max_children = 25
pm.process_idle_timeout = 15s
request_terminate_timeout = 0
EOF

# --- Systemd service ---
cp sapi/fpm/php-fpm.service "/usr/lib/systemd/system/php-fpm${PHPMAJOR}.service"
sed -i "s|\${exec_prefix}|${FPMDIR}/usr|g" "/usr/lib/systemd/system/php-fpm${PHPMAJOR}.service"
sed -i "s|\${prefix}|${FPMDIR}/usr|g" "/usr/lib/systemd/system/php-fpm${PHPMAJOR}.service"

systemctl daemon-reload
systemctl enable "php-fpm${PHPMAJOR}"

# --- Loading Apache FPM module if not already present ---
if [ ! -e "/usr/local/apache/conf.d/php-fpm.conf" ]; then
cat > /usr/local/apache/conf.d/php-fpm.conf <<EOF
<IfModule !proxy_fcgi_module>
    LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
</IfModule>
EOF
fi

# --- External modules (imagick, redis, imap, etc.) ---
if [ -e "${CONFBASE}/php${PHPMAJOR}_external.conf" ]; then
    bash "${CONFBASE}/php${PHPMAJOR}_external.conf" || true
fi

# --- Monitor integration ---
if [ -d "/etc/monit.d" ]; then
  if [ ! -e "/etc/monit.d/php-fpm${PHPMAJOR}" ]; then
    if [ -e "/usr/local/cwpsrv/htdocs/resources/conf/monit.d/php-fpm${PHPMAJOR}" ]; then
      cp "/usr/local/cwpsrv/htdocs/resources/conf/monit.d/php-fpm${PHPMAJOR}" /etc/monit.d/ 2>/dev/null || true
      monit reload || true
    fi
  fi
fi

systemctl restart "php-fpm${PHPMAJOR}"

# --- CSF pignore ---
if [ -e "/etc/csf/csf.pignore" ]; then

    # PHP-FPM + PHP binary
    if ! grep -q "${FPMDIR}/usr/sbin/php-fpm" /etc/csf/csf.pignore; then
        echo "exe:${FPMDIR}/usr/sbin/php-fpm" >> /etc/csf/csf.pignore
    fi

    if ! grep -q "${FPMDIR}/usr/bin/php" /etc/csf/csf.pignore; then
        echo "exe:${FPMDIR}/usr/bin/php" >> /etc/csf/csf.pignore
    fi

    # memcached daemon
    if command -v memcached >/dev/null 2>&1; then
        if ! grep -q "exe:/usr/bin/memcached" /etc/csf/csf.pignore; then
            echo "exe:/usr/bin/memcached" >> /etc/csf/csf.pignore
        fi
    fi

    # redis-server daemon
    if command -v redis-server >/dev/null 2>&1; then
        if ! grep -q "exe:/usr/bin/redis-server" /etc/csf/csf.pignore; then
            echo "exe:/usr/bin/redis-server" >> /etc/csf/csf.pignore
        fi
    fi

    # Restart CSF/LFD to apply changes
    csf -r
fi

rm -rf /usr/local/src/php-build
rm -rf /usr/local/src/build-dir

echo "PHP ${PHPVER} (php-fpm${PHPMAJOR}) build finished successfully."

It is for sample, you can modify it by your needs.

⚙️ Step 5 — Trigger the GUI Build Once

From the CWP Admin Panel:

PHP-FPM Selector → PHP 8.4 → Choose desired version of PHP → Build

CWP will:

  • generate the build configuration files

  • stop early because no packages exist (expected!)

  • but now the config files are ready

The GUI selector

(Image on the shared link)

This step must be done once so the GUI produces:

/usr/local/cwp/.conf/php-fpm_conf/php84.conf
/usr/local/cwp/.conf/php-fpm_conf/php84_pre.conf
/usr/local/cwp/.conf/php-fpm_conf/php84_external.conf

Our builder script depends on them.

⚙️ Step 6 — Build PHP 8.4 With Logging

Run the custom builder script manually:

bash /root/build-php-fpm84-el9.sh 2>&1 | tee /root/php84-build.log

This:

  • logs all output

  • compiles PHP 8.4.14

  • installs extensions - e.g. IonCube loader if it was selected

  • reloads FPM

  • integrates CSF pignore entries

    • exe:/usr/bin/redis-server

    • exe:/usr/bin/memcached

After the build:

Test PHP:

/opt/alt/php-fpm84/usr/bin/php -v
/opt/alt/php-fpm84/usr/sbin/php-fpm -t

Verify IonCube:

grep -Ri ioncube /opt/alt/php-fpm84/usr/php/php.d/

Verify Imagick:

/opt/alt/php-fpm84/usr/bin/php -r "print_r(Imagick::getVersion());"

⚙️ Repeat the Process for PHP 8.5

The steps are identical, except:

  • PHP version is different

  • ionCube loader uses the beta build
    ioncube_loaders_lin_x86-64_beta.tar.gz

Here is the IonCube documentation. The PHP 8.4 is fully supported, PHP 8.5 is Beta in the moment.


🎉 Result

After completing these steps you will have:

Fully working PHP 8.4 or 8.5
100% GUI-compatible (PHP Selector, vhost handler, extension manager)
Proper OpenSSL 3.x integration
All external PECL modules working
Systemd FPM services
Clean, isolated alt-PHP folders under /opt/alt
No conflict with AlmaLinux REMI PHP packages

And most importantly:

You can now run PHP 8.4 / 8.5 safely in production on CWP EL9.

I also fixed the PHP - OpenSSL compilation issue in AlmaLinux 9.x with PHP 8.3.28 version of the script. PHP now uses OpenSSL 3.x.

Checking the compiled PHP versions:

[root@vps ~]# /opt/alt/php-fpm84/usr/bin/php -v
PHP 8.4.14 (cli) (built: Dec  1 2025 22:53:34) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.14, Copyright (c) Zend Technologies
    with the ionCube PHP Loader v15.0.0, Copyright (c) 2002-2025, by ionCube Ltd.
    with Zend OPcache v8.4.14, Copyright (c), by Zend Technologies

[root@vps ~]# /opt/alt/php-fpm83/usr/bin/php -v
PHP 8.3.28 (cli) (built: Dec  1 2025 16:39:53) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.28, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.28, Copyright (c), by Zend Technologies
[root@vps ~]# 

Checking OpenSSL:

[root@vps ~]# /opt/alt/php-fpm84/usr/bin/php -i | grep -i "openssl"
Configure Command =>  './configure'  '--prefix=/opt/alt/php-fpm84/usr' '--with-config-file-path=/opt/alt/php-fpm84/usr/php' '--with-config-file-scan-dir=/opt/alt/php-fpm84/usr/php/php.d' '--with-zlib=/usr' '--enable-mbstring' '--with-zip' '--enable-bcmath' '--enable-pcntl' '--enable-ftp' '--enable-exif' '--enable-calendar' '--enable-sysvmsg' '--enable-sysvsem' '--enable-sysvshm' '--with-tidy' '--with-curl' '--with-iconv' '--with-gmp' '--with-pspell' '--enable-gd' '--with-jpeg' '--with-freetype' '--enable-gd-jis-conv' '--with-webp' '--with-avif' '--with-zlib-dir=/usr' '--with-xpm' '--with-openssl=/usr' '--with-pdo-mysql=mysqlnd' '--with-gettext=/usr' '--with-bz2=/usr' '--with-mysqli' '--enable-soap' '--enable-phar' '--with-xsl' '--with-kerberos' '--enable-posix' '--enable-sockets' '--with-external-pcre' '--with-libdir=lib64' '--with-mysql-sock=/var/lib/mysql/mysql.sock' '--enable-intl' '--with-imap' '--with-imap-ssl' '--enable-fpm' '--enable-opcache' '--with-password-argon2' 'PKG_CONFIG_PATH=/usr/lib64/pkgconfig' 'OPENSSL_CFLAGS=-I/usr/include' 'OPENSSL_LIBS=-L/usr/lib64'
SSL Version => OpenSSL/3.5.1
libSSH Version => libssh/0.10.4/openssl/zlib
openssl
OpenSSL support => enabled
OpenSSL Library Version => OpenSSL 3.5.1 1 Jul 2025
OpenSSL Header Version => OpenSSL 3.5.1 1 Jul 2025
Openssl default config => /etc/pki/tls/openssl.cnf
openssl.cafile => no value => no value
openssl.capath => no value => no value
OpenSSL support => enabled
[root@vps ~]# 

If you have any suggestions, please feel free to write to me.

Edited by TheHolbi
Correct line: Create these files based on the sample and content of 8.3.ini:

Create an account or sign in to comment

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.