I have two servicesr accessible via NginX. The web server configuration looks like this:
location /service1/ {
# process php files
}
location /service2/ {
proxy_pass http://127.0.0.1:9999/;
}
However, if one clicks on https://example.com/service1 (or 2) he gets a 404 error. There is no folder called "service1" (or 2) in the website root.
I would like links to "https://example.com/service1" to point to "https://example.com/service1/" (with trailing slash), possibly without specyfing a redirect for every service I have, i.e
location = /service1 {
return 301 https://$host/service1/;
}
location /service1/ {
# process php files
}
location = /service2 {
return 301 https://$host/service2/;
}
location /service2/ {
proxy_pass http://127.0.0.1:9999/;
}
I have already tried try_files $uri $uri/ =404;, but it seems to only work for real files and folders in the website root, no "virtual" subdirectories.
I am avoiding configurations like location /service { ... } because they seem more vulnerable.
Inside your location = blocks you need to generate an internal redirect to $uri/. You can achieve this using try_files or rewrite...last.
For example:
location = /service1 {
try_files nonexistent $uri/$is_args$args;
}
Notice that the internal redirection must be the last parameter. See this document for details.
Or:
location = /service1 {
rewrite ^(.*)$ $1/ last;
}
See this document for details.
Related
I am running any Nginx file server. I have 2 main folders i.e. folder-a and folder-b. If a user tries to land on /folder-a/abc and it's a 404, I should auto-redirect to another folder like /folder-b/abc. How do I set up such a rule in Nginx? My top folder names will always be hard-coded names like folder-a and folder-b.
As being said by #RichardSmith, if you want to look for a file in one of two locations, you can use try_files directive:
location ~ ^/folder-a(?<suffix>/.*) {
try_files $uri $uri/ /folder-b$suffix /folder-b$suffix/ =404;
}
If you want to generate an HTTP redirect, you can use error_page directive with the additional named location:
location ~ ^/folder-a(?<suffix>/.*) {
error_page 404 #redirect;
}
location #redirect {
return 301 /folder-b$suffix;
}
If you have some additional configuration directives in your root location (location / { ... }), you should either duplicate them inside the location ~ ^/folder-a(?<suffix>/.*) { ... } or move them to the server context if there are no other locations where those directives should not be applied.
I have configured nginx to serve static page as below.
location /home {
alias /home/username/files/home;
try_files $uri /home/index.html;
}
Only index.html loads on http://example.com/home. All other css, js and image files are getting 404 as request is still going for http://example.com/css/style.css instead of http://example.com/home/css/style.css. Is there any way I can configure /home prefix to all the static file without manually adding to all static files?
You can try to use variable root depending on HTTP Referer header (although it is a dirty hack):
map $http_referer $root {
~example\.com/home/ /home/username/files/home;
default <your default root here>;
}
server {
...
root $root;
location /home {
root /home/username/files;
try_files $uri /home/index.html;
}
}
Note that if any of your web pages under /home/ have a links to the main site, those links won't work correctly because of example.com/home/... HTTP Referer header value.
Why root /home/username/files; instead of alias /home/username/files/home;, you ask? Because as nginx documentation states:
When location matches the last part of the directive’s value:
location /images/ {
alias /data/w3/images/;
}
it is better to use the root directive instead:
location /images/ {
root /data/w3;
}
Can anybody please help me to remove first directory name from URL?
My Image location is _data/hotel/3/15377/hotel_image.jpg
But Image path gets changed due to relative URL in code and it become to something like this.
example.com/france/_data/hotel/3/15377/hotel_image.jpg
example.com/usa/_data/hotel/3/15377/hotel_image.jpg
example.com/india/_data/hotel/3/15377/hotel_image.jpg
is their any possibilities to remove dynamic country name from above URL
If you want to rewrite only this particular URL, you can use this location block in your config:
location ~ /[a-z]+/_data/hotel/3/15377/hotel_image.jpg {
try_files /_data/hotel/3/15377/hotel_image.jpg;
}
If you want to rewrite all URLs which lead to /<country>/_data/..., you can use:
location ~ /[a-z]+/_data/(.+) {
try_files /_data/$1;
}
or for stricter URL checking:
location ~ /(?:france|usa|india)/_data/(.+) {
try_files /_data/$1;
}
#Ivan Shatsky's answer is great for files but also if we want to redirect a general url is better if you use the rewrite directive.
Depending where you define the rewrite directive you have two ways to implement it:
A. In the server context
server {
...
rewrite ^/[a-z]+/_data/(.+)$ /_data/$1 last;
...
}
B. In the location context
location ~ /[a-z]+/_data/(.+) {
rewrite ^/[a-z]+/_data/(.+)$ /_data/$1 break;
proxy_pass http://backend;
}
Teo, why did you change the flag to break?* Because, if this directive is put inside of a location context, the last flag might make nginx to run 10 cycles and return the 500 error.
Note:
Remember not add / at the end of the proxy_pass directive. This example wont work:
...
proxy_pass http://backend/;
...
I need to serve file from my filesystem for GET / request. I tried the following:
location = / {
index page2257160.html;
root /var/www/site/;
}
The rest of requests are proxied to backend:
location / {
proxy_pass http://localhost:1234;
}
But when I do the request, instead of serving the file from filesystem, nginx asks backend about /page2257160.html, backend returns 404, nginx sends this 404 back to client.
How can I fix this?
The index directive performs an internal redirect, so you will need a second location to match the rewritten URI. For example:
root /var/www/site/;
location = / {
index page2257160.html;
}
location = /page2257160.html {
}
See this document for details.
You can achieve the same thing with one location block and a try_files directive. For example:
location = / {
root /var/www/site/;
try_files /page2257160.html =404;
}
See this document for more.
I have a valid url of the type http://example.com/valid/. Using nginx how do i redirect a url of type http://example.com/valid/dsdhshd to my valid url?
I tried:
location /valid/ {
resolver 8.8.8.8;
proxy_pass http://example.com/valid/;
proxy_redirect off;
}
But it gives a 500 internal server error.
I also tried location return 301 $scheme://example.com/valid/; but this just put me in an infinite redirection loop.
If you want to send the redirect to the client, don't proxy the request and simply send it.
server {
# Your server configuration ...
# Enclose regular expressions in default location.
location / {
location /valid {
location ~ /valid/.+ {
try_files $uri #invalid;
}
# Handle the request to the valid URL ...
}
}
location #invalid {
return 301 $scheme://$server_name/valid;
}
}
That should do the trick. You did get a redirect loop because your location block also matched the /valid/ URL itself, something you don't wanted to match. You only want to match URLs which have something after that string, e.g. /valid/foo. That is exactly what the regular expression in the location block above is ensuring.
here's a sample i could think about
server {
location /valid {
try_files $uri $uri/ #redirect_invalid;
}
location #redirect_invalid {
return 301 $scheme://$server_name/valid;
}
}
But this will be very specific and if there's many folders you'll need to add each separately, I can't think of a method to make this generic for all folders, maybe someone else could help me with this.