Apache 2.4 with PHP-FPM 5.6 on Centos 6

apache-2.4php-fpmphp5

I'm trying to get PHP working over FPM on Centos.

On the FPM side, /etc/php-fpm.d/www.conf is pretty much the default values. I'm left it using a TCP port as follows (I may want to change to a file port later for performance, but lets walk before we run):

listen = 127.0.0.1:9000

The php-fpm service starts without any problems.

So I think my problems are on the Apache side. I added a config file conf.d/php-fpm.conf containing the following:

# Defining a worker will improve performance
# And in this case, re-use the worker (dependent on support from the fcgi application)
# If you have enough idle workers, this would only improve the performance marginally
<Proxy "fcgi://localhost:9000/" enablereuse=on max=10>
</Proxy>
<FilesMatch "\.php$">
    <If "-f %{REQUEST_FILENAME}">
        # Pick one of the following approaches
        # Use the standard TCP socket
        SetHandler "proxy:fcgi://localhost/:9000"
        # If your version of httpd is 2.4.9 or newer (or has the back-ported feature), you can use the unix domain socket
        #SetHandler "proxy:unix:/path/to/app.sock|fcgi://localhost/"
    </If>
</FilesMatch>

I've set up a test site as follows:

<VirtualHost 192.168.1.35:80>
    ServerAdmin webmaster@example.com
    ServerName centos.local
    ServerAlias www.centos.local

    #ProxyPassMatch "^/(.*\.php)$" "unix:/var/run/myappname.sock|fcgi://localhost/webroot"

    DirectoryIndex index.html

    ErrorLog /var/log/httpd24/centos.error.log
    CustomLog /var/log/httpd24/centos.access.log combined

    <Directory /var/www/vhosts/centos.local/httpdocs>
        DocumentRoot /var/www/vhosts/centos.local/httpdocs
        # Allow .htaccess
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

(I'm not sure if the ProxyPassMatch is needed, I seem to get the same result whether I have it or not).

The httpd service starts, and html pages serve fine, but if I try to load a PHP file, I get Service Unavailable in the browser, and the following written to the error log:

[Sun Jul 22 21:13:21.813760 2018] [proxy:error] [pid 14621] (2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /var/run/myappname.sock (localhost) failed
[Sun Jul 22 21:13:21.814003 2018] [proxy_fcgi:error] [pid 14621] [client 192.168.1.41:54578] AH01079: failed to make connection to backend: httpd-UDS

Hopefully someone can tell me where I'm going wrong!

Edit:

As suggested, I've taken out the ProxyPassMatch. I now get the following error:

[Sun Jul 22 23:25:08.066467 2018] [proxy:error] [pid 16319] (13)Permission denied: AH00957: FCGI: attempt to connect to 127.0.0.1:8000 (*) failed
[Sun Jul 22 23:25:08.066548 2018] [proxy_fcgi:error] [pid 16319] [client 192.168.1.41:56396] AH01079: failed to make connection to backend: localhost

It seems to be failing to find the FPM on port 8000, but I can't see anything in any of my config files. What am I missing?

Thanks,

James

Best Answer

Since you are using a TCP socket proxy on <Proxy "fcgi://localhost:9000/" enablereuse=on max=10> </Proxy>

The issue is caused by SetHandler "proxy:fcgi://localhost/:9000"

For some reason Apache interprets the slash as a directory separator and defaults to port 8000 for the proxy.

To resolve the issue simply remove the / before :9000

SetHandler "proxy:fcgi://localhost:9000"

Ensure your php-fpm configuration matches:

[www]
listen = localhost:9000
listen.allowed_clients=localhost

I highly recommend you declare an IP address instead. localhost is kind of a catch-all.

Since localhost can be applied to multiple IP addresses on the webserver, I recommend explicitly specifying an IP, to avoid the proxy being assigned to multiple private IPs or DNS resolution.
Example:

#/etc/hosts
127.0.0.1 localhost
192.168.1.2 localhost fqdn.example.com

Below is a suggested Apache virtual host and php-fpm configuration when not using a Unix Domain Socket (UDS).

9001 is used to not conflict with the default [www] php-fpm pool and allow you to create a separate pool configuration.

Ensure your MPM configuration does not conflict with your current configurations.

#/etc/httpd/conf.d/01-mpm.conf
LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule cgid_module modules/mod_cgid.so
<IfModule mpm_event_module>
    ServerLimit              100
    StartServers             4
    ThreadLimit              64
    MaxRequestWorkers        100
    MinSpareThreads          25
    MaxSpareThreads          75
    ThreadsPerChild          25
    MaxConnectionsPerChild   1000
    ListenBacklog       511
</IfModule>
#/etc/httpd/conf.d/999-centos.local.conf
<VirtualHost 192.168.1.35:80>
    ServerAdmin webmaster@example.com
    ServerName centos.local
    ServerAlias www.centos.local
    DocumentRoot /var/www/vhosts/centos.local/httpdocs

    ErrorLog /var/log/httpd24/centos.error.log
    CustomLog /var/log/httpd24/centos.access.log combined

    <Directory /var/www/vhosts/centos.local/httpdocs>
        # Allow .htaccess
        AllowOverride All
        Require all granted
        DirectoryIndex index.php index.html
        <IfModule mod_setenvif.c>
            SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
        </IfModule>
    </Directory>

    <IfModule proxy_fcgi_module>
        <Proxy "fcgi://127.0.0.1:9001/" enablereuse=on max=10>
            ProxySet timeout=1800
        </Proxy>
        <FilesMatch "\.php$">
            <If "-f %{REQUEST_FILENAME}">
                SetHandler "proxy:fcgi://127.0.0.1:9001"
            </If>
        </FilesMatch>
    </IfModule>
</VirtualHost>
;/etc/php-fpm.d/centos.local.conf
[centos.local]
user=apache
group=apache

listen=127.0.0.1:9001
listen.allowed_clients=127.0.0.1

pm=dynamic
pm.max_children=10
pm.start_servers=2
pm.min_spare_servers=2
pm.max_spare_servers=5

security.limit_extensions=.php

You can optionally replace the TCP socket configuration in favor of using a UDS.

<VirtualHost>
    #...
    <IfModule proxy_fcgi_module>
        <Proxy "fcgi://127.0.0.1/" enablereuse=on max=10>
            ProxySet timeout=1800
        </Proxy>
        <FilesMatch "\.php$">
            <If "-f %{REQUEST_FILENAME}">
                SetHandler proxy:unix:/var/run/unique-domain.sock|fcgi://127.0.0.1/
            </If>
        </FilesMatch>
    </IfModule>
</VirtualHost>
[centos.local]
;...

;listen=127.0.0.1:9001
;listen.allowed_clients=127.0.0.1
listen=/var/run/unique-domain.sock
listen.mode=0660
listen.owner=nobody
listen.group=nobody

;...

Note: mod_proxy_fcgi UDS support was introduced in Apache 2.4.9 [sic]

You should not use enablereuse=on when using UDS and Apache 2.4 < 2.4.11 There were issues in Apache prior to 2.4.11 that were not compatible with UDS and connection reuse . [sic]

If you experience strange responses or 503 service unavailable errors while using UDS, remove enablereuse=on max=10 from the <Proxy "fcgi://127.0.0.1:9001/">