skip to Main Content

Considering the following working Apache config (used inside the httpd:2.4.48-alpine docker container)

<VirtualHost *:80>
   
   DocumentRoot "/code2"

   <Proxy "fcgi://php/">
       ProxySet enablereuse=On
   </Proxy>

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

   <Directory /code2>
       Options Indexes FollowSymLinks
       AllowOverride All
       Require all granted
   </Directory>

   DirectoryIndex index.php

</VirtualHost>

However if I move the /code2 directory which matches the path in the php-fpm container (named "php") to e.g: /code ( I also update the DocumentRoot and Directory path ).

I get a 404 on all the php files. Why is this so? how can I provide a different path to the php files for each container?

Another interesting thing to note is that both the access log of apache and php don’t display the full path to the php file thats being accessed, just the filename only.

2

Answers


  1. If you want to use the "DocumentRoot" directive with a PHP handler, you need to mount that volume to httpd as well. By default, non-existent files will directly trigger a 404 (See https://cwiki.apache.org/confluence/display/HTTPD/PHP-FPM "Proxy via handler")

    Here’s a small example (with docker-compose for simplicity) for your use-case:

    ./docker-compose.yaml:

    version: "3.9"
    
    services:
      httpd:
        build:
          context: ./httpd/
        ports:
          - 80:80
        volumes:
          - ./php-vol:/code2:rw
      php:
        image: php:8.0-fpm
        volumes:
          - ./php-vol:/code2:rw
          - ./php-vol2:/code2/another-dir:rw
    

    ./httpd/Dockerfile

    FROM httpd:2.4.48-alpine
    
    COPY php-fpm.conf conf/extra/php-fpm.conf
    
    RUN echo "Include conf/extra/php-fpm.conf" >> conf/httpd.conf
    
    RUN sed -i 
            -e 's/^#(LoadModule .*mod_proxy.so)/1/' 
            -e 's/^#(LoadModule .*mod_proxy_fcgi.so)/1/' 
            conf/httpd.conf
    

    ./httpd/php-fpm.conf (using PHP handler, see https://cwiki.apache.org/confluence/display/HTTPD/PHP-FPM)

    <VirtualHost *:80>
       DocumentRoot "/code2"
    
       <Proxy "fcgi://php/">
           ProxySet enablereuse=On
       </Proxy>
    
       <FilesMatch .php$>
           SetHandler "proxy:fcgi://php:9000"
       </FilesMatch>
       
       <Directory /code2>
           Options Indexes FollowSymLinks
           AllowOverride All
           Require all granted
       </Directory>
    
       DirectoryIndex index.php
    </VirtualHost>
    

    If you only want to serve .php files with php-fpm, this could be simplified:

    <VirtualHost *:80>
       ProxyPassMatch ^/(.*.php(/.*)?)$ fcgi://php:9000/code2/$1
    
       DirectoryIndex index.php
    </VirtualHost>
    
    Login or Signup to reply.
  2. If you want to use a different path in httpd and php-fpm you can customize the environment variables sent to php-fpm with ProxyFCGISetEnvIf.

    https://httpd.apache.org/docs/2.4/mod/mod_proxy_fcgi.html#proxyfcgisetenvif

    Unfortunately the combination of variables php-fpm might look at to determine where to look on disk can be a little confusing — it’s actually the reason this directive exists to give you a chance at the last moment to see what mod_proxy_fcgi would have sent and then tweak them.

    This example from the manual is eerily (with the d suffix being dropped) close to your issue:

    ProxyFCGISetEnvIf "reqenv('PATH_TRANSLATED') =~ m|(/.*prefix)(d+)(.*)|" PATH_TRANSLATED "$1$3"
    

    I suggest using this pattern to transform PATH_TRANSLATED (filesystem path) from your httpd container to the one that’s valid in the FPM container.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search