13

I am attempting to get nginx-proxy to work with the php-fpm variant of the official php image via fastcgi. Unfortunately, I seem to be unable to do so. I'm sure the problem is just something simple that I don't know about.

I have followed the instructions for nginx-proxy to the best of my ability and have boiled it down to a very simple way to re-create the issue. Here's my docker-compose.yml file:

version: "3" services: proxy: image: jwilder/nginx-proxy ports: - "80:80" volumes: - /var/run/docker.sock:/tmp/docker.sock:ro environment: - DEFAULT_HOST=test.local fpm: image: php:fpm environment: - VIRTUAL_HOST=test.local - VIRTUAL_PROTO=fastcgi 

I then drop in a simple index.php file by running:

docker container exec -it web_fpm_1 /bin/bash -c 'echo "<?php phpinfo(); ?>" > /var/www/html/index.php' 

(It puts web_ in front because this project is in a directory named web/.)

I also modify my hosts file to point test.local to 127.0.0.1, so I can test it. However, every attempt to browse to test.local results in a blank white page.

The logs for the web_proxy_1 container don't indicate anything out of the ordinary, as far as I know:

❯ docker container logs web_proxy_1 WARNING: /etc/nginx/dhparam/dhparam.pem was not found. A pre-generated dhparam.pem will be used for now while a new one is being generated in the background. Once the new dhparam.pem is in place, nginx will be reloaded. forego | starting dockergen.1 on port 5000 forego | starting nginx.1 on port 5100 dockergen.1 | 2020/07/20 19:24:54 Generated '/etc/nginx/conf.d/default.conf' from 2 containers dockergen.1 | 2020/07/20 19:24:54 Watching docker events dockergen.1 | 2020/07/20 19:24:54 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification 'nginx -s reload' nginx.1 | test.local 172.18.0.1 - - [20/Jul/2020:19:25:12 +0000] "GET / HTTP/1.1" 200 5 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" nginx.1 | test.local 172.18.0.1 - - [20/Jul/2020:19:25:13 +0000] "GET /favicon.ico HTTP/1.1" 200 5 "http://test.local/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" 

The logs for the web_fpm_1 container show that nothing gets sent except a 200 response:

❯ docker container logs web_fpm_1 [20-Jul-2020 19:24:54] NOTICE: fpm is running, pid 1 [20-Jul-2020 19:24:54] NOTICE: ready to handle connections 172.18.0.3 - 20/Jul/2020:19:25:12 +0000 "- " 200 172.18.0.3 - 20/Jul/2020:19:25:13 +0000 "- " 200 

What am I doing wrong?

Incidentally, I have asked this question on the nginx-proxy repo, the nginx-proxy Google Group, and the php repo. I either get no response or they pass the buck.

10
  • try curl http://test.local/var/www/html/index.php let me know if this works Commented Jul 20, 2020 at 17:41
  • Can you show the nginx logs please. Commented Jul 20, 2020 at 18:16
  • Hey, thanks for the replies. @WSMathias9: I'm afraid the result is nothing. It returns nothing, just like going to the page itself returns a blank white page. @ Daniel: Done. I've edited the original post to include the proxy's logs. Commented Jul 20, 2020 at 19:32
  • Let both services share /var/www/html/index.php and /var/run/docker.sock:/tmp/docker.sock through volumes in docker-compose.yml. See what happens. Also you can put them in same network as well. Commented Jul 20, 2020 at 19:43
  • 1
    @BentCoder That's not what it supposed to be configured. Don't just try 777 open and give everything to everything and "see what happens". This is how you open your server for hackers and make system unstable. Very bad advice. Data should only be on 1 container. Commented Jul 20, 2020 at 19:51

2 Answers 2

2
+100

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.

Sign up to request clarification or add additional context in comments.

12 Comments

Okay, @Daniel, this is getting me closer than ever to getting nginx-proxy to work over fastcgi. I am now, at least, getting a "Welcome to nginx" page. Your github repo worked a treat and does highlight what I need to do, for the most part. I am still wondering how to get this to work with more than one server, however. Looks like I need to follow jwilder's virtual host instructions. Do I just copy the entire server {} block to the vhost file?
Also, I checked out traefik. It looks like it would be worth looking into further, but since I've come so far already with nginx-proxy, I'd like to complete this mission first.
The magic is happening when the nginx-proxy is listening to the docker socket /var/run/docker.sock:/tmp/docker.sock:ro. The proxy can see when you load up a new container and automatically regenerates its own nginx config. The nginx-proxy uses environment variables VIRTUAL_... while traefik uses so called labels. You should try to alter the nginx-proxy template and provide your own with the missing SCRIPT_FILENAME OR you alter the nginx fastcgi_params to include SCRIPT_FILENAME.
@Sturm I am using traefik for local development on my notebook and I use nginx (manually configured) on production systems. The "configure automatically" stuff is only really helpful locally or while developing but it's not worse doing the configuration by hand.
So I'm guessing that you don't think I should follow the virtual host instructions? "You should try to alter the nginx-proxy template and provide your own with the missing SCRIPT_FILENAME OR you alter the nginx fastcgi_params to include SCRIPT_FILENAME" - I'm afraid I do not know where/how to do this. Could you please amend your answer to include instructions on exactly how to update the proxy template?
|
2

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 || true docker 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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.