renatomefi / php-fpm-healthcheck Goto Github PK
View Code? Open in Web Editor NEWA POSIX compliant sh script to healthcheck PHP fpm status, can be used only for pinging or check for specific metrics
License: MIT License
A POSIX compliant sh script to healthcheck PHP fpm status, can be used only for pinging or check for specific metrics
License: MIT License
Installed as
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
result is:
# php-fpm-healthcheck
/usr/local/bin/php-fpm-healthcheck: 36: set: Illegal option -o pipefail
# php-fpm-healthcheck -v
/usr/local/bin/php-fpm-healthcheck: 36: set: Illegal option -o pipefail
If you have more than 8kb exported in your environment, they'll will be send by default towards the fcgi call to php fpm, this makes fpm close the connection causing either exit status code of 104
or 253
depending on when it happens in the internal calls.
Send only the needed variables towards php fpm
It could be possible by replacing the fcgi call with:
env -i cgi-fcgi...
env -i
meant to clear the current variables in the session
An strace would look like:
strace cgi-fcgi -bind -connect /var/run/php-fpm.sock
execve("/usr/bin/cgi-fcgi", ["cgi-fcgi", "-bind", "-connect", "/var/run/php-fpm.sock"], 0x7ffed28a0c08 /* 191 vars */) = 0
arch_prctl(ARCH_SET_FS, 0x7f1e94c06b88) = 0
set_tid_address(0x7f1e94c06bc0) = 16859
open("/etc/ld-musl-x86_64.path", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib/libfcgi.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/local/lib/libfcgi.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/libfcgi.so.0", O_RDONLY|O_CLOEXEC) = 3
fcntl(3, F_SETFD, FD_CLOEXEC) = 0
fstat(3, {st_mode=S_IFREG|0755, st_size=38488, ...}) = 0
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240+\0\0\0\0\0\0"..., 960) = 960
mmap(NULL, 2138112, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x7f1e94771000
mmap(0x7f1e94979000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x8000) = 0x7f1e94979000
close(3) = 0
mprotect(0x7f1e94979000, 4096, PROT_READ) = 0
mprotect(0x7f1e94c03000, 4096, PROT_READ) = 0
mprotect(0x561b68d55000, 4096, PROT_READ) = 0
rt_sigaction(SIGPIPE, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2], NULL, 8) = 0
rt_sigaction(SIGPIPE, {sa_handler=0x7f1e9477694e, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f1e949c10ea}, NULL, 8) = 0
rt_sigaction(SIGUSR1, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGUSR1, {sa_handler=0x7f1e94776af8, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f1e949c10ea}, NULL, 8) = 0
socket(AF_UNIX, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/php-fpm.sock"}, 23) = 0
write(3, "\1\1\0\1\0\10\0\0\0\1\0\0\0\0\0\0", 16) = 16
brk(NULL) = 0x561b693c7000
brk(0x561b693ca000) = 0x561b693ca000
write(3, "\1\4\0\1\37\370\0\0008\16FEEDBACK_COLLECTOR_HTT"..., 8192) = 8192
write(3, "\1\4\0\1\1\245\3\0SERVICE_PORT8081\30\3BOTKIT"..., 440) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=16859, si_uid=0} ---
rt_sigreturn({mask=[]}) = -1 EPIPE (Broken pipe)
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
select(4, [3], [3], NULL, NULL) = 2 (in [3], out [3])
read(3, "", 8192) = 0
shutdown(3, SHUT_WR) = 0
poll([{fd=3, events=POLLIN}], 1, 2000) = 1 ([{fd=3, revents=POLLIN|POLLHUP}])
read(3, "", 1024) = 0
close(3) = 0
exit_group(-3) = ?
+++ exited with 253 +++
/opt/search-api # strace cgi-fcgi -bind -connect /var/run/php-fpm.sock
execve("/usr/bin/cgi-fcgi", ["cgi-fcgi", "-bind", "-connect", "/var/run/php-fpm.sock"], 0x7ffdc1d0c428 /* 191 vars */) = 0
arch_prctl(ARCH_SET_FS, 0x7feba6734b88) = 0
set_tid_address(0x7feba6734bc0) = 16862
open("/etc/ld-musl-x86_64.path", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib/libfcgi.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/local/lib/libfcgi.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/libfcgi.so.0", O_RDONLY|O_CLOEXEC) = 3
fcntl(3, F_SETFD, FD_CLOEXEC) = 0
fstat(3, {st_mode=S_IFREG|0755, st_size=38488, ...}) = 0
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240+\0\0\0\0\0\0"..., 960) = 960
mmap(NULL, 2138112, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x7feba629f000
mmap(0x7feba64a7000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x8000) = 0x7feba64a7000
close(3) = 0
mprotect(0x7feba64a7000, 4096, PROT_READ) = 0
mprotect(0x7feba6731000, 4096, PROT_READ) = 0
mprotect(0x55cb34157000, 4096, PROT_READ) = 0
rt_sigaction(SIGPIPE, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2], NULL, 8) = 0
rt_sigaction(SIGPIPE, {sa_handler=0x7feba62a494e, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7feba64ef0ea}, NULL, 8) = 0
rt_sigaction(SIGUSR1, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGUSR1, {sa_handler=0x7feba62a4af8, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7feba64ef0ea}, NULL, 8) = 0
socket(AF_UNIX, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/php-fpm.sock"}, 23) = 0
write(3, "\1\1\0\1\0\10\0\0\0\1\0\0\0\0\0\0", 16) = 16
brk(NULL) = 0x55cb34ba0000
brk(0x55cb34ba3000) = 0x55cb34ba3000
write(3, "\1\4\0\1\37\370\0\0008\16FEEDBACK_COLLECTOR_HTT"..., 8192) = 8192
write(3, "\1\4\0\1\1\245\3\0SERVICE_PORT8081\30\3BOTKIT"..., 440) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=16862, si_uid=0} ---
rt_sigreturn({mask=[]}) = -1 EPIPE (Broken pipe)
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
select(4, [3], [3], NULL, NULL) = 2 (in [3], out [3])
read(3, "", 8192) = 0
shutdown(3, SHUT_WR) = 0
poll([{fd=3, events=POLLIN}], 1, 2000) = 1 ([{fd=3, revents=POLLIN|POLLHUP}])
read(3, "", 1024) = 0
close(3) = 0
exit_group(-3) = ?
+++ exited with 253 +++
When php-fpm stuck and didn't respond, php-fpm-healthckeck can't handle this, and timeouts to connect to the port.
root@deployment-php-5bddfd7964-7ctmf:/app# php-fpm-healthcheck -v Trying to connect to php-fpm via: localhost:9000/status ^C
So, php-fpm-healthcheck doesn't return fail status in a reasonable time.
Since K8s doesn't handle timeouts healthcheck, it doesn't work. Because Kubernetes remove the pod from service only when heathcheck returning fail event.
Readiness probe errored: rpc error: code = DeadlineExceeded desc = context deadline exceeded
Readiness probe errored, but pod didn't remove from services.
Is there any way to setup a reasonable timeout to connect to the PHP port for the php-fpm-healthcheck?
I use this script on centos, but failed.
error output like this:
[root@root /] echo "any text" | tail +5
[root@root /] tail: cannot open `+5' for reading: No such file or directory
or
[root@root /] FCGI_CONNECT=/dev/shm/php-fpm.socket FCGI_STATUS_PATH=/fpm/status ./php-fpm-healthcheck.sh --verbose
[root@root /] Trying to connect to php-fpm via: /dev/shm/php7-fpm.socket/fpm/status
[root@root /] tail: cannot open `+5' for reading: No such file or directory
Add a new Dockerfile for buster:
Add it to the Makefile in /test/Dockerfile-buster
Add to the circleci build
https://github.com/renatomefi/php-fpm-healthcheck#livenessprobe
--listen-queue=10 # fails if there are more than 10 processes waiting in the fpm queue
In this case, pod should be scaleUp, rather than reset?
--accepted-conn=5000 # fails after fpm has served more than 5k requests, this will force the pod to reset, use with caution
In this case, pod don't have to reset., Why do you configure it this way?
So how do you configure it in production?
Test when a metrics has fail to success
--accepted-conn
since it increases on every time a request is served by php-fpmHi,
When command cgi-fcgi fails to connect to a php-fpm instance the script exists.
Shouldn't there be an implementation for the following exit codes as described in the script header:
2,9,111 - Couldn't connect to PHP fpm, is it running?
For example:
if test "$FPM_STATUS" = "Could not connect to $1"; then
>&2 printf "Failed to connect to php-fpm instace via $1. Is it running? \\n";
exit 2;
fi;
# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/
Run php-fpm-healthcheck --listen-queue=10
And you will get this error :
/usr/local/bin/php-fpm-healthcheck: 78: test: Illegal number:
Currently the test matrix only tests alpine images, would be good to be able to test strecht
for instance.
mark
feature to separate those distro specificdocker.sh
has to adhere to the marks, build and run this matrix, maybe the make file could inform which Dockerfile
to look atI found this lovely project, but I am confused on what FastCGI really is and why it's a dependency for checking the status of PHP-FPM.
What I am attempting to do is:
Here is how I am starting my services:
graph TD;
A[S6 Overlay] --> B[PHP-FPM];
B[PHP-FPM] --> C[NGINX];
The folks over at S6 Overlay have been very helpful and pointed me in the right direction for the script side of things: just-containers/s6-overlay#482
Now I just need to get that "definition of healthy" with an exit code of 0.
That's when I found this project and saw the dependency for FastCGI.
I googled "Install FastCGI Ubuntu 22.04" and this was the first result: https://installati.one/ubuntu/22.04/fcgiwrap/
Even with having fcgiwrap
installed, I am getting this error:
Error:
Make sure fcgi is installed (i.e. apk add --no-cache fcgi). Aborting.
I have all my source code available on GitHub: https://github.com/serversideup/docker-php/tree/feature/add-readiness/src
Note: The fpm-nginx
image is built from the fpm
image (so you understand the image dependency and what's included).
Thanks for all your hard work! This project is incredible!! 🤩
Support all php-fpm metrics which can be seen via: php-fpm-healthcheck -v
Of course ignoring non numeric/measurable data
Based on https://serverfault.com/a/355546 the listen queue len value is decreased on connection. So initially the value might be for example 128. When I run the check via php-fpm-healthcheck --listen-queue-len=10
it fails with 'listen queue len' value '128' is greater than expected '10'
. In this case this should only fail if the value of listen queue len is lower than 10.
Currently our master
branch has a CircleCI failed run.
Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
exit status 128
CircleCI received exit code 128
@renatomefi will we continue using CircleCI?
Currently we're only testing when sockets are running on localhost:9000
, create a test where we connect via socket for instance
How to change FCGI connection is described here: https://github.com/renatomefi/php-fpm-healthcheck#connection-via-socket-or-another-host
The current docker image would have to be either altered in runtime or build a new one with new php-fpm pool configuration to create a socket
Document on how to contribute to this project
Basically run make qa
Docker has its internal healthcheck https://docs.docker.com/engine/reference/builder/#healthcheck
Would be good to document and test it
It might require to split the test process since you probably have to use docker inspect
to get the current healthcheck status
Hi guys,
We had to switch from alpine to debian linux (unfortunately). Since then, the healthcheck script is no longer running. I only receive the answer: Make sure fcgi is installed (i.e. apk add --no-cache fcgi). Aborting.
I'm running the script with: FCGI_CONNECT=/var/run/socket/php5-fpm.sock php-fpm-healthcheck
Could we find out the reason for it?
Is there a way to disable access logs for path /status in php-fpm?
- 21/Oct/2019:19:58:00 +0000 "GET /status" 200
I run this in Kubernetes and have separate containers for php-fpm and nginx. I don's see the logs from the line above in nginx logs, just in php-fpm logs.
Hi all,
When trying to use this script with ubuntu I'm seeing an ever-growing number of active cgi-fcgi instances and the health checks aren't terminating. Any idea why?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.