How to get domains PHP version in CLI?

I’m trying to write a script, which will create a php-fpm watcher for Monit. For some reason one of the sites keeps crashing, and I want to setup watchers for each domain. I have the basic setup in Monit, but its not picking the site crash up as the .pid file exists, but the .sock doesn’t for the domain:

# PHP-FPM 7.4
check file php7.4-fpm-pidfile with path /var/run/php/php7.4-fpm.pid
    if does not exist then restart
    start program = "/usr/sbin/service php7.4-fpm start" with timeout 60 seconds
    stop program  = "/usr/sbin/service php7.4-fpm stop"

    # PHP-FPM 7.3
check file php7.3-fpm-pidfile with path /var/run/php/php7.3-fpm.pid
    if does not exist then restart
    start program = "/usr/sbin/service php7.3-fpm start" with timeout 60 seconds
    stop program  = "/usr/sbin/service php7.3-fpm stop"

# PHP-FPM 8.1
check file php8.1-fpm-pidfile with path /var/run/php/php8.1-fpm.pid
    if does not exist then restart
    start program = "/usr/sbin/service php8.1-fpm start" with timeout 60 seconds
    stop program  = "/usr/sbin/service php8.1-fpm stop"


# PHP-FPM 8.2
check file php8.2-fpm-pidfile with path /var/run/php/php8.2-fpm.pid
    if does not exist then restart
    start program = "/usr/sbin/service php8.2-fpm start" with timeout 60 seconds
    stop program  = "/usr/sbin/service php8.2-fpm stop"

So I’m trying to write a script, which will create a listener for each of the domains that users PHP. So far I have:

#!/bin/bash
source /etc/hestiacp/hestia.conf
source $HESTIA/func/main.sh

for user in $($BIN/v-list-users plain | cut -f1 ); do
    echo "Doing user: $user"
    for domain in $(v-list-web-domains $user | awk 'NR > 2 {print $1}' ); do
        echo "Doing domain: $domain"
    done
done

I’ve stumbled at the point of working out which PHP version the domain uses (if any), so I can create the correct listener?

(if anyone has a better idea of monitoring the different sites with PHP, I’m also open to that :)). I’m still trying to find why PHP keeps crashing (seemingly just for this site), but in the mean time I need to make sure its up

Thanks

Andy

You should be able to get php version via the backend template.

If it is default it is always het server default version

Something like this could work:

#!/bin/bash
source /etc/hestiacp/hestia.conf
source "$HESTIA/func/main.sh"

for user in $("$BIN/v-list-users" plain | cut -f1); do
        echo "Doing user: $user"
        for domain in $("$BIN/v-list-web-domains" "$user" plain | awk '{print $1}'); do
                echo "Doing domain: $domain"
                if [[ "$("$BIN/v-list-web-domain" "$user" "$domain" | grep BACKEND | awk '{print $2}')" != "no-php" ]]; then
                        sock_used="$(grep -Eo '\/.+\.sock' "/home/${user}/conf/web/${domain}/nginx.conf" | head -n1)"
                        echo "Domain $domain uses sock $sock_used"
                else
                        echo "Domain $domain does not use php-fpm"
                fi
        done
        echo ""
done

Amazing @sahsanu - works like a charm :slight_smile: Now I just need to figure out the syntax to put in the Monit checker config for PHP. I thought this would work:

check file php7.3-fpm-pidfile with path /var/run/php/php7.3-fpm.pid
    start program = "/usr/sbin/service php7.3-fpm start" with timeout 60 seconds
    stop program  = "/usr/sbin/service php7.3-fpm stop"
    if does not exist then restart

 check file php7.3-fpm-cadmap.co.uk-socket with path /run/php/php7.3-fpm-cadmap.co.uk.sock
     if failed unixsocket /run/php/php7.3-fpm-cadmap.co.uk.sock then restart
     depends on php7.3-fpm-pidfile

But I get:

/etc/monit/conf-enabled/php-fpm:16: syntax error ‘unixsocket’

This is Monit version 5.31.0, which AFAIK supports “unixsocket” … so a bit baffling?

I’m glad it works but I don’t use monit so I’m sorry but I can’t help you here.

Anyway, I’ve seen answers saying to add something like

if failed unixsocket /run/php/php7.3-fpm-cadmap.co.uk.sock then restart

inside the check file pid part but as I said, I don’t use monit so I’ve no idea.

Thanks. I did actually try that before, and got the same error:

check file php7.3-fpm-pidfile with path /var/run/php/php7.3-fpm.pid
    start program = "/usr/sbin/service php7.3-fpm start" with timeout 60 seconds
    stop program  = "/usr/sbin/service php7.3-fpm stop"
    if does not exist then restart
    if failed unixsocket /run/php/php7.3-fpm-cadmap.co.uk.sock then restart

Won’t restart, and gives:

/etc/monit/conf-enabled/php-fpm:14: syntax error ‘unixsocket’

Maybe I’ll take another look tomorrow, with fresh eyes :slight_smile:

Cheers

Andy

1 Like

Ok, here is my script :slight_smile:

#!/bin/bash

source /etc/hestiacp/hestia.conf
source "$HESTIA/func/main.sh"

# Use an associative array to store the pools
declare -A pools

# List of supported PHP versions
php_versions=("5.6" "7.0" "7.1" "7.2" "7.3" "7.4" "8.0" "8.1" "8.2")

for user in $("$BIN/v-list-users" plain | cut -f1); do
    echo "Doing user: $user"
    for domain in $("$BIN/v-list-web-domains" "$user" plain | awk '{print $1}'); do
        echo "Doing domain: $domain"
        if [[ "$("$BIN/v-list-web-domain" "$user" "$domain" | grep BACKEND | awk '{print $2}')" != "no-php" ]]; then
            sock_used="$(grep -Eo '\/.+\.sock' "/home/${user}/conf/web/${domain}/nginx.conf" | head -n1)"
            echo "Domain $domain uses sock $sock_used"

            matched=false
            for version in "${php_versions[@]}"; do
                if [[ $sock_used =~ "php${version}-fpm" ]]; then
                    echo "Domain $domain uses php-fpm $version"
                    # Append the socket to the corresponding string
                    pools["$version"]="${pools["$version"]}${sock_used};"
                    matched=true
                    break
                fi
            done

            if [ "$matched" = false ]; then
                echo "Domain $domain uses unknown php-fpm version"
            fi
        else
            echo "Domain $domain does not use php-fpm"
        fi
    done
    echo ""
done


echo "" > /etc/monit/conf-enabled/php-fpm
# Now we can easily process each PHP version and its corresponding pools
for version in "${php_versions[@]}"; do
    if [ -n "${pools["$version"]}" ]; then
        # Convert the delimited string back to an array
        IFS=';' read -ra sock_array <<< "${pools["$version"]}"

        #echo "pools_${version//./_}: ${sock_array[@]}"
        echo "check process php${version}-fpm-pidfile with path /var/run/php/php${version}-fpm.pid" >> /etc/monit/conf-enabled/php-fpm
        echo "    start program = \"/usr/sbin/service php${version}-fpm start\" with timeout 60 seconds" >> /etc/monit/conf-enabled/php-fpm
        echo "    stop program  = \"/usr/sbin/service php${version}-fpm stop\"" >> /etc/monit/conf-enabled/php-fpm
        echo "    if does not exist then restart" >> /etc/monit/conf-enabled/php-fpm
        for i in "${sock_array[@]}"; do
            echo "    if failed unixsocket $i then restart" >> /etc/monit/conf-enabled/php-fpm
        done

        # add a couple of line breaks
        echo "" >> /etc/monit/conf-enabled/php-fpm
        echo "" >> /etc/monit/conf-enabled/php-fpm
    fi
done

# make sure we reboot monit, otherwise it won't take effect
service monit restart

This will output a file in /etc/monit/conf-enabled/php-fpm for the PHP Versions, with all the .sock listeners

Also - the issue I had before, was because I was doing:

check file php....

But it should have been “process”:

check process php...

Someone on ServerFault helped me on that :slight_smile:

2 Likes

Well done :wink:

Thanks for sharing the script and the solution to monit issue.

2 Likes

A little update. The other script worked fine with nginx, but when you have Apache + nginx as the reverse proxy, then the .sock is set in apache2.conf, not nginx.conf. So this does the trick now:

#!/bin/bash

source /etc/hestiacp/hestia.conf
source "$HESTIA/func/main.sh"

# Use an associative array to store the pools
declare -A pools

# List of supported PHP versions
php_versions=("5.6" "7.0" "7.1" "7.2" "7.3" "7.4" "8.0" "8.1" "8.2")

for user in $("$BIN/v-list-users" plain | cut -f1); do
    echo "Doing user: $user"
    for domain in $("$BIN/v-list-web-domains" "$user" plain | awk '{print $1}'); do
        echo "Doing domain: $domain"
        if [[ "$("$BIN/v-list-web-domain" "$user" "$domain" | grep BACKEND | awk '{print $2}')" != "no-php" ]]; then
            sock_used="$(grep -Eo '\/.+\.sock' "/home/${user}/conf/web/${domain}/nginx.conf" | head -n1)"

            # if no value for sock_used, then lets try and get it from the Apache confiugration
            if [ -z "$sock_used" ]; then
                sock_used="$(grep -Eo '\/.+\.sock' "/home/${user}/conf/web/${domain}/apache2.conf" | head -n1)"
            fi

            echo "Domain $domain uses sock $sock_used"

            matched=false
            for version in "${php_versions[@]}"; do
                if [[ $sock_used =~ "php${version}-fpm" ]]; then
                    echo "Domain $domain uses php-fpm $version"
                    # Append the socket to the corresponding string
                    pools["$version"]="${pools["$version"]}${sock_used};"
                    matched=true
                    break
                fi
            done

            if [ "$matched" = false ]; then
                echo "Domain $domain uses unknown php-fpm version"
            fi
        else
            echo "Domain $domain does not use php-fpm"
        fi
    done
    echo ""
done


echo "" > /etc/monit/conf-enabled/php-fpm
# Now we can easily process each PHP version and its corresponding pools
for version in "${php_versions[@]}"; do
    if [ -n "${pools["$version"]}" ]; then
        # Convert the delimited string back to an array
        IFS=';' read -ra sock_array <<< "${pools["$version"]}"

        #echo "pools_${version//./_}: ${sock_array[@]}"
        echo "check process php${version}-fpm-pidfile with path /var/run/php/php${version}-fpm.pid" >> /etc/monit/conf-enabled/php-fpm
        echo "    start program = \"/usr/sbin/service php${version}-fpm start\" with timeout 60 seconds" >> /etc/monit/conf-enabled/php-fpm
        echo "    stop program  = \"/usr/sbin/service php${version}-fpm stop\"" >> /etc/monit/conf-enabled/php-fpm
        echo "    if does not exist then restart" >> /etc/monit/conf-enabled/php-fpm
        for i in "${sock_array[@]}"; do
            echo "    if failed unixsocket $i then restart" >> /etc/monit/conf-enabled/php-fpm
        done

        # add a couple of line breaks
        echo "" >> /etc/monit/conf-enabled/php-fpm
        echo "" >> /etc/monit/conf-enabled/php-fpm
    fi
done

# make sure we reboot monit, otherwise it won't take effect
service monit restart
3 Likes