I get the following output to stderr from the php container.
api-php | [21-Sep-2017 21:49:18] WARNING: [pool www] child 13, script '/srv/www/public/index.php' (request: "GET /something") executing too slow (25.593270 sec), logging
api-php | [21-Sep-2017 21:49:18] NOTICE: child 13 stopped for tracing
api-php | [21-Sep-2017 21:49:18] NOTICE: about to trace 13
api-php | [21-Sep-2017 21:49:18] ERROR: failed to open /proc/13/mem: Permission denied (13)
api-php | [21-Sep-2017 21:49:18] NOTICE: finished trace of 13
root@f161350c4858:/srv/www# id
uid=0(root) gid=0(root) groups=0(root)
root@f161350c4858:/srv/www# id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
root@f161350c4858:/srv/www# ls -lash /proc/13/mem
0 -rw------- 1 www-data www-data 0 Sep 21 21:49 /proc/13/mem
root@f161350c4858:/srv/www# cat /proc/13/mem
cat: /proc/13/mem: Permission denied
Now, the slowlog would be a PHP-FPM running as root. However, it's my understanding that /proc is a special kernel access dir and does not conform to standard permissions, instead obeying the UID/GID values to determine process authorization for accessing memory space. This is obviously for security purposes.
I'm not really sure what the solution here is. Maybe this is even a PHP-FPM design flaw?
It looks like it's reading /proc/$$/mem in https://github.com/php/php-src/blob/6053987bc27e8dede37f437193a5cad448f99bce/sapi/fpm/fpm/fpm_trace_pread.c#L40, but I'm not 100% sure why -- it's talking about "tracing", which Docker's definitely blocking (likely in the default seccomp profile and possibly via capabilities), but I'm not familiar enough with this part of PHP-FPM to say much more than that. :disappointed:
(It's definitely by design that PHP-FPM is doing this, and also definitely by design that Docker is blocking it by default.)
@tianon good find. The reason, as I understand it that php-fpm is reading this is because it needs to get the trace details for the slow_log. PHP-FPM wouldn't really have access to this any other way, unless PHP somehow passed it all back to FPM, but that wouldn't work without an explicit call to PHP since PHP isn't going to know how long the call is taking. This is a PHP-FPM concern.
I'm wondering if this is working on a bare metal install of Debian.
I imagine that this works fine on a bare metal install of Debian because it won't be applying the same security constraints by default that Docker is, and PHP-FPM will likely be able to read it's own memory file just fine.
Regardless, this is really working-as-designed, so further comments/questions should likely be posted to the Docker Community Forums, the Docker Community Slack, or Stack Overflow. Thanks!
@tianon I respect that this issue may not be rooted in this docker container implementation. However, respectfully, I disagree with closing this issue until there is a resolution since it flat out does not work.
@oojacoboo I've trying with owner permission (under CoreOS), but get another error
/var/www/html $ id
uid=82(www-data) gid=82(www-data) groups=82(www-data)
/var/www/html $ ps
PID USER TIME COMMAND
1 root 0:00 php-fpm: master process (/usr/local/etc/php-fpm.conf)
48 www-data 0:16 php-fpm: pool www
53 www-data 0:00 sh
62 www-data 0:01 php-fpm: pool www
63 www-data 0:00 php-fpm: pool www
65 www-data 0:00 ps
/var/www/html $ cat /proc/48/mem
cat: read error: I/O error
--cap-add all solve this problem, will check more
--cap-add SYS_PTRACE is enough
I'm still unable to reproduce an issue here -- are the systems you're testing on using AppArmor or SELinux? (I guess CoreOS is likely using SELinux, but odd that --cap-add SYS_PTRACE works when I don't have an issue running the PHP-FPM container as-is and I don't have AppArmor or SELinux, but obviously do have the same set of default capabilities.)
$ docker pull php:7-fpm
7-fpm: Pulling from library/php
Digest: sha256:d8ebbb9f1146af10ec9b05943f82197d99b92d6e25516d82291f6d50419f4f4b
Status: Image is up to date for php:7-fpm
$ docker run -it --rm php:7-fpm
[12-Oct-2017 21:51:56] NOTICE: fpm is running, pid 1
[12-Oct-2017 21:51:56] NOTICE: ready to handle connections
See also https://travis-ci.org/docker-library/php/jobs/286978534#L2972, where Travis runs our php-fpm-hello-web test successfully (https://github.com/docker-library/official-images/blob/5b0acc55af0bdfc198407153d4e55b0248cb3843/test/tests/php-fpm-hello-web/run.sh), which also does not do anything special beyond simply docker run (and runs successfully on systems which have AppArmor enabled, but hasn't been tested on SELinux).
@tianon PHP-FPM runs fine for most operations. As you can see in my case, it's when trying to write to the slow_log that's the issue.
I'm not using AppArmor or SELinux. I'm using the pretty default php:7.1-fpm container.
Does the container crash, or just fail to write to the slow_log and move on?
Right, it only fails to write the slow_log. This is a PHP-FPM error, everything else works perfectly fine.
@oojacoboo Just run container with --cap-add SYS_PTRACE option, it's solve issue with tracing
So, it looks like the only thing that's actionable here is to add a brief note to the documentation that if request_slowlog_timeout is enabled, one should include --cap-add SYS_PTRACE in order for PHP-FPM to read the PHP backtrace, right?
(Probably with a link to https://secure.php.net/manual/en/install.fpm.configuration.php#request-slowlog-timeout for context.)
@tianon Right. But not sure if it's only one tracing call.
I guess my advice from https://github.com/docker-library/php/issues/241#issuecomment-353678973 applies here too (and it'd probably make sense to combine the two into a single PR on the docs), namely that we need a variant-fpm.md file for the php image over in the docs which describes configuration and notes that --cap-add SYS_PTRACE is necessary if request_slowlog_timeout is enabled.
(Noted that over on #241 now -- closing this in favor of that one since we need general documentation about configuring FPM anyhow, which is what that issue covers.)
Most helpful comment
@oojacoboo Just run container with
--cap-add SYS_PTRACEoption, it's solve issue with tracing