Nginx same config for multiple paths - nginx

I'd like to configure several paths within a site (such as /foo/ and /bar/) in the same way. To avoid copy-pasting, I figured I should use a single location block, but the only way I found for doing that is to use a regex, such as:
location ~ ^/(foo|bar)/ {
...
}
Is this the best way or is there a better alternative?

This would work, but I believe it works slower, because it involves a regex engine, another alternative you could create the config you want in a separate file and include them in each location so that it would be written once and could be edited all together, like this
location /foo {
include foo.conf;
}
location /bar {
include foo.conf;
}
Inside foo.conf you could write any config that's in a location scope
heres a random sample snippet:
root /foo/bar;
try_files $uri /index.html;

Related

Nginx Configuration for Dynamic URL Segments as Arguments for Parent Segment Index

I am trying to set a location in the configuration that allows me to do something like https://example.com/car/<vin> which would not go to a <vin> application or directory but to /car/index.html. From there, I would read the URL or pass <vin> to /car/index.html.
I have tried various regex location blocks, like the one below, but they all result in a 404 when accessing /car/<vin>.
location ~ ^/car/(.*)$ {
root $document_root/car/
index index.html;
}
What would be an appropriate location block?
Do you want to use a regular expression? The prefix location would also work as it matches any URI that begins with /car/. See this document for details.
For example:
location ^~ /car/ {
try_files /car/index.html =404;
}
Using $document_root in the root statement may not work, and the index directive only works with URIs that end with a /. The try_files statement is probably the simplest solution. See this document for details.

convert url segment to get variable keeping others get variables

I can't fix that I have a url
domain.com/api/class/access/1/index.php?username=usuariodemo&name=sala
where /1/ is a ID so, I need convert /1/ to get variables like
domain.com/api/class/access/index.php?id=1&username=usuariodemo&name=sala
That is pure PHP not framework my index.php is located on folder api/class/access/index.php
I have this I try others but this explain me better waht I want do
location /api/class/access/(.*)/* {
try_files $uri $uri/ /api/class/access/index.php?id=$1&$query_string;
}
That show me:
No input file specified.
Thanks!
Regards!
The location statement in your question is invalid and probably unnecessary.
If you want to rewrite a URI ending with .php it may be easiest to place a rewrite statement inside the block that processes all .php URIs, usually: location ~ \.php$ { ... }.
For example:
location ~ \.php$ {
rewrite ^(/api/class/access/)(\d+)/(index.php)$ $1$3?id=$2 last;
...
}

Rewrites in Nginx

I need to enter a bunch or rewrites in my conf file in Nginx. I am not very experienced so I copied what I found before, example.
location = /index.php/blog/blog/xxx/yyy/ {
return 301 /index.php/blog/xxx/yyy/;
}
However I was told that the best way is the following:
location ^~ /index.php/blog/blog/xxx/yyy/ {
rewrite ^/index.php/blog/xxx/yyy/;
}
Which one id the correct one?
The first one is more correct, both location as well as the return -wise, and it'll work faster.
FWIIW, your second snippet looks like it's missing a space in the rewrite after ^, and it's also less efficient, both location as well as rewrite-wise.
References:
http://nginx.org/r/location
http://nginx.org/r/return
http://nginx.org/r/rewrite

How can I have same rule for two locations in NGINX config?

How can I have same rule for two locations in NGINX config?
I have tried the following
server {
location /first/location/ | /second/location/ {
..
..
}
}
but nginx reload threw this error:
nginx: [emerg] invalid number of arguments in "location" directive**
Try
location ~ ^/(first/location|second/location)/ {
...
}
The ~ means to use a regular expression for the url. The ^ means to check from the first character. This will look for a / followed by either of the locations and then another /.
Another option is to repeat the rules in two prefix locations using an included file. Since prefix locations are position independent in the configuration, using them can save some confusion as you add other regex locations later on. Avoiding regex locations when you can will help your configuration scale smoothly.
server {
location /first/location/ {
include shared.conf;
}
location /second/location/ {
include shared.conf;
}
}
Here's a sample shared.conf:
default_type text/plain;
return 200 "http_user_agent: $http_user_agent
remote_addr: $remote_addr
remote_port: $remote_port
scheme: $scheme
nginx_version: $nginx_version
";
Both the regex and included files are good methods, and I frequently use those. But another alternative is to use a "named location", which is a useful approach in many situations — especially more complicated ones. The official "If is Evil" page shows essentially the following as a good way to do things:
error_page 418 = #common_location;
location /first/location/ {
return 418;
}
location /second/location/ {
return 418;
}
location #common_location {
# The common configuration...
}
There are advantages and disadvantages to these various approaches. One big advantage to a regex is that you can capture parts of the match and use them to modify the response. Of course, you can usually achieve similar results with the other approaches by either setting a variable in the original block or using map. The downside of the regex approach is that it can get unwieldy if you want to match a variety of locations, plus the low precedence of a regex might just not fit with how you want to match locations — not to mention that there are apparently performance impacts from regexes in some cases.
The main advantage of including files (as far as I can tell) is that it is a little more flexible about exactly what you can include — it doesn't have to be a full location block, for example. But it's also just subjectively a bit clunkier than named locations.
Also note that there is a related solution that you may be able to use in similar situations: nested locations. The idea is that you would start with a very general location, apply some configuration common to several of the possible matches, and then have separate nested locations for the different types of paths that you want to match. For example, it might be useful to do something like this:
location /specialpages/ {
# some config
location /specialpages/static/ {
try_files $uri $uri/ =404;
}
location /specialpages/dynamic/ {
proxy_pass http://127.0.0.1;
}
}
This is short, yet efficient and proven approach:
location ~ (patternOne|patternTwo) {
#rules etc.
}
So one can easily have multiple patterns with simple pipe syntax pointing to the same location block / rules.
This worked for me
upstream nextjs-fp {
server nextjs-frontend:3000;
}
server {
listen 80;
location ~* .(_next|profile|orders)$ {
proxy_pass http://nextjs-fp;
}
}

Display default image when missing file in nginx

We have various pictures associated with items on our site but not for all of them. To this end we would like to display the contents of 'blank.jpg' if a given image is not found.
To this end we have the nginx config like this
location /static/images/ {
root /blah_blah_blah/pictures/;
error_page 404 blank.jpg;
break;
}
The problems with this is that this takes /static/images/fred.jpg and redirects to /static/images/blank.jpg when what we want is to simply display the contents of blank.jpg whilst keeping the /static/images/fred.jpg url
It also seems to go into a redirect loop occasionally.
Not sure if you still need it 10 month later but this looks like what you were looking for: https://serverfault.com/questions/562269/redirect-missing-images-in-a-specific-directory
I'd like to share a little bit more sophisticated example. It's a way how you can match only selected extensions or name patterns:
location ~ ^/media/(.*)/preview(.*).(png|mp4)$ {
try_files $uri #rewrite;
}
location #rewrite {
rewrite ^/media/(.*)/preview(.*).(png|mp4)$ $scheme://$host/media/no_preview/preview$2.$3 redirect;
}

Resources