How to restart php-fpm inside a docker container? - php

I'm using docker and my container is build over php:5.6-fpm image from php official repo.
Is it somehow possible to restart/reload php-fpm from inside a container?

php-fpm is a process manager which supports the USER2 signal, which is used to reload the config file.
From inside the container:
kill -USR2 1
Outside:
docker exec -it <mycontainer> kill -USR2 1
Complete example:
docker run -d --name test123 php:7.1-fpm-alpine
docker exec -it test123 ps aux
docker exec -it test123 kill -USR2 1
docker exec -it test123 ps aux

You don't have to go inside the container
on your host
ps -ef|grep fpm // find master pid
kill -USR2 <master_pid>

This works for me:
If the command fpm restart fails run this inside the Docker container -> www#:
root#...:/var/www# **ps -ef|grep fpm**
www-data 160 1 0 10:02 ? 00:00:00 php-fpm: pool www
www-data 161 1 0 10:02 ? 00:00:00 php-fpm: pool www
root 1111 170 0 10:04 pts/0 00:00:00 grep --color=auto fpm
root#...:/var/www# **kill -USR2 170**
root#...:/home/user/Docker# **docker-compose stop**
Stopping docker_nginx_1 ... done
Stopping docker_oracle_1 ... done
root#...:/home/user/Docker# **docker-compose up -d**
Starting docker_oracle_1 ... done
Starting docker_nginx_1 ... done
root#...:/home/user/Docker# **docker-compose exec oracle bash**
root#...:/var/www# **/etc/init.d/php7.2-fpm restart**
* Restarting PHP 7.2 FastCGI Process Manager php-fpm7.2 **[ OK ]**

docker container kill --signal USR2 php_container_name
Details: https://docs.docker.com/engine/reference/commandline/container_kill/

You can also just restart the container..
sudo docker restart <container>

Related

How to build a docker image on top of Jelastic jelastic/nginxphp?

For local development I try to build a docker image on top of jelastic/nginxphp as suggested in https://docs.jelastic.com/building-custom-container/ . Unfortunately I can not see any server (php-fpm or nginx) once I start the image.
docker run -p 8080:80 jelastic/nginxphp:1.14.2-php-7.2.9
➜ ~ curl 127.0.0.1:8080
curl: (52) Empty reply from server
I can see that systemd gets started, but I do not see php-fpm or nginx.
➜ ~ docker exec 55a454cf01ad ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 191276 10172 ? Ssl 07:58 0:00 /usr/bin/qemu-x86_64 /usr/lib/systemd/systemd
root 9 0.0 0.0 200788 10408 ? Rl+ Nov25 0:00 /usr/bin/ps aux
I wonder how to build my app on top of this image. Is there any documentation or is there an example for jelastic/nginxphp?
Generally, the jelastic/nginxphp docker image is built in a quite different way from, for example, the Nginx repo from the Docker library - that's because it was designed to be launched on Virtuozzo DevOps platform and have the support of all the functionality and automatizations provided there.
If you run
'docker inspect jelastic/nginxphp:1.14.2-php-7.2.9', you can see
"Cmd": [
"/usr/lib/systemd/systemd"
],
To run the image locally, you need to override the CMD during launch
docker run -p 8080:80 jelastic/nginxphp:1.14.2-php-7.2.9 /usr/sbin/nginx '-g daemon off;'

Why PHP-FPM socket stops allowing connections from Docker after restart?

PHP-FPM is running locally on my Ubuntu 20.04 installation, configured to listen on a socket:
/etc/php/7.4/fpm/pool.d/www.conf:
[www]
user = www-data
group = www-data
listen = /run/php/php7.4-fpm.sock
listen.owner = www-data
listen.group = www-data
;listen.mode = 0660
;listen.acl_users =
;listen.acl_groups =
I can start a Docker container and communicate with PHP-FPM by sharing the socket file through a bind mount volume:
$ docker run --rm -it \
-v "/etc/passwd:/etc/passwd:ro" \
-v "/etc/group:/etc/group:ro" \
-v "/run/php/php7.4-fpm.sock:/run/php-fpm/www.sock" \
alpine:latest
/ # apk add --no-cache fcgi
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
(1/1) Installing fcgi (2.4.2-r0)
Executing busybox-1.31.1-r16.trigger
OK: 6 MiB in 15 packages
/ # ls -lah /run/php-fpm/www.sock
srw-rw---- 1 www-data www-data 0 Oct 30 21:25 /run/php-fpm/www.sock
/ # REQUEST_METHOD=GET SCRIPT_FILENAME=index.php cgi-fcgi -bind -connect /run/php-fpm/www.sock
Primary script unknownStatus: 404 Not Found
Content-type: text/html; charset=UTF-8
File not found.
Now if I restart PHP-FPM on the host while the container is still running:
$ sudo systemctl restart php7.4-fpm.service
$ sudo tail -n 6 /var/log/php7.4-fpm.log
[30-Oct-2020 18:25:36] NOTICE: systemd monitor interval set to 10000ms
[30-Oct-2020 18:28:47] NOTICE: Terminating ...
[30-Oct-2020 18:28:47] NOTICE: exiting, bye-bye!
[30-Oct-2020 18:28:47] NOTICE: fpm is running, pid 67860
[30-Oct-2020 18:28:47] NOTICE: ready to handle connections
[30-Oct-2020 18:28:47] NOTICE: systemd monitor interval set to 10000ms
I am no longer able to connect to the socket from the Docker container:
/ # REQUEST_METHOD=GET SCRIPT_FILENAME=index.php cgi-fcgi -bind -connect /run/php-fpm/www.sock
Could not connect to /run/php-fpm/www.sock
If the container is re-started, it works again.
So I imagine that the problem is related to how sockets shared in bind mounts work, but it could also be on PHP-FPM, I have no idea on how to "fix" this.

Starting supervisor programs as another user

I have a docker (php:7-fpm-alpine) container with supervisor installed. It is added to a default installation by:
RUN apk add nginx composer php7-fpm php7-session supervisor && \
... ... ...
cp supervisord.conf /etc/supervisor.d/conf.ini
Supervisor has its default config (didn't change it after installation), I have added my own config to append to it (supervisord.conf):
[program:php-fpm7]
command = /usr/sbin/php-fpm7 --nodaemonize --fpm-config /etc/php7/php-fpm.d/www.conf
autostart=true
autorestart=true
priority=5
stdout_logfile=/var/log/supervisor/php-fpm.log
stderr_logfile=/var/log/supervisor/php-fpm.error.log
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
priority=10
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx.error.log
Now the original issue I have is that my Laravel app can't write to storage folder. I could chmod 777 the folder recursively, and it works, but is not what I want.
So steps I took first is to chown -R nginx:nginx /var/www/* leaving permissions as is. This resolved nothing, still can't write.
Doing a ps aux revealed this:
PID USER TIME COMMAND
1 root 0:00 {supervisord} /usr/bin/python2 /usr/bin/supervisord --nodaemon --configuration /etc/supervisord.conf
8 root 0:00 {php-fpm7} php-fpm: master process (/etc/php7/php-fpm.d/www.conf)
9 root 0:00 nginx: master process /usr/sbin/nginx -g daemon off;
10 nginx 0:00 nginx: worker process
11 nginx 0:00 nginx: worker process
12 nginx 0:00 nginx: worker process
13 nginx 0:00 nginx: worker process
14 nginx 0:00 {php-fpm7} php-fpm: pool www
15 nginx 0:00 {php-fpm7} php-fpm: pool www
So php-fpm is running as nginx user (I've changed it's original config to replace user nobody to nginx). This did nothing good, as with this settings instead of nobody user, request returns 502 error.
Nginx master process is running as root, and worker processes as nginx.
This is a tad confusing as I am not sure which user is my web server using here? Root or nginx? Does it take the user from supervisor, nginx master or nginx worker?
I've tried changing supervisor to start as nginx user, but that fails as supervisor needs root access to create pid.
Reverting supervisor to root and adding user=nginx to [program:nginx] section made supervisor not start nginx at all.
How can I do the permissions here the right way?
I think the best you can do , is to run both nginx and php-fpm as www-data:www-data
step one
add/edit this to your nginx.conf:
user www-data www-data;
step two
add/edit php-fpm.conf and set user and group to www-data more info here
I hope that will help you

Laravel fails to process jobs in a queue

For starters, this is the list of processes inside my Docker container:
/var/www/html # ps aux
PID USER TIME COMMAND
1 root 0:00 {php-fpm.sh} /bin/sh /php-fpm.sh
6 root 0:02 /usr/sbin/crond
8 root 0:00 /sbin/syslogd -D -s 500
10 root 1:31 php /var/www/html/artisan queue:work --queue=mailer --sleep=3 --tries=3
11 root 0:00 /usr/bin/logger -t mailer
12 root 0:24 php-fpm: master process (/usr/local/etc/php-fpm.conf)
25 root 0:02 /usr/sbin/crond
30 root 0:01 /sbin/syslogd -D -s 500
13505 www-data 6:20 php-fpm: pool www
21682 www-data 0:17 php-fpm: pool www
21837 root 0:00 /bin/sh
22078 www-data 0:00 php-fpm: pool www
22123 root 0:00 ps aux
31186 root 0:00 /bin/sh
31301 root 0:00 /bin/sh
This is the entry point of my container:
#! /bin/sh
# Start cron daemon
/usr/sbin/crond
# Logger, max log file size 500Kb
/sbin/syslogd -D -s 500
( php /var/www/html/artisan queue:work \
--queue=mailer \
--sleep=3 --tries=3 2>&1 | /usr/bin/logger -t mailer & )
# Run PHP-FPM
php-fpm -F
The problem is php /var/www/html/artisan queue:work does not process jobs in the qeueu.
For that to happen I have to log in to the container by running docker exec -it /bin/sh and then run php /var/www/html/artisan queue:work --queue=mailer --sleep=3 --tries=3 and it works just fine.
So the question is what's wrong.

Where is php7.0-fpm.sock located

I have a simple project with directory structure
I am setting up nginx config for my drupal site, and for the fastcgi_pass I have been using 127.0.0.1:9000 but I want to use a unix socket as suggested in this conf:
# PHP 7 socket location.
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
but I can't find php/php7.0-fpm.sock;
I have the following path in my centos distro
/var/run/php-fpm/php-fpm.pid
Check the php-fpm config where the socket will be created with:
$ cat /etc/php/7.0/fpm/pool.d/www.conf
Look for listen, for example:
listen = /run/php/php7.0-fpm.sock
php-fpm creates the socket file after you started the process.
sudo service php7.0-fpm stop
sudo service php7.0-fpm start
Check the directory if socket file was created:
$ cd /run/php && ls -la
First check if php-fpm is running on your system, for doing this you could use pgrep for example:
# pgrep -fa php-fpm
5666 php-fpm: master process (/etc/php-fpm.conf)
5667 php-fpm: pool www
5668 php-fpm: pool www
5669 php-fpm: pool www
5670 php-fpm: pool www
5671 php-fpm: pool www
In this case, it shows is up and running and using the configuration file /etc/php-fpm.conf. Before checking the configuration file and trying to check for the listen = directive you could quickly look into /proc/net/unix for example:
# grep php /proc/net/unix
Which may return something like:
ffff8800bfb2f400: 00000002 00000000 00010000 0001 01 28561 /tmp/php-fpm.sock
In this case, it shows that the path for the php-fpm socket is located in /tmp/php-fpm.sock the one could be verified by checking the conf in /etc/php-fpm.d/www.conf in this case being: listen= /tmp/php-fpm.sock
In case you don't get any result and php-fpm is up and running, by checking the configuration you may find that is using the defaults by listing on a TCP socket:
listen = 127.0.0.1:9000
Something you could change to listen on a Unix socket like your suggested conf:
listen = /var/run/php/php7.0-fpm.sock
In some Linux distros normally this is used:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
After modifying your configuration don't forget to restart the services systemctl restart php-fpm. To check that the socket has been created you could do:
$ file /var/run/php/php7.0-fpm.sock
If socket exists if should print out something like this:
/var/run/php/php7.0-fpm.sock: socket
you can see it by running
$ ss --unix |grep 'php'
It is likely that an older libpcre3 is installed and satisfies the dependency in the php7.0 package, but only the newer library package provides pcre_jit_stack_free.
If this is the case, do an apt-get install libpcre3, and you’re good to go.
Ref.: https://github.com/oerdnj/deb.sury.org/issues/372
I hope this helps you.
Use this:
cat /etc/php/7.0/fpm/pool.d/www.conf | grep 'listen ='
Output example: listen = /run/php/php7.2-fpm.sock
Or for universal php vesions:
cat /etc/php/$(php -r "echo PHP_VERSION;" | grep --only-matching --perl-regexp "7.\d+")/fpm/pool.d/www.conf | grep 'listen ='

Categories