Nginx multiple static route - nginx

Directory Structure:
project
|__profile_pictures
|__user1.png
|__static
|__js
|__main.js
Requests:
1) /js/main.js
2) /profile_pictures/user1.png
Nginx configuration:
location ~/profile_picture(^.+\.(jpg|jpeg|gif|png)$) {
alias /home/chirag/Desktop/project/profile_pictures/$1;
expires -1;
}
location ~*(^.+\.(jpg|jpeg|gif|css|png|js|ico|eot|otf|svg|ttf|woff|hbs)$) {
alias /home/chirag/Desktop/project/static/$1;
expires -1;
}
First request should goto static folder.(Working)
Second request should goto profile_pictures folder.
Second request is failing. What am i missing here?

The problem is with the first profile picture location block. So the right way to handle this would be
location ~ ^/profile_picture/(.+\.(jpg|jpeg|gif|png)$) {
alias /home/chirag/Desktop/project/profile_pictures/$1;
expires -1;
}
location ~*(^.+\.(jpg|jpeg|gif|css|png|js|ico|eot|otf|svg|ttf|woff|hbs)$) {
alias /home/chirag/Desktop/project/static/$1;
expires -1;
}
Do not use the ^ in the middle of a regex. It is meant to suggest the beginning. Also you missed the following / after the profile picture. The new location block should work for you.
Good Luck Mate. Cheers

Related

nginx locations with similar prefixes

I'm trying to do configure nginx to serve different version of an Angular SPA, usually prefixed with "dev" or "prod" but having a location that is "dev" and "prod", but i don't want nginx to expose directories that are not configured (inside nginx.conf).
For example,
http://myserver/dev
http://myserver/dev-SomeFeatureBranch
If I use exact matching (= modifier), I can't reach anything below /dev or below /dev-SomeFeatureBranch, so that's not an option.
If I don't specify a modifier, I get prefix matching which kinda works but exposes other branches that I have not configured in my nginx.conf
For example, if i have a directory named "dev-SomePrivateBranch" in the same directory as my other Dev branches and I use the following configs:
location / {
root ../www;
}
location /dev {
alias ../dev;
}
location /dev-SomeFeatureBranch {
alias ../dev-SomeFeatureBranch;
}
I can effectively reach http://myserver/dev-SomePrivateBranch , since it matches "/dev" but i don't want to reach locations that i have not explicitly configured.
Add to that issues with trailing slashes, I'd like http://myserver/dev/ to work as well as http://myserver/dev
I'm sure this is super simple once you are used to nginx's ways, but i can't seem to get that working for the life of me.
You need to use a trailing / if you want your locations to refer to a single directory name rather than a random set of directory names that happen to begin with the same characters.
For example:
location / {
root ../www;
}
location /dev/ {
alias ../dev/;
}
location /dev-SomeFeatureBranch/ {
alias ../dev-SomeFeatureBranch/;
}
Note that the location and alias directives should both end with /.
The alias is probably unnecessary, as root ..; should work if the location name and directory name are the same.
For example:
location / {
root ../www;
}
location /dev/ {
root ..;
}
location /dev-SomeFeatureBranch/ {
root ..;
}
I do not like relative paths for root and alias, but it should still work if that's what you prefer.
The efficient solution to manage /dev and /dev/ is to redirect from one to the other. Nginx does this automatically if the directory exists. But in your case, it's not obvious as the initial URI is processed in the location / block. You can solve the problem with an explicit redirect.
For example:
location / {
root ../www;
}
location = /dev { return 301 /dev/; }
location /dev/ {
root ..;
}
location = /dev-SomeFeatureBranch { return 301 /dev-SomeFeatureBranch/; }
location /dev-SomeFeatureBranch/ {
root ..;
}
Finally, if the root is the same for all the location blocks, you may as well use a regular expression, in which case the entire solution can be wrapped up into one expression.
For example:
location / {
root ../www;
}
location ~ ^/dev(|-SomeFeatureBranch)($|/) {
root ..;
}
Note that the evaluation order of regular expression location blocks is significant. See this document for details.

nginx server: how to remove first directory from URL

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/;
...

nginx reject request if header not present

I need nginx to reject requests if header StaticCookie is not present. I don't care about its value, I just need for it to exist.
What I came up with is this, but this doesn't work. Nginx allows requests with no headers at all.
if ($http_StaticCookie = false) {
return 403;
}
root /usr/share/asuno/www;
location ~* /css/ {
expires max;
}
location ~* /js/ {
expires max;
}
I saw this post -
Nginx: Reject request if header is not present or wrong - but it deals with defined header values. What I need is to check mere existence of the header.
I tried putting location directives inside the if clause but then nginx throws errors trying to read the config.
How can this be done?
the comment by Alexey Ten is correct, thanks.
if ($http_StaticCookie = "") { return 403; }

How to write nginx rules/regexes to match empty non empty path

I want to have an nginx rule that will proxy requests with empty path / to a back end server, and another rule that match non empty paths, ex. http://mysite/x/y/z
The following two rules do not do this, the second one is catching all:
# empty path
location ^/?$ {
proxy_pass http://127.0.0.1:8000;
}
location / {
expires -1;
alias /var/static-site/;
}
I have tried /.*/ for the second rule, without success...
Use the "=" modifier to process an exact match on "/":
location = / {
proxy_pass http://127.0.0.1:8000;
}
location / {
expires -1;
alias /var/static-site/;
}

How to disable logging images in nginx but still allow the get request?

I'm trying to log only java-script files request in the nginx access_log.
I tried using the following code i found on this site:
location ~* ^.+.(jpg|jpeg|gif|css|png|html|htm|ico|xml|svg)$ {
access_log off;
}
the problem is it doesn't allow the get request at all and i get a 404 error when trying to run the html file that executes the js file in the browse.
I want everything to work just the same but for the access log to log only request for js files.
How do i do that?
Put it in the server block and make sure that the "root" is correctly set up. It does work
Working example:
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires +60d;
access_log off;
}
I have this in the server block and not a location block.
Alternatively you can keep all requests within single location but use access_log with condidional if operator to disable images logging:
map $request_uri $is_loggable {
~* ^.+\.(jpg|jpeg|gif|css|png|html|htm|ico|xml|svg)$ 0;
default 1;
}
server {
location / {
access_log /path/to/log/file combined if=$is_loggable;
...
}
}
Here combined is a name of default log format.
You say that you want to log only java-script files, so actually you can use even simplier solution:
map $request_uri $is_loggable {
~* ^.+\.js$ 1;
default 0;
}

Resources