Tuesday, July 4, 2017

Nginx to serve php files from a different server

Leave a Comment

I am trying to configure nginx to serve PHP from another server.

The files can be located within a directory under /sample on the other server

Fast CGI is running on port 9000 on the other server

Here is what I have tried, which is not working at the moment.

location ~ [^/]\.php(/|$) {                 proxy_pass      http://192.168.x.xx;                 proxy_redirect http://192.168.x.xx /sample;                 fastcgi_split_path_info ^(.+?\.php)(/.*)$;                 if (!-f $document_root$fastcgi_script_name)                 {                         return 404;                 }                 # Mitigate https://httpoxy.org/ vulnerabilities                 fastcgi_param HTTP_PROXY "";                 fastcgi_read_timeout 150;                 fastcgi_buffers 4 256k;                 fastcgi_buffer_size 128k;                 fastcgi_busy_buffers_size 256k;                 fastcgi_pass 127.0.0.1:9000;                 fastcgi_index index.php;                 include fastcgi_params;                 fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;         } 

I also need to configure nginx to serve static files from the same server

3 Answers

Answers 1

You don't have to use proxy_ directives, because they work with HTTP protocol, but in this case FastCGI protocol is used. Also, as it was said in comments, no need for if statement, because Nginx server cannot determine if the file on a remote server exists.

You could try this configuration:

location ~ [^/]\.php(/|$) {     fastcgi_split_path_info ^(.+?\.php)(/.*)$;     # Mitigate https://httpoxy.org/ vulnerabilities     fastcgi_param HTTP_PROXY "";     fastcgi_read_timeout 150;     fastcgi_buffers 4 256k;     fastcgi_buffer_size 128k;     fastcgi_busy_buffers_size 256k;     fastcgi_pass 192.168.x.xx:9000;  #not 127.0.0.1, because we must send request to remote PHP-FPM server     fastcgi_index index.php;     include fastcgi_params;     fastcgi_param  SCRIPT_FILENAME /path/to/site/root$fastcgi_script_name; } 

You will need to replace /path/to/site/root with a real path on the PHP-FPM server. For example, if the request http://example.com/some/file.php must be handled by /var/www/some/file.php, then set it like this:

fastcgi_param  SCRIPT_FILENAME /var/www$fastcgi_script_name; 

Also, to make PHP-FPM server be able to receive requests from outside, edit your FPM pool configuration (on Debian it usually located in /etc/php5/fpm/pool.d/www.conf, on Centos - /etc/php-fpm.d/www.conf):

Replace

listen = 127.0.0.1:9000 

with:

listen = 9000 

or:

listen = 192.168.x.xx:9000 # FPM server IP 

Probably you will also need to edit allowed_clients directive:

listen.allowed_clients = 127.0.0.1,192.168.y.yy # Nginx server IP 

I also need to configure nginx to serve static files from the same server

If I understand correctly, and you want to serve static files from the server, Nginx is working on, then you may just add another location to your Nginx configuration.

Answers 2

You should not use proxy_* directives. using Nginx as a proxy would be done only if a distant server has rendered the page (and you would request it with HTTP protocol).

Here the thing you want to proxy is a fastcgi server, not an HTTP server.

So the key is:

fastcgi_pass 127.0.0.1:9000; 

Where you currently say you want to reach a fastcgi server on IP 127.0.0.1 port 900, which seems quite wrong.

Use instead:

fastcgi_pass 192.168.x.xx:9000; 

And remove proxy_* stuff.

Edit: also, as stated in comments by @Bart, you should not use an if testing that a local file in the document root, matching the php script name does exists. The php files are not on this server. So remove this file. If you want to apply some security check, you would, later, alter your very generic location [^/]\.php(/|$) to something more specific, like location=/index\.php, or some others variations.

Answers 3

The following configuration does exactly what you need:

server {     listen 80;     index index.php index.html;     server_name localhost;     error_log  /var/log/nginx/error.log;     access_log /var/log/nginx/access.log;     root {STATIC-FILES-LOCATION};      location ~ \.php$ {         try_files $uri =404;         fastcgi_split_path_info ^(.+\.php)(/.+)$;         fastcgi_pass {PHP-FPM-SERVER}:9000;         fastcgi_index index.php;         include fastcgi_params;         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;         fastcgi_param PATH_INFO $fastcgi_path_info;     } } 

All you have to do is replace {STATIC-FILES-LOCATION} with the location of your static files on the Nginx server and {PHP-FPM-SERVER} with the IP of the PHP-FPM server.

This way you will serve all files without the PHP extension statically from the Nginx server and all the PHP files will be interpreted with the PHP-FPM server.

Here's a working example of a dockerised version of what you are trying to achieve - https://github.com/mikechernev/dockerised-php/. It serves the static files from Nginx and interprets the PHP files via the PHP-FPM container. In the accompanying blog post (http://geekyplatypus.com/dockerise-your-php-application-with-nginx-and-php7-fpm/) I go in lengths about the whole connection between Nginx and PHP-FPM.

EDIT: One important thing to keep in mind is that the paths in both the Nginx and PHP-FPM servers should match. So you will have to put your php files in the same directory on the PHP-FPM server as your static files on the Nginx one ({STATIC-FILES-LOCATION}).

An example would be to have /var/www/ on Nginx holding your static files and /var/www on PHP-FPM to hold your php files.

Hope this helps :)

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment