Nginx Reason for $uri/ - wordpress

I am looking at standard nginx server config for wordpress.
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
I understand the reason for $uri index.php$is_args$args
I do not understand the point of $uri/
I can see from nginx documentation "It is possible to check directory’s existence by specifying a slash at the end of a name, e.g. “$uri/”"
But I don`t get, what is the reason for returning a directory on request? Why would this be useful in a wordpress setup?

There is no such thing as "returning a directory on request". But trying to examine contents of a directory, and use them in order to satisfy a request - that's what it is here.
NGINX always has some non-empty value for the index directive (default is index.html), and that's essentially the files that NGINX will attempt to serve when trying a directory.
You don't really need $uri/ for WordPress if both conditions are met:
you don't have custom subdirectories/subsites which hold PHP files
you are using pretty permalinks
Removing $uri/ will result in saving one or more system stat calls (file existence check), so it is a performance improvement. The special case there would be a link /wp-admin. With try_files $uri /index.php$is_args$args it will be processed through /index.php, but Wordpress will do a proper redirect to /wp-admin/ (with slash).
And for what it's worth, you don't even need try_files if you have a habit of maintaining a well-structured website and intend to make it more optimized.

Related

How can i use NGINX try_files without changing the browser location for the client?

I am using nginx try_files for Server-Side-Rendering. Since GET-parameters affect the resulting html, i want to use try_files to check if i have a prerendered version with the matching query string (file is saved at /posts/?page=5/index.html)
I have the following try_files statement in place:
try_files $uri/$is_args$args/ $uri $uri/ #ssr;
This works, but the client gets redirected to www.page.com/posts/?page=5 which is including the slash of the subdirectory i have. This results in the browser getting a 404 in the end, because that post does not exist.
How can i use try_files like i did, but without actually redirecting the client? To be clear: I want to serve files from whereever with try_files, but not actually let the client know which file is served, thats none of the browsers business in my case.
Is there a way to achieve this?

try_files vs an empty location block in NGINX?

Wondering about the difference between doing:
location / {
try_files $uri $uri/ =404;
}
And doing:
location / {}
They both seem to serve files\folders only if they exist, or returning 404 error page if they don't.
There is no difference, try_files $uri $uri/ =404; is exactly the default nginx behavior:
Check if $document_root$uri is a file, and if it is, serve the request with the contents of this file;
Check if $document_root$uri is a directory, and if it is, serve the request with the first found index file from this directory. If no index files found, nginx will return directory list if you have autoindex on in your nginx config or HTTP 403 Forbidden error otherwise;
Return HTTP 404 Not found if $document_root$uri nor a file neither a directory.
Advantage of the try_files directive is that you can specify additional files/directories to check and select what to do if none of them are found (jump to another URI / jump to some named location / return any HTTP error code).
However try_files may give you some performance penalty depending of your settings, read this article by #DanilaVershinin for more details.

nginx Sinatra head meta refresh 404

For some reason, a page is forwarding to an nginx-served 404 page. The site is working except for this one page. On my landing page, I have the following in the header:
<meta http-equiv="refresh" content="5;URL=/second">
Even hard coding http://mydomain.local/second serves up the same 404.
This is a Sinatra deployment.
get "/second" do
#title = "my Title"
erb :index
end
I am thinking maybe my locations directive in nginx.conf is a bit screwy:
location / {
autoindex off;
try_files $uri $uri/ $uri/$request =404;
index /;
}
Anybody have any insight why Sinatra wouldn't capture the route and just serve up the file? Cheers.
Lets break this down:
autoindex off;
You don't need to specify this, it's off by default.
try_files $uri $uri/ $uri/$request =404;
Try and match requests to files in this order, serve the first one which matches. If none match, return 404. Your request is http://mydomain.local/second, so you are telling Nginx to look for:
webroot/second
webroot/second/
webroot/second/GET /second HTTP/1.1
Return 404
The index directive tells Nginx how to handle requests ending with a slash, you would normally specify files likely to be index files within your project, eg index.php, index.html etc. You don't really use this and try_files together as they serve a similar purpose.
Also worth noting that Nginx adds a trailing slash to any request which doesn't have one and doesn't end with a file extension, so it may also be the case that get "/second" do needs to change to get "/second/" do, as I doubt Sinatra ever sees the request without the trailing slash appended

nginx match specific file from different folder on certain routes

I have an angularjs app, it has a blog as well. This url shows all blog posts under
http://example.com/blog/
And specific blog posts under
http://example.com/blog/example-blog-post-title
Now i'm precompiling HTML of blog posts for SEO purposes and i want to serve them completely separately from my main app like this:
...
root "/home/ubuntu/client/public";
location / { ## Handle default requests ##
try_files $uri $uri/ /index.html;
}
location /blog { ## serve precompiled blog HTML
alias /home/ubuntu/bloghtml;
try_files $uri.html $uri/ index.html;
}
...
And this works, by going to http://example.com/blog/example-blog-post-title nginx successfully serves file /home/ubuntu/bloghtml/example-blog-post-title.html
However the issue is that in this case nginx doesn't correctly route blog post list under http://example.com/blog/ to my main angular app, i get error 403 on that URL.
I tried changing location /blog to location /blog/ in conf file, this makes the http://example.com/blog/ work, howewever i get 404 errors on http://example.com/blog/example-blog-post-title
How can i make this work for both cases?
If you change the location from /blog to /blog/ you need to remember to change alias from /home/ubuntu/bloghtml to /home/ubuntu/bloghtml/. The alias and location need to have the same ending, otherwise the calculated pathnames are wrong.
I try to avoid using alias and try_files in the same block because of some known issues. You might consider making the last directory in the path blog so that you can use root instead.
I presume that your angular app is /index.html, in which case your try_files statement is incorrect. The $url/ will cause it to try /blog/index.html (assuming you have an index directive in force) and index.html is missing a leading /.
I would suggest you try:
location /blog {
alias /home/ubuntu/bloghtml;
try_files $uri.html /index.html;
}
but consider designing out the alias directive too.

nginx with site in a subdir which does not match the ends of url

When I try to use laravel PHP framework, I try to place it in a dir called /home/usr/proj/laravel, but as we know that the public html of laravel is settled in /home/usr/proj/laravel/public, thus my problem is how to make the setting of nginx such that when I access by mysite.com/laravel/ or mysite.com/laravel, we in fact redirected to the location laravel/public/index.php.
Also, it seems that there is a rule of nignx which is suggested by the official of laravel, to make the url looks pretty
location / {
try_files $uri $uri/ /index.php?$query_string;
}
How can I use this in my case?
UPDATE
It seems the following code works for me (but give me error NotFoundHttpException in RouteCollection.php line 145:, maybe caused by my router setting)
location /laravel{
root /home/usr/proj/laravel/public;
index index.php index.html;
try_files $uri $uri/ /laravel/public/index.php?$query_string;
}
Regarding your Update, I think that you should keep your original try_files syntax:
try_files $uri $uri/ /index.php?$query_string;
since the location is set to /laravel and the root is in the public folder. The way it is currently written ends up looking for file /home/usr/proj/laravel/public/public/index.php in the disk.
You should also check to configure your application URL so that it contains the /location part of the URL. I am not quite sure about how Laravel 5 is configured since my experience is with Laravel 4.

Resources