I am migrating my server to use mod_proxy_fcgi and php-fpm instead of mod_php. Apache is able to forward .php requests to the fcgi proxy and PHP executes correctly. I've got this working with:

ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://$1

Unfortunately, Apache forwards all .php requests to the proxy, even when the file doesn't exist. This causes a few problems. My ErrorDocument rule isn't invoked, and DirectoryIndex index.php index.html doesn't fall back to index.html.

I was able to fix these problems with mod_rewrite:

RewriteEngine On                                                           
RewriteCond %{REQUEST_FILENAME} ^/((.*\.php)(/.*)?)$                       
RewriteCond /var/www/html/%2 -f                                   
RewriteRule . fcgi:// [P] 

However, the Apache documentation does not recommend RewriteRule: "This is because this flag triggers the use of the default worker, which does not handle connection pooling."

Ideally, I think I'd either like to use ProxyPass in a FilesMatch block (currently unsupported), or define a new handler that proxies through fcgi and use it to handle .php requests, similar to what mod_php does.

Any suggestions for simulating a standard mod_php setup but actually proxying through fcgi?

6 Answers 6


One option is to install mod_proxy_handler: https://gist.github.com/progandy/6ed4eeea60f6277c3e39

Or you can wait for Apache 2.4.10, which should include the module.

Basically the module lets you do this:

<FilesMatch \.php$>
SetHandler proxy:fcgi://localhost:9000

<FilesMatch \.php$>
    SetHandler "proxy:unix:/path/to/socket.sock|fcgi://./"
  • YAEEES! I lost an entire day to trial and error, what solved the issue for me was using the #tcp block above. Using ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://$1 does not work with VirtualDocumentRoots, and the rewriting trick never worked for me.
    – mcdado
    Oct 20, 2017 at 22:14
  • 1
    Also, it's important to note that proxy:fcgi://localhost:9000 does not want the path after it. This was a big time misunderstanding for me.
    – mcdado
    Oct 20, 2017 at 22:15
  • FYI I wrote this up in a blog post: mcdado.com/post/166619749589/apache-and-php-fpm-via-homebrew
    – mcdado
    Oct 20, 2017 at 23:45
  • Make sure that php-fpm is listening using a socket instead of a TCP port as otherwise it won't work (displays the php code in the browser). The php-fpm listen config should look like listen = /var/run/php-fpm7.sock
    – 8ctopus
    Apr 19, 2020 at 9:01

Just for the record as a one liner:

AddHandler "proxy:unix:/path/to/socket.sock|fcgi://./" .php

You'll need a recent Apache 2.4 (RedHat back ported that to 2.4.6)



I had same issue when file did not existed was showing "File not found." message , this fixed my issue and allowed me to setup a 404 page :

<VirtualHost *:80>

---------- content --------

DocumentRoot /home/user/public_html/domain.tld

#this disables php execution if you wish to show only html files
#ProxyPass /errors !

ProxyErrorOverride On
# /errors folder is located in public_html
ErrorDocument 404 /errors/404.php


Ditto to the OP.

  • I also couldn't figure out how to get Apache VHOST config to route non-findable requests to a 404.
  • Similarly, I was also stymied by trying to figure out how to get extension-less URL's to map throuh ProxyPassMatch.
    • Sure... I could route everything through the php-fpm proxy, but that killed javascript and css files.

Theoretical Solution

My guess is that I'd have to write a custom 404.php processor -- and then route all requests through that appending the requested file(s) as a query string.

For example:

RewriteRule ^.*$   fcgi://{DOCUMENT_ROOT}/404.php?no_comprende=%{REQUEST_URI} [P]
ProxyPassMatch ^/(.*\.php(/.*)?)$    fcgi://{DOCUMENT_ROOT}/$1

in theory -- and assuming that the order in which they are listed still applies as normal:

Any 404'd file would be caught before the ProxyPassMatch directive was reached


  • php5-fpm (5.4.23)
  • Apache 2.4.2
  • Ubuntu 12.04 / 3.8.0-34 x86_64

To handle extension-less URLs with php-fpm I adapted the above to look for extension-less URL's as such in my VHOST config:

# Extensionless URL's
RewriteCond %{REQUEST_FILENAME} ^/((.*)(/.*)?)$
RewriteCond %{DOCUMENT_ROOT}/%2.php -f
RewriteRule !.*\.php$   fcgi://{DOCUMENT_ROOT}/%1.php   [P]

# files w/ .php extensions
RewriteCond %{REQUEST_FILENAME} ^/((.*\.php)(/.*)?)$
RewriteCond %{DOCUMENT_ROOT}/%2 -f
RewriteRule . fcgi://{DOCUMENT_ROOT}/%1 [P]

Not pretty, but it does get the job done :-(


I had precisely the same problem as ide and spent far longer trying to solve this than I had hoped. Since this is the only post or article I was able to find that helped me to adequately solve the issue, I wanted to add my solution to the mix.

My configuration:

  • Ubuntu 14.04
  • Apache 2.4.20
  • PHP-FPM 5.5.9-1ubuntu4.17 (fpm-fcgi) (built: May 19 2016 19:08:26)

I encountered a few additional challenges:

  1. My ErrorDocument handler is a PHP file.
  2. I have a bunch of RedirectPermanent directives in my document root's .htaccess file. These were not being honored because the requests were proxied to PHP-FPM before the redirect rules were evaluated.
  3. FilesMatch was insufficient for me because I use URL rewriting in similar ways to Wordpress. E.g. /mydir/mypath.html points to /mydir/script.php. I couldn't get it to match the rewritten URLs, though perhaps I overlooked somethig?
  4. I was able to get misterich's approach to work, but after reading Apache's performance warning, I decided to dig in further.

My solution is basically this:

  1. Intercept and redirect requests for non-existent directories and files and rewrite them to the error handler PHP file.
  2. Use another rewrite rule to route my rewritten error request to PHP-FPM.
  3. Route all other requests to PHP-FPM using ProxyPassMatch.

To solve the 301 redirects (#2), I'll simply leverage the error handler to issue redirects.

RewriteEngine On

RewriteRule ^.*\.php$ /error.php?error=404&requestUri=$1

RewriteCond %{REQUEST_FILENAME} ^/(error.php)$
RewriteCond %{DOCUMENT_ROOT}/%1 -f
RewriteRule . fcgi://{DOCUMENT_ROOT}/%1   [P]

ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://"

I had the same issue that when there is no index.php apache does not fall back to index.html when using ProxyPassMatch.

What I did instead is I used (apache 2.4):

<FilesMatch "\.php$">
  SetHandler "proxy:unix:/usr/local/php73/var/run/mpelov-php-fpm.sock|fcgi://localhost/"

I'm not sure if that'll work on apache 2.2 though.

The problem with that is that you cannot tell the path to the file. So http://example.com/file.php will be mapped to /file.php which is normally fine, but if php-fpm uses chroot it goes a bit complicated because for php the file is /file.php and if you have http://example.com/file.html then apache handles the request and the path is //file.html

So you can't use filematch with fpm+chroot.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .