I'm trying to route a specific URL to another folder in my application root, which I can do with this:
location /verify {
alias /var/www/app/webroot/vue-dist;
index index.html
try_files $uri $uri/ /index.html =404;
}
The above routes example.com/verify to its correct folder just fine. However, I'm having trouble adding a dynamic variable to the end.
For example, I'm trying to append an ID to the end of that: example.com/verify/yDWaAzF4qqy. I've tried this without any luck:
location ~ ^/verify/(?<id>.*)$
I'm not super familiar with Nginx and how it handles regex so any help would be greatly appreciated.
Related
I'm quite new to Nginx so I might be misunderstanding of what try_files can do.
For my local development set up I have multiple installations that will each be accesible via their own subdomain. These installations are being migrated into a new folder structure but I still want to have the ability to support both at the same time. When pulled via git the new full path looks like this :
/home/tom/git/project/v3/[installation]/public/
The old structure goes 1 directory deeper namely as follows:
/home/tom/git/project/v3/[installation]/workspace/public
Where installation is variable according to the installation name and the /public folder will be the root for nginx to work from.
The root is determined by the subdomain and is extracted via regex like so:
server_name ~^(?<subdomain>[^.]+)\.local\.project\.test;
So far I've managed to get all this working for one of the folder structures but not both at the same time. My Nginx configuration for this local domain looks like this. Below is what I've tried but just can't seem to get working. As soon as I pass the #workspace named location as fallback for try_files it always defaults to 404.
index index.html index.htm index.nginx-debian.html index.php;
server_name ~^(?<subdomain>[^.]+)\.local\.project\.test;
root /home/tom/git/project/v3/$subdomain/public/;
location / {
try_files $uri #workspace =404;
}
location #workspace {
root /home/tom/git/project/v3/$subdomain/workspace/public/;
try_files $uri =404;
}
I have also tried shortening the root and passing the following parameters to try_files
root /home/tom/git/project/v3/$subdomain;
location / {
try_files /public/$uri /workspace/public/$uri =404;
}
But this still defaults to a 404, with a $uri/ as a third parameter there it will emit a 403 forbidden trying to list the directory index of the root.
I hope someone can provide some advice or an alternative as to how to approach this issue I am facing. If I need to provide additional data let me know,
Thanks in advance.
The named location must be the last element of a try_files statement.
For example:
location / {
try_files $uri #workspace;
}
location #workspace {
...
}
See this document for details.
The $uri variable includes a leading /, so your constructed pathnames contain a // which may be why they fail.
For example:
location / {
root /home/tom/git/project/v3/$subdomain;
try_files /public$uri /workspace/public$uri =404;
}
I already make extensive use of rewrite in nginx to perform this sort of thing:
/photos/123344 -> /photos/photos.php?id=123344
/photos/london-2016 -> /photos/photo-shoot.php?name=london-2016
Currently I have no rule for other (non-dynamic) pages. E.g
/photos/shoot-register.php -> /photos/shoot-register.php
Which I'd like to become
/photos/shoot-register.php -> /photos/shoot-register
But without specifying an individual rewrite rule for each .php file.
It seems that try_files is the correct directive here:
location ~ ^/photos {
try_files $uri $uri.php?$args;
rewrite ^/photos/([0-9]+)(/?)$ /photos/photo.php?id=$1;
rewrite ^/photos/([^/\.]+)(/?)$ /photos/photo-shoot.php?name=$1;
}
But this doesn't work, unless I delete the two rewrite lines.
I assume that means that execution doesn't stop after try files? It finds "shoot-register.php" but then carries on executing and ends up with /photos/photo-shoot.php?name=shoot-register.php?
How can I make it stop after try_files succeeds in finding a match?
Thanks
what if you move the rewrites to separate named location, and then change your try_file directive to try the file, then the php file and then directing to the new location?
location ~ ^/photos {
try_files $uri $uri.php?$args #rewrites;
}
location #rewrites {
rewrite ^/photos/([0-9]+)(/?)$ /photos/photo.php?id=$1;
rewrite ^/photos/([^/\.]+)(/?)$ /photos/photo-shoot.php?name=$1;
}
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.
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.
My url looks like this:
http://site.ru/web/index.php?r=api%2Finit&user_id=1&extension_id=test
And I want rewrite it using Nginx to:
http://site.ru/api/v1/?action=init&user_id=1&bot_extension_id=test
That is, rewriting index.php?r=api only, without touching other values for r.
This is what I've tried, it isn't working though
location / {
rewrite /web/index.php?r=api%2F(.*?) /api/v1/?action=$1;
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php?$args;
}