How do I get PHP-FPM to work with nginx-proxy with FastCGI? How do I get PHP-FPM to work with nginx-proxy with FastCGI? docker docker

How do I get PHP-FPM to work with nginx-proxy with FastCGI?


The default generated config of nginx-proxy is not fully working.

I think something is messed up with VIRTUAL_ROOT environment variable, because the root of the problem is PHP getting a wrong path via SCRIPT_FILENAME (that's why you see no PHP output) and there is no try_files with =404 symbol (that's why you get 200 with everything).

I have a prepared working setup using docker-compose in GitHub to demonstrate that it would work with an existing SCRIPT_FILENAME in the nginx config.

I have changed test.local to test.localhost.

I think to get it working as it should, you would have to use an nginx template for nginx-proxy, so the generated default.conf does work with php fpm and have the missing fastcgi param included.

Another, yet different approach would be to pack PHP and a manually configured webserver (nginx) in a project and having the automated reverse nginx proxy in a standalone project.This would cost you an additional process running but gives you more control and easier deployment.

Alternatively, you might want to have a look into traefik which does essentially the same as nginx-proxy.


Daniel's answer is definitely on the right track. I use the php-fpm image with nginx as my main stack for php sites. Having said that, I don't use the nginx-proxy docker image. Instead, I use plain nginx on the host machine, and configure ports to point to backend php-fpm docker images.

I'm not using docker-compose either. Since it's just docker containers running single sites, I don't need it. Here's an example docker run command:

docker rm -f www.example.com || truedocker run -itd -p 9001:9000 -P \        --name www.example.com \        --volume /var/www/html/www.example.com:/var/www/html/www.example.com \        --link mariadb:database.example.com \        --restart="always" \        --hostname="example.com" \    --log-opt max-size=2m \    --log-opt max-file=5 \        mck7/php-fpm:7.4.x-wordpress

And here is an example nginx config:

server {  server_name example.com www.example.com;  location ~ /.well-known {    allow all;  }  location ~ /\.ht {    deny all;  }  root /var/www/html/www.example.com/src;  index index.php;  location / {    try_files $uri $uri/ /index.php?$args;  }  location ~ [^/]\.php(/|$) {    fastcgi_split_path_info ^(.+?\.php)(/.*)$;    if (!-f $document_root$fastcgi_script_name) {      return 404;    }    include fastcgi_params;    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;    fastcgi_param PATH_INFO       $fastcgi_path_info;    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;    fastcgi_pass   127.0.0.1:9001;    fastcgi_index  index.php;  }}

A few things about this setup are key. The port re-mapping for the docker container. In this example I map port 9001 to 9000. The other "gotcha" is that the root for the container must be an actual location on the host. I have no idea why this is the case, but for whatever reason the path docker thinks it's using has to actually be the path on the host as well.