Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fastcgi does not work #1466

Closed
SturmB opened this issue Jul 6, 2020 · 20 comments · Fixed by #2449
Closed

fastcgi does not work #1466

SturmB opened this issue Jul 6, 2020 · 20 comments · Fixed by #2449
Assignees
Labels
kind/bug Issue reporting a bug

Comments

@SturmB
Copy link

SturmB commented Jul 6, 2020

I am unable to get this to work via fastcgi with a simple php-fpm container. 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_fpm_1 container show that nothing gets sent except a 200 response:

[06-Jul-2020 15:40:39] NOTICE: fpm is running, pid 1
[06-Jul-2020 15:40:39] NOTICE: ready to handle connections
172.19.0.3 -  06/Jul/2020:15:41:02 +0000 "- " 200
172.19.0.3 -  06/Jul/2020:15:41:03 +0000 "- " 200

What am I doing wrong?

@flowl
Copy link

flowl commented Jul 21, 2020

This problem made me very curious and I found out why it's not working.

Missing in the generated default.conf from the default template:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Also missing something like try_files $uri $uri/ /index.php?$args =404 to stop sending 200 status code even when no file exists.

See my test repo: https://github.com/flowl/so6292053

  1. When you start it using docker-compose up -d, http://test.localhost:8011 will only show you status code 200 with a blank page.
  2. Copy ./docker/nginx/conf.d/working-default.conf.dist to ./docker/nginx/conf.d/default.conf
  3. reload nginx: docker container exec -it so6292053_proxy_1 /etc/init.d/nginx reload

You will now see a phpinfo(); page at http://test.localhost:8011

@tkw1536
Copy link
Collaborator

tkw1536 commented Jul 25, 2020

When I do docker-compose up and navigate to http://localhost:8011/ I get File not found. . Navigating to http://localhost:8011/index.php, I get a phpinfo page.

Perhaps you have an outdated version of the jwilder/nginx-proxy:latest? Can you do a docker-compose pull?

@tkw1536
Copy link
Collaborator

tkw1536 commented Jul 25, 2020

For context, the default.conf that gets generated for me is:

# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
  default $http_x_forwarded_proto;
  ''      $scheme;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
  default $http_x_forwarded_port;
  ''      $server_port;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
  default upgrade;
  '' close;
}
# Apply fix for very long server names
server_names_hash_bucket_size 128;
# Default dhparam
ssl_dhparam /etc/nginx/dhparam/dhparam.pem;
# Set appropriate X-Forwarded-Ssl header
map $scheme $proxy_x_forwarded_ssl {
  default off;
  https on;
}
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
log_format vhost '$host $remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent"';
access_log off;
		ssl_protocols TLSv1.2 TLSv1.3;
		ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
		ssl_prefer_server_ciphers off;
resolver 127.0.0.11;
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
server {
	server_name _; # This is just an invalid value which will never trigger on a real hostname.
	listen 80;
	access_log /var/log/nginx/access.log vhost;
	return 503;
}
# test.localhost
upstream test.localhost {
				## Can be connected with "so6292053_default" network
			# so6292053_fpm_1
			server 172.19.0.2:9000;
}
server {
	server_name test.localhost;
	listen 80 default_server;
	access_log /var/log/nginx/access.log vhost;
	location / {
		root   /var/www/html/;
		include fastcgi_params;
		fastcgi_pass test.localhost;
	}
}

@flowl
Copy link

flowl commented Jul 25, 2020

@tkw1536 in the config is no try_files $uri $uri/ /index.php and in fastcgi_params or the default.conf there is no fastcgi_param SCRIPT_FILENAME $request_filename;

@bgorhoball
Copy link

@tkw1536 in the config is no try_files $uri $uri/ /index.php and in fastcgi_params or the default.conf there is no fastcgi_param SCRIPT_FILENAME $request_filename;

Thanks! It works!!

@songhanpoo
Copy link

fastcgi not work with wordpress-fpm.
i have reconfig nginx then this can compile php but not load css.

@tkw1536
Copy link
Collaborator

tkw1536 commented Oct 30, 2020

Based on the example by @flowl I have implemented https://github.com/tkw1536/nginx-proxy-fpm-workaround. This solution
does not require manually intervening in the nginx-proxy container. It additionally serves non-php files statically.

@flowl
Copy link

flowl commented Oct 30, 2020

@songhanpoo

fastcgi not work with wordpress-fpm.

My previously mentioned line of config with try_files should contain arguments, at least for wordpress:

try_files $uri $uri/ /index.php?$args;

@tkw1536 it should be taken care of where the files are coming from because SCRIPT_FILENAME is probably in a vendor file /etc/nginx/fastcgi_params or so.

The missing configuration should be dynamically build into the resulting files, anything fixed or hardcoded is against the idea of the dynamic reverse proxy imo.

@songhanpoo
Copy link

Based on the example by @flowl I have implemented https://github.com/tkw1536/nginx-proxy-fpm-workaround. This solution
does not require manually intervening in the nginx-proxy container. It additionally serves non-php files statically.

I have tried ! this only work then compile static file php.
but not render css. something else fix that ?

@buchdag buchdag self-assigned this May 11, 2021
@buchdag buchdag added the kind/bug Issue reporting a bug label May 11, 2021
@kazkame
Copy link

kazkame commented May 15, 2021

I confirm, I face the same issue, merci buchdag pour ton travail et si tu arrives à regler le fastcgi

@PeterTucker
Copy link

I'm not sure if this would be a solution, but if there was somehow a way to implement additional VIRTUAL_ variables in the services being proxied for a location.conf and static.conf so nginx would see these variables on a new container and add them to /vhost.d/. I'm basing this on @fowl / @tkw1536 fix. The issue is though this workaround is "working" we need a way to instead of defining the static and location conf in nginx-proxy container, instead define it in the service-being-proxied's container, so when a new container is "seen" by nginx-proxy it automagically adds location / static confs. Not sure if this is possible.

How it's currently done via @tkw1536 workaround via volume mounts in nginx-proxy container:

version: '3'
services:
   nginx:
    image: jwilder/nginx-proxy
    ports:
      - 80:80
    volumes:
        - /var/run/docker.sock:/tmp/docker.sock:ro
        - ./fpm_workaround_location.conf:/etc/nginx/vhost.d/example.com_location:ro
        - ./fpm_workaround_static.conf:/etc/nginx/vhost.d/example.com:ro

   php:
    image:  php:fpm
    environment:
      VIRTUAL_HOST: example.com
      VIRTUAL_PROTO: fastcgi
      VIRTUAL_PORT: 9000
      VIRTUAL_ROOT: /var/www/html
    volumes:
      - ./html:/var/www/html

Proposed workaround in the actual proxied service via environment variables:

php:
    image:  php:fpm
    environment:
      VIRTUAL_HOST: example.com
      VIRTUAL_PROTO: fastcgi
      VIRTUAL_PORT: 9000
      VIRTUAL_ROOT: /var/www/html

      # Proposed variables to add to nginx-proxy:
      VIRTUAL_LOCATION_CONF: ./example.com_location.conf
      VIRTUAL_STATIC_CONF: ./example.com_static.conf

    volumes:
      - ./html:/var/www/html

fpm_workaround_location.conf / example.com_location.conf :

fastcgi_param SCRIPT_FILENAME $request_filename;

fpm_workaround_static.conf / example.com.conf :

# match anything that doesn't end in .php
location ~ .*(?<!\.php)$ {
    root /var/www/$server_name;
    try_files $uri =404;
}

Again, not sure if this is even possible, but it seems like it might be a fix if one of the devs could get it working.@buchdag

@buchdag
Copy link
Member

buchdag commented Jun 14, 2021

Disclaimer : I'm not a user of php-fpm and not really familiar with it

I'm having issues understanding if this "fpm-workaround" that keep being mentioned is something specific to nginx-proxy / some setup or something that has to be applied with nginx + php-fpm no matter what. Could someone point me to some doc regarding this ?

@PeterTucker
Copy link

@buchdag:

Based on the example by @flowl I have implemented https://github.com/tkw1536/nginx-proxy-fpm-workaround. This solution
does not require manually intervening in the nginx-proxy container. It additionally serves non-php files statically.

and ...
nginx-proxy/nginx-proxy#1466

... might help you.

@buchdag
Copy link
Member

buchdag commented Jun 14, 2021

Could you re explain to me how those new VIRTUAL_*_CONF would work ?

php:
    image:  php:fpm
    environment:
      VIRTUAL_HOST: example.com
      VIRTUAL_PROTO: fastcgi
      VIRTUAL_PORT: 9000
      VIRTUAL_ROOT: /var/www/html

      # Proposed variables to add to nginx-proxy:
      VIRTUAL_LOCATION_CONF: ./example.com_location.conf
      VIRTUAL_STATIC_CONF: ./example.com_static.conf

    volumes:
      - ./html:/var/www/html

Because either I did not get it, or the expected behaviour of those two new variables is already possible with two existing features, Per-VIRTUAL_HOST configuration for VIRTUAL_STATIC_CONF and Per-VIRTUAL_HOST location configuration for VIRTUAL_LOCATION_CONF.

Those two features automatically add the directives contained in specially named files respectively to the server and location / blocks corresponding to specific VIRTUAL_HOST (and only to those blocks corresponding to this specific VIRTUAL_HOST the files are named after).

This is why @tkw1536 is using /etc/nginx/vhost.d/example.com and /etc/nginx/vhost.d/example.com_location for the container that has VIRTUAL_HOST: example.com. If you don't have running container with a VIRTUAL_HOST that includes example.com, the example.com prefixed files inside /etc/nginx/vhost.d won't be included in the rendered nginx configuration.

@buchdag
Copy link
Member

buchdag commented Jun 14, 2021

@tkw1536 it should be taken care of where the files are coming from because SCRIPT_FILENAME is probably in a vendor file /etc/nginx/fastcgi_params or so.

@flowl I did not understand that part.

The missing configuration should be dynamically build into the resulting files, anything fixed or hardcoded is against the idea of the dynamic reverse proxy imo.

Isn't that what @tkw1536 proposed solution using per_VIRTUAL_HOST configuration and per-VIRTUAL_HOST location configuration does ?

@PeterTucker
Copy link

@buchdag @flowl @tkw1536 @SturmB

After a few weeks of experimenting, reading articles, and searching for an answer on how to setup a multiple wordpress/fpm setup with nginx-proxy, I was finally able to come up with a setup that works. No hacks needed. I hope this helps!

https://github.com/PeterTucker/multiple-docker-wp-fpm-nginx-proxy-setup

@VitalyLitvinov74
Copy link

VitalyLitvinov74 commented Feb 17, 2022

@PeterTucker
you can create your local fastcgi_params file as:

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name
fastcgi_param  REDIRECT_STATUS    200;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #new line

and import him to conteiner:

proxy:
    image: 'jwilder/nginx-proxy'
    container_name: 'reverse-proxy'
    ports:
      - '${PORT}:80'
    volumes:
      - './nginx/vhosts:/etc/nginx/vhost.d'
      - './nginx/config:/etc/nginx/conf.d'
      - '/var/run/docker.sock:/tmp/docker.sock:ro'
      - './nginx/certs:/etc/nginx/certs'
      - './nginx/fastcgi_params:/etc/nginx/fastcgi_params' #<-this!
php container:
 php:
    container_name: php
    build:
       context: ./php/
    environment:
      VIRTUAL_HOST: "${BACKEND}"
      VIRTUAL_ROOT: "/var/www/html/web"
      VIRTUAL_PROTO: fastcgi
      VIRTUAL_PORT: 9000
    volumes:
      - '../backend:/var/www/html'

but i do like this::

php-proxy:
  image: nginx
  container_name: php-proxy
  volumes:
    - './php/proxy/conf:/etc/nginx/conf.d'
  environment:
    VIRTUAL_HOST: "${BACKEND}"
  links:
    - php
  volumes_from:
    - php

php:
  container_name: php
  build:
     context: ./php/
  volumes:
    - '../backend:/var/www/html'

@rodrigoaguilera
Copy link
Contributor

I opened a MR to fix this #2011

Basically the old jwilder image used to include SCRIPT_FILENAME in the fastcgi_params file so fastcgi worked.
Luckily we can just include the more complete fastcgi.conf that sets the SCRIPT_FILENAME variable.
More details about the differences.
nginxinc/docker-nginx#298 (comment)

I guess at some point upstream nginx decided not to include that variable in fastcgi_params for the user to set it manually and have fastcgi.conf for a more complete and out-of-the-box config.

The examples still suggest that SCRIPT_FILENAME is included
https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/

@rodrigoaguilera
Copy link
Contributor

I just searched through the commits and there is some that actually revert the change
https://github.com/nginx-proxy/nginx-proxy/commits?author=qiqizjl
but there is not much context about why so it is difficult to find the reason behind those commits

@Boefjim
Copy link

Boefjim commented Apr 4, 2024

Any progress on this issue?
Currently I am also experiencing problems with the PHP fastcgi container not being properly proxied.
tkw1536's workaround container seems to be inaccessible, so I would have to overwrite the params manually otherwise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Issue reporting a bug
Projects
None yet