A PHP fpm Health Check script
With the ascension of containerized applications it becomes more and more useful to have a php-fpm
This POSIX compliant sh script gets php-fpm status page using
cgi-fcgi tool, parses it's outcome and allows you to choose a metric which you want to check one, a ping mode is also available which only makes sure php-fpm is answering.
Previously at work we had Docker containers containing both
Nginx processes, while they were managed by another process being Supervisord or s6 overlay for instance.
One good example is this image from Ric Harvey
It works really well, but I wanted to achieve a few other things like using the official images and its release cycle, logs belonging to their own processes, not mixed, I didn't like to rely on Supervisord since I had bad experiences in the past with it, and other things related to the "Docker way", I'm not saying it's perfect but I wanted some of those things.
Now comes the
php-fpm healthcheck part, while having in place a healthcheck which requested an url in the application asking if it was alive, it was indirectly testing the whole chain,
Nginx -> php-fpm -> application, and now I had the chance to test still the whole chain via nginx but also monitor how busy and stable is
php-fpm, if you check its
/status page it has quite some useful information, so why not monitor on it? For instance you could make a container unhealthy after a certain amount of requests, or if the queue is too long and even slow requests, and that's what this script tries to achieve!
Good news is that you can still do it even using the mixed container approach, but I wanted to take a time to explain why I came to do it like this now! The advantage in my opinion is that having separate containers you have a better grasp on where the problem is laying and you can restart only what's failing, not the whole, also avoiding Supervisord to restart it for you since you are already behind a container orchestration tool.
Enable php-fpm status page
On you php-fpm pool configuration add:
pm.status_path = /status
For instance on the official php image you can alter the file
The script is POSIX sh but also uses some tools from your operating system, being:
In case you're using alpine you only need to make sure you have installed
wget -O /usr/local/bin/php-fpm-healthcheck \ https://raw.githubusercontent.com/renatomefi/php-fpm-healthcheck/master/php-fpm-healthcheck \ && chmod +x /usr/local/bin/php-fpm-healthcheck
wget -O $(which php-fpm-healthcheck) \ https://raw.githubusercontent.com/renatomefi/php-fpm-healthcheck/master/php-fpm-healthcheck \ && chmod +x $(which php-fpm-healthcheck)
If you're aiming only to make sure php-fpm is alive and answering to requests you can:
$ php-fpm-healthcheck $ echo $? 0
verbose to see php-fpm status output:
$ php-fpm-healthcheck -v Trying to connect to php-fpm via: localhost:9000 php-fpm status output: pool: www process manager: dynamic start time: 11/Sep/2018:10:47:06 +0000 start since: 436 accepted conn: 1 listen queue: 0 max listen queue: 0 listen queue len: 0 idle processes: 1 active processes: 1 total processes: 2 max active processes: 1 max children reached: 0 slow requests: 0 $ echo $? 0
Let's say you want to fail our healthcheck after your fpm has handled more than
$ php-fpm-healthcheck --accepted-conn=3000 $ echo $? 0
And you can also check if you have more than
10 processes in the queue:
$ php-fpm-healthcheck --accepted-conn=3000 --listen-queue-len=10 $ echo $? 0
How a failing metric looks like
$ php-fpm-healthcheck --accepted-conn=1 'accepted conn' value '6' is greater than expected '1' $ echo $? 1
Connection via socket or another host
You can simply specify
FCGI_CONNECT variable with your connection uri:
$ FCGI_CONNECT=/var/run/php-fpm.sock php-fpm-healthcheck $ echo $? 0
More and more people are looking for health checks on kubernetes for php-fpm, here is an example of livenessProbe and readinessProbe:
# PodSpec: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#podspec-v1-core spec: containers: - name: "php-fpm" livenessProbe: exec: command: - php-fpm-healthcheck - --listen-queue-len=10 # fails if there are more than 10 processes waiting in the fpm queue - --accepted-conn=5000 # fails after fpm has served more than 5k requests, this will force the pod to reset, use with caution initialDelaySeconds: 0 periodSeconds: 10
# PodSpec: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#podspec-v1-core spec: containers: - name: "php-fpm" readinessProbe: exec: command: - php-fpm-healthcheck # a simple ping since this means it's ready to handle traffic initialDelaySeconds: 1 periodSeconds: 5
Why POSIX sh
Most of the containers contain limited software installed, using POSIX sh aims to be compatible with most of the OS images around.
Made with love by Renato Mefi
Distributed under MIT License