Unable to set up Nginx to handle PHP along with proxy_pass
I have three requirements from my Nginx setup:
- Forward all requests on / to my Java server running on port 9001
- Intercept all static file URLs and serve them through Nginx itself.
- Serve a particular base URL from a folder containing PHP scripts.
Of these, I'm able to achieve the first two, but when I visit http://localhost/ecwid_fu_scripts/
through my web browser, the request is intercepted by the Java server running on port 9001, and doesn't get routed to the index.php
in /home/ankush/ecwid_fu_scripts/
. Here's my Nginx configuration:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location /assets/images/ {
root /home/ankush/fu_main_files/;
autoindex off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 100;
}
location /ecwid_fu_scripts/ {
index index.php;
root /home/ankush/ecwid_fu_scripts/;
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location / {
proxy_pass http://localhost:9001;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
Solution 1:
Your issue is with the root
directive, and the scope of this root
.
location /ecwid_fu_scripts/ {
root /home/ankush/ecwid_fu_scripts/;
In this case, when someone requests example.com/ecwid_fu_scripts/, nginx is looking for the files in the defined root
, plus the location. This becomes /home/ankush/ecwid_fu_scripts/ecwid_fu_scripts/, which is not where your index.php is located.
To solve this, you have two choices (with #2 being the preferred option, if you have freedom over your project):
- Change the
root
of that location block to /home/ankush/ instead. -
Or restructure your project structure so everything is in one relative project folder. Now, set the global
root
-- the directive outside of any location block -- to the new project folder name (let's sayroot /home/ankush/ecwid_files/;
, after theserver_name
directive).
Now, we still need to add the contents of the location ~ \.php$
block inside the location /ecwid_fu_scripts/
block, because when the root
is changed, things relating to this new root needs to used in the same block. This is because of this type of pitfall: the location block for ecwid_fu_scripts is saying it's a .php file, it does try_files, and then it finishes with this block, and sent off to the next-related block: the global location ~ \.php$
. Problem is, it doesn't know what the root
is anymore, since it isn't defined globally. Thus, fastcgi_pass in this block isn't getting the full path.
So in the end, your config will look like this with option #1:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location /assets/images/ {
root /home/ankush/fu_main_files/;
autoindex off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 100;
}
location /ecwid_fu_scripts/ {
index index.php;
root /home/ankush/;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location / {
proxy_pass http://localhost:9001;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
}