Nginx - changing root folder for specific url gives 404 error
I am trying to arrange a location block for anyone get through mydomain.com/game/admin
url, make sure the nginx server to pull the content exists in /var/www/html/my-cakephp-app/
directory. My application is built using cakephp framework and its directory structure is shown below:
- /var/www/html/my-cakephp-app/
- admin
- Config
- Console
- Controller
- View
- webroot (App entry-point index.php file exists in this directory)
Also I have static html/css website located in the /var/www/html
directory. So anyone with mydomain.com
url can see that website too.
Here is my current nginx server block:
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.html index.htm index.php;
server_name mydomain.com;
location / {
try_files $uri $uri/ =404;
}
location /game/admin {
return 301 /game/admin/;
}
location /game/admin/ {
root /var/www/html/my-cakephp-app/admin/webroot;
try_files $uri $uri/ /game/admin/index.php$is_args$args;
location ~* \.php(/|$) {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
With this setup, my static web-site working fine. But cakephp application gives 404 not found error in browser. No any errors in the nginx/error.log.
But when I run with below nginx configuration, my application works fine. But I have to get rid of my html/css site.I am planning to upgrade html/css app with a wordpress site. So I should have the ability to run the wordpress site as the parent.
server {
listen 80;
server_name mydomain.com;
root /var/www/html/my-cakephp-app/admin/webroot;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php$is_args$args;
autoindex on;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
I couldn't think of what I have done wrong with the first server block. Any suggestions would be really helpful.
Solution 1:
The two main problems are:
- the outer
location ~ \.php$
block takes precedence over thelocation /game/admin/
block unless you use the^~
modifier (see this document for details) - the
root
directive generates a path to the file by simple concatenation, so your controller is expected to be located at/var/www/html/my-cakephp-app/admin/webroot/game/admin/index.php
(see this document for details)
One option is to move the project so that the directory structure matches the URI structure. This could be achieved using a symbolic link which points /var/www/html/game/admin
to /var/www/html/my-cakephp-app/admin/webroot
in which case the outer location ~ \.php$
block will be able to execute both projects.
Another option is the alias
directive. See this document for details.
location ^~ /game/admin {
alias /var/www/html/my-cakephp-app/admin/webroot;
if (!-e $request_filename) { rewrite ^ /game/admin/index.php last; }
location ~ \.php$ {
if (!-f $request_filename) { return 404; }
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
Note that $document_root$fastcgi_script_name
will not work with alias
and that $request_filename
should be used instead.
I avoid using alias
and try_files
together due to this issue. See this caution on the use of the if
directive.