nginx location matching for url params only - nginx

I need to rewrite any root subdomain requests and append locale params if they aren't already there. e.g. -> de.example.com needs to be rewritten as -> de.example.com/?locale=de. then I proxy it off to the app.
2 questions:
1) is this the correct approach? or should I be using regex instead here? (new to this
so if other problems, please lmk)
2) is there a way to log things inside the location block? Having trouble getting same config working on another server, logging would help. (e.g logging what args is if it isn't matching, or if it matches on another location block).
It only needs to happen on the root page so this is my current config
#existing default (nonsubdomain block)
server {
server_name _;
root /var/www/web_app;
try_files $uri/index.html $uri.html $uri #app;
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
#just added for subdomain
server {
server_name de.example.com;
root /var/www/web_app;
location / {
try_files $uri/index.html $uri.html $uri #app;
}
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
location = / {
if ($args != locale=de ){
rewrite ^ $scheme://de.example.com/?locale=de permanent;
}
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}

1) is this the correct approach? or should I be using regex instead here? (new to this so if other problems, please lmk)
You should use $arg_locale != de instead of $args != locale=de. Look at the docs: http://nginx.org/en/docs/http/ngx_http_core_module.html#var_arg_
2) is there a way to log things inside the location block? Having trouble getting same config working on another server, logging would help. (e.g logging what args is if it isn't matching, or if it matches on another location block). It only needs to happen on the root page so this is my current config
Debug log: http://nginx.org/en/docs/debugging_log.html

Related

how to set the locaction in nginx.conf for removing URL's trailing slash?

Today I used two servers for nginx, the content of nginx.conf as follows:
#192.168.2.98
server {
listen 8091;
location ^~ /ttank {
alias /develop/servers-running/front/vue-public/dist;
index index.html;
try_files $uri $uri/ /ttank/index.html;
}
}
#192.168.2.97
location /ttank {
proxy_pass http://192.168.2.98:8091;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
}
I can access the 192.168.2.98:8091/ttank by enter address: http://192.168.2.98:8091/ttank in chrome, I also can access 192.168.2.98's ttank by entering the address http://192.168.2.97/ttank/, but when I change the addres http://192.168.2.97/ttank/ into http://192.168.2.97/ttank, my chrome entered into waiting status forever, the only difference between two addresses is the last "/", I don't know how to modify the config file for removing the last "/" when accessing ttank by 192.168.2.97?
Try usinge a rewrite rule to get rid of the ending slashes
location /ttank {
rewrite ^/(.*)/$ /$1 break;
...;
...;
proxy_pass ...;
}
it should do it

How to use vue.js with Nginx?

I want to build a single page application with Vue.js using Nginx as my webserver and a my own Dropwiward REST API. Moreover I use Axios to call my REST request.
My nginx config looks like
server {
listen 80;
server_name localhost;
location / {
root path/to/vue.js/Project;
index index.html index.htm;
include /etc/nginx/mime.types;
}
location /api/ {
rewrite ^/api^/ /$1 break;
proxy_pass http://localhost:8080/;
}
}
Currently I can just call my localhost/api/path/to/rescource to get the the information from the backend.
I build the Front end with HTML and javascript(vue.js) which has worked so far. However when I want to build a single page application most tutorials mention node.js. How can I use Nginx instead?
Add the following code to your Nginx Config, as detailed in the VueRouter docs, here:
location / {
try_files $uri $uri/ /index.html;
}
Also, you need to enable history mode on VueRouter:
const router = new VueRouter({
mode: 'history',
routes: [...]
})
I struggled with same problem. But I found how can I do. You just add this to your nginx.conf.
location / {
root /home/admin/web/domain.com/public_html/; #-> index.html location
index index.html;
include /etc/nginx/mime.types;
try_files $uri $uri/ /index.html;
}
This worked for me:
location /static/ {
root /root/bdn/bdn/server/;
}
location /media/ {
root /root/bdn/bdn/server/;
}
location ^~ /admin/ { # Define routes to be directed to backend as proxy
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/run/gunicorn.sock;
}
location ^~ /api/ { # Define routes to be directed to backend as proxy
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/run/gunicorn.sock;
}
location ^~ /api-auth/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/run/gunicorn.sock;
}
location ^~ /{
root /root/bdn/bdn/server/templates/;
index index.html;
}
error_page 404 /; # PARTICULARLY THIS ERROR REDIRECTION

How to configure Nginx to try two upstreams before 404ing?

Given an Nginx configuration roughly like this:
upstream A {
server aa:8080;
}
upstream B {
server bb:8080;
}
server {
listen 80;
location #backendA {
proxy_pass http://A/;
}
location #backendB {
proxy_pass http://B/;
}
location / {
# This doesn't work. :)
try_files #backendA #backendB =404;
}
}
Basically, I would like Nginx to try upstream A, and if A returns a 404, then try upstream B instead, and failing that, return a 404 to the client. try_files does this for filesystem locations, then can fall back to a named location, but it doesn't work for multiple named locations. Is there something that will work?
Background: I have a Django web application (upstream A) and an Apache/Wordpress instance (upstream B) that I would like to coexist in the same URL namespace for simpler Wordpress URLs: mysite.com/hello-world/ instead of mysite.com/blog/hello-world/.
I could duplicate my Django URLs in the Nginx locations and use wordpress as a catch-all:
location /something-django-handles/ {
proxy_pass http://A/;
}
location /something-else-django-handles/ {
proxy_pass http://A/;
}
location / {
proxy_pass http://B/;
}
But this violates the DRY principle, so I'd like to avoid it if possible. :) Is there a solution?
After further googling, I came upon this solution:
location / {
# Send 404s to B
error_page 404 = #backendB;
proxy_intercept_errors on;
log_not_found off;
# Try the proxy like normal
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://A;
}
location #backendB {
# If A didn't work, let's try B.
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://B;
# Any 404s here are handled normally.
}

Root directory shows 404 in nginx

I am new to nginx server. I tried to set a new url "/images/" for serving images. I edited the bi.site file in site-enabled folder.
server {
listen *:80;
access_log /var/log/myproject/access_log;
location / {
proxy_pass http://127.0.0.1:5000/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /images/ {
root /www/myproject/files_storage;
}
}
And in /www/myproject/files_storage location i put a temp.txt file.
When i put http://www.main_url/images/temp.txt it shows 404 not found. What am i doing wrong ? Did i miss something important ?
this:
location /images/ {
root /www/myproject/files_storage;
}
results in /www/myproject/files_storage/images path, it would be obvious if you setup error_log. So use "alias" directive instead of "root"
http://nginx.org/en/docs/http/ngx_http_core_module.html#alias

questions about $args on try_files inside location with regex

(sorry for my bad english)
i have a URL like this:
http://www.domain.com/resize.php?pic=images/elements/imagename.jpg&type=300crop
that php checks if that image exists and serves, if not, creates image on disk with the size specified in the type parameter and returns it.
what I wanted is to check if the image exists on disk at that size, with nginx, so run only resize.php when necessary to create the image.
I tried this, but i think that location directive doesn't operate on query parameters ($args) using regex, then loncation does not match with sample URL :(
any help please?
I need to rewrite the parameters ($args) and use them in the try_files directive... is this possible?
location ~ "^/resize\.php\?pic=images/(elements|gallery)/(.*)\.jpg&type=([0-9]{1,3}[a-z]{0,4})$)" {
try_files /images/$1/$2.jpg /imagenes/elements/thumbs/$3_$2.jpg #phpresize;
}
location #phpresize {
try_files $uri =404;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering on;
proxy_pass http://www.localhost.com:8080;
}
You cannot match query string in location (e.g., see here and here). The only way to process requests differently depending on the query string contents is to use if and conditional rewrites.
However, if it is OK to handle requests to /resize.php which do not have expected query parameters using the #phpresize location config, you can try something like this:
map $arg_pic $image_dir {
# A subdirectory with this name should not exist.
default invalid;
~^images/(?P<img_dir>elements|gallery)/.*\.jpg$ $img_dir;
}
map $arg_pic $image_name {
# The ".*" match here might be insecure - using something like "[-a-z0-9_]+"
# would probably be better if it matches all your image names;
# choose a regexp which is appropriate for your situation.
~^images/(elements|gallery)/(?P<img_name>.*)\.jpg$ $img_name;
}
map $arg_type $image_type {
~^(?P<img_type>[0-9]{1,3}[a-z]{0,4})$ $img_type;
}
location ~ "^/resize.php$" {
try_files /images/${image_dir}/${image_name}.jpg /imagenes/elements/thumbs/${image_type}_${image_name}.jpg #phpresize;
}
location #phpresize {
# No changes from your config here.
try_files $uri =404;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering on;
proxy_pass http://www.localhost.com:8080;
}

Resources