Use try_files with different document roots - nginx

I know there is a suggested solution in How to use try_files with 2 or more roots but it does not quite fit what I try to achieve.
We are in the process of migrating a big old webserver with 100,000s of pages to a new webserver. During this process we update the content. The directory for the new content was created from scratch. While we are updating the content we want to make sure that if something is missing in the new folder it can be retrieved from the old one.
My simplified folder structure looks like this:
/mnt/oldcontent
/var/opt/data/company/newcontent
For our scenario the ideal solution would be if we could do something like this:
location / {
try_files /var/opt/data/company/newcontent/$uri /mnt/oldcontent/$uri ...;
}
I know this is invalid syntax.

Your solution would need the root to be set to the root of the filesystem.
As a location can only serve a single root, you could use a named location to try the other one.
For example:
root /var/opt/data/company/newcontent;
location / {
try_files $uri $uri/ #oldcontent;
}
location #oldcontent {
root /mnt/oldcontent;
try_files $uri =404;
}
See this document for details.

Related

What is difference between using $uri and $uri$args in try_files directive

For my other Angular apps, I am using the below config and everything seems to work fine.
location / {
try_files $uri$args $uri$args/ /index.html;
}
Now the one which I am working has nested folders within the dist folder.
And folder structure is something like:
dist \
-- assets
-- folder1
-- folder2
-- folder3
-- folder4
-- folder5
index.html
index.html
And the inner index.html is called with query params, and the url will be like - <ip>/folder1/folder2/index.html?a=1&b=2&c=3. But this is returning the fallback index.html at the root location. Later, I changed the above location block like this and it started working properly.
location / {
try_files $uri $uri/ /index.html;
}
So I am not clear why the first location block didn't work. And I can't find anything in docs - try_files
All of the parameters of a try_files statement except the last parameter are looking for filenames in the local file system.
So given the URI /foo/bar, the term $uri$args will search for a local file at /path/to/root/foo/bar, and if it does not exist will move on to the next term or the default clause at the end of the statement.
In the above case, $args is empty. However, given the URI /foo/bar?baz, the term $uri$args will search for a local file at /path/to/root/foo/barbaz.
I don't know why anyone would use $uri$args or $uri$args/ as file terms on a try_files statement, but there may well be a legitimate use case.
The last parameter of a try_files statement is special. It can be a status code (for example =404), a named location to branch to, or a URI.
In the case of a URI, Nginx will internally redirect to that URI. A typical example might be /index.php$isargs$args - in this case it is perfectly legitimate to append the $args parameter, as we are creating a new URI and keeping the original argument string.
See this document for details.

Nginx location alias with dynamic parameter

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.

How do I correctly use try_files when looking in two different directories for files to serve?

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;
}

Nginx, render a file with dynamic name

I have a cachebreaker that produces css filenames as this one: /css/vendor.min.333311133.css.
I want nginx to answer request with a previous version with the latest.
Note that I will only have one version of that file in the directory... so I'm thinking of a rule like the following, but it's not working:
location ~* /css\/vendor\.min\.(.*)\.css {
try_files $uri ~* /css\/vendor\.(.*)\.css =404;
}
Does anybody knows if nginx support dynamic names in try_files? Or should I use another directive? Any ideas?
If your build process is able to do this, just put the file there without the cachebreaker part and do this:
location ~* /css\/vendor\.min\.(.*)\.css {
try_files /css/vendor.min.css =404;
}
In theory you can use a regex capture inside the location, but since the old version number would be in there, it would not help.

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