Configure PHP-FPM on CentOS 7/RHEL and Oracle Linux

Configure PHP-FPM on CentOS 7/RHEL and Oracle Linux

After installing php, to make it work with apache we have 2 options: either installing the Apache Module or using php-fpm.

This article covers how to configure php-fpm to work with Apache

Prerequisite:

  1. Apache installed.
  2. Vhost configured.
  3. You must first install php which is covered in this article.

Creating php.ini file

Navigate to your vhost directory copy the original php.ini file, we will remove all the comments so that it is easier to edit.

cd /etc/httpd/conf/sites/example.com/
cp /etc/php.ini .
cat php.ini | sed -E 's/^\;.*//g' | sed '/^$/d' > example.com-php.ini

Next we should add the cgi.fix_pathinfo=0 directive to the php.ini file.

echo "cgi.fix_pathinfo=0" >> example.com-php.ini

Creating the conf file

Now we will create the www.conf for the php-fpm to use for configuration.

We will copy the existing www.conf remove the comments and make a few modifications/

cat /etc/php-fpm.d/www.conf | sed -E 's/^\;.*//g' | sed '/^$/d' > php-example.com.conf

Then edit the conf to look as follow:

;;;;;;;;;;;;;;;;;;
; Global Options ;
;;;;;;;;;;;;;;;;;;
[global]
pid = /var/run/php81-fpm/php-fpm-example.com.pid
error_log = /home/logs/apache/example.com/php-fpm_error.log

[example.com]
listen = 9001
listen.backlog = 128

listen.owner = example.com
listen.group = example.com
listen.mode = 0666
user = example.com
group = example.com
pm = ondemand
pm.max_children = 16
pm.process_idle_timeout = 10s
pm.max_requests = 5000
pm.status_path = /example.com/fpm-status
ping.path = /example.com/fpm-ping

request_terminate_timeout = 60s
request_slowlog_timeout = 45s
slowlog = /home/logs/apache/example.com/php_slowlog.log

catch_workers_output = yes
env[TMPDIR] = /home/websites/example.com/tmp
env[TMP_DIR] = /home/websites/example.com/tmp

We should create the user which will be managing the php-fpm service. We will creating the user example.com which has been defined in our conf above.

useradd example.com

Create the pid directory:

mkdir -p /var/run/php81-fpm/

Next we will be creating a script which we will use to start and stop the php-fpm service for the website example.com

vim /etc/init.d/php-fpm-example.com

Paste the following:

#! /bin/sh

#PHP-FPM binary to be used
php_fpm_BIN=/usr/sbin/php-fpm


#Create /var/run/php81-fpm/ directory as on RHEL 7 /var/run is a tmpfs volatile mount
[ -d /var/run/php81-fpm/ ] || install -m 755 -o root -g root -d /var/run/php81-fpm/

php_fpm_CONF=/etc/httpd/conf/sites/example.com/php-example.com.conf
php_fpm_PID=/var/run/php81-fpm/php-fpm-example.com.pid
php_fpm_INI=/etc/httpd/conf/sites/example.com/example.com-php.ini


php_opts="--fpm-config $php_fpm_CONF -c $php_fpm_INI"

check_config () {
        return=0
        if [ "x$fpmSlowLog" != "x" ]; then
                if [ ! -f "$fpmSlowLog" ]; then
                        touch $fpmSlowLog > /dev/null 2>&1
                fi
        fi

        if [ "x$fpmErrorLog" != "x" ]; then
                if [ ! -f "$fpmErrorLog" ]; then
                        ( touch $fpmErrorLog > /dev/null 2>&1 && chown $fpmUser:$fpmGroup $fpmErrorLog )
                fi
        fi
}

wait_for_pid () {
        try=0

        while test $try -lt 35 ; do

                case "$1" in
                        'created')
                        if [ -f "$2" ] ; then
                                try=''
                                break
                        fi
                        ;;

                        'removed')
                        if [ ! -f "$2" ] ; then
                                try=''
                                break
                        fi
                        ;;
                esac

                echo -n .
                try=`expr $try + 1`
                sleep 1

        done

}

case "$1" in
        start|start-nocheck)
                if [ "$1" == "start" ]; then
                        check_config || exit 1
                fi
                echo -n "Starting php-fpm "

                $php_fpm_BIN $php_opts

                if [ "$?" != 0 ] ; then
                        echo " failed"
                        exit 1
                fi

                wait_for_pid created $php_fpm_PID

                if [ -n "$try" ] ; then
                        echo " failed"
                        exit 1
                else
                        echo " done"
                fi
        ;;
        stop)
                check_config || exit 1
                echo -n "Gracefully shutting down php-fpm "

                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi

                kill -QUIT `cat $php_fpm_PID`

                wait_for_pid removed $php_fpm_PID

                if [ -n "$try" ] ; then
                        echo " failed. Use force-quit"
                        exit 1
                else
                        echo " done"
                fi
        ;;
        restart)
                $0 stop
                $0 start-nocheck
        ;;
        reload)
                check_config || exit 1
                echo -n "Reload service php-fpm "

                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi

                kill -USR2 `cat $php_fpm_PID`

                echo " done"
        ;;
        *)
                echo "Usage: $0 {start|stop|restart|reload}"
                exit 1
        ;;

esac

Give the proper permission to the script:

chmod +x /etc/init.d/php-fpm-example.com

Next configure the service to be managed by systemd.

vim /usr/lib/systemd/system/php-fpm-example.com.service

And paste the following:

[Unit]
Description=PHP-FPM service for example.com website

[Service]
User=root
Group=root
Type=notify
PIDFile=/var/run/php81-fpm/php-fpm-example.com.pid
ExecStart=/etc/init.d/php-fpm-example.com start
ExecStop=/etc/init.d/php-fpm-example.com stop
Restart=always
StartLimitInterval=5
StartLimitBurst=3
Environment=SYSTEMD_LOG_LEVEL=debug

[Install]
WantedBy=multi-user.target

This systemd script was tested on Oracle Linux with SELINUX disabled.

Now to enable the service at boot run the following command:

systemctl enable php-fpm-example.com

Finally add the wollowing line to your vhost:

ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://localhost:9001/home/websites/example.com/www retry=0 timeout=1800

Then reload the httpd service.