0

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

  • 1
    Try to comment the line ProxyPassMatch .... – Federico Sierra Jul 22 '18 at 22:02
1

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/">

  • Nitpick: You have an extra slash in the last VirtualHost block. – Nisse Engström Nov 4 '18 at 0:37
  • @NisseEngström corrected, thanks. I copy pasted, just to demonstrate the change to using a UDS – fyrye Nov 4 '18 at 0:40
0

The tutorial you've followed shows three distinct methods for proxying PHP to php-fpm. They are all mutually exclusive, and you're meant to choose exactly one of them.

I recommend you stick with the Proxy via handler approach as in your first code block, and remove the TCP socket (IP and port) approach from your second code block. That is, delete the following:

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

It doesn't reference the TCP socket that php-fpm is listening on anyway.

BTW you should also fix the DirectoryIndex but that's another issue.

  • Thanks. I've updated the post with the error I'm getting now. – James Shields Jul 22 '18 at 22:37
  • @JamesShields Did you forget to set the SELinux boolean? – Michael Hampton Jul 23 '18 at 12:32
  • It would seem that I did forget to set the SELinux boolean. Most of the tutorials on FPH seem to forget it too. Any hints or pointers on what's needed? – James Shields Jul 23 '18 at 22:34
  • @JamesShields Or, actually, port number. 8000 isn't allowed by default. See serverfault.com/a/566320/126632 for the allowed port numbers and how to add your own. – Michael Hampton Jul 23 '18 at 22:43

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.