Set proxy_pass in nginx based on request_method - nginx

I have two application and a nginx server on top of that. I want to proxy all GET requests coming on nginx to one app running on http://127.0.0.1:9101/ and proxy all other request methods to http://10.41.115.241:8000/
I have tried couple of options but none worked
I have tried using limit_exempt
location /api/v1/executions {
error_page 502 = #apiError;
rewrite ^/api/(.*) /$1 break;
proxy_pass http://127.0.0.1:9101/;
limit_except PUT POST DELETE {
proxy_pass http://10.41.115.241:8000/;
}
proxy_read_timeout 90;
proxy_connect_timeout 90;
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;
#proxy_set_header Connection '';
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
#proxy_set_header Host $host;
}
I have also tried if condition
location /api/v1/executions {
error_page 502 = #apiError;
rewrite ^/api/(.*) /$1 break;
proxy_pass http://10.41.115.241:8000/;
if ($request_method = GET) {
proxy_pass http://127.0.0.1:9101/;
}
proxy_read_timeout 90;
proxy_connect_timeout 90;
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;
#proxy_set_header Connection '';
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
#proxy_set_header Host $host;
}
but in both ways I got this error
"proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /path/to/config

Always try to use map instead of if for conditional logic in NGINX. Unless it's absolutely impossible with map.. In your particular case, it's easy.
Create a variable $backend which will hold your desired proxy_pass value depending on the request methods:
http {
map $request_method $backend {
default http://10.41.115.241:8000/;
GET http://127.0.0.1:9101/;
}
...
}
Then use it you in your config:
location /api/v1/executions {
error_page 502 = #apiError;
rewrite ^/api/(.*) /$1 break;
proxy_pass $backend;
proxy_read_timeout 90;
proxy_connect_timeout 90;
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;
#proxy_set_header Connection '';
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
#proxy_set_header Host $host;
}

Related

Proxying shiny-server through Django and nginx

I'm running a docker containerized django app with nginx as a reverse proxy and want to include several shiny apps I've inherited. I want django to sit between shiny-server (which serves the apps) and the client (i.e. NOT reverse proxy certain urls directly to shiny-server). However shiny-server seems to be trying to use some kind of websocket and hence while some elements of the ui render properly, the main files (leaflet maps, plots etc) don't. Instead I get a gray overlay. The console displays some cryptic error messages i.e. Connection closed. Info: {"isTrusted":false}. My nginx configuration is as follows:
#Connect to upstream shiny apps server
upstream shiny {
server shiny:80;
}
#Connect upstream django server via uWSGI
upstream django {
server django:8001;
}
#Required for shiny's WebSockets
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name 127.0.0.1;
resolver 127.0.0.11;
#Production settings
#listen 8000;
#server_name 195.134.90.182;
charset utf-8;
client_max_body_size 100M;
#Serve django's media (Not Implemented)
location /media/ {
alias /var/www/media;
}
location /static/ {
alias /var/www/static;
}
location / {
proxy_http_version 1.1; # you need to set this in order to use params below.
proxy_pass http://django;
proxy_set_header X-forwarded-FOR $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
# include /usr/src/wastewater_app/uwsgi_params;
proxy_temp_file_write_size 64k;
proxy_connect_timeout 100800s;
proxy_send_timeout 100800;
proxy_read_timeout 100800;
proxy_buffer_size 64k;
proxy_buffers 16 32k;
proxy_busy_buffers_size 64k;
proxy_redirect off;
proxy_request_buffering off;
proxy_buffering off;
keepalive_timeout 650000;
}
#Proxy shiny requests to shiny-server
location ~* /shiny/(.+) {
rewrite ^/shiny/(.*)$ /$1 break;
proxy_pass http://shiny/$1/;
proxy_redirect http://shiny/ $scheme://$host/shiny/;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 100800s;
proxy_send_timeout 100800;
proxy_read_timeout 100800;
keepalive_timeout 650000;
# required for WebSockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location /__sockjs__/{
proxy_pass http://shiny/;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 100800s;
proxy_send_timeout 100800;
proxy_read_timeout 100800;
keepalive_timeout 650000;
}
location /ws {
proxy_pass http://shiny/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 100800s;
proxy_send_timeout 100800;
proxy_read_timeout 100800;
keepalive_timeout 650000;
}
I've also tried disabling sockets via:
#shiny-server.conf
sanitize_errors off;
disable_protocols websocket xdr-streaming xhr-streaming iframe-eventsource iframe- htmlfile;
However the problem persists.I've tried pretty much every solution suggested on the web and several permutations thereof but none have worked for this case. Open to any and all suggestions (please note I'm not familiar with websockets)

How can I optimize my nginx configuration

I have nginx .conf file as below; I'm wondering if it can be write simpler:
default.conf
upstream docsapp {
server app:8000;
}
server {
listen 80;
location / {
alias /usr/share/nginx/html/;
}
location /admin/ {
proxy_pass http://docsapp/admin/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /api/ {
proxy_pass http://docsapp/api/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /api-token-auth/ {
proxy_pass http://docsapp/api-token-auth/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /docs/ {
proxy_pass http://docsapp/docs/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /media/ {
add_header Access-Control-Allow-Origin *;
alias /usr/local/src/app/media/;
internal;
}
location /static/ {
alias /usr/local/src/app/static/;
}
client_max_body_size 8M;
}
Location \ is Vue.js app, remaining is Django REST Framework. I've searched a web for a while but none of found solutions worke for me.
Another problem occurred during attempt to split this file into two:
vue.conf
server {
listen 80;
location / {
alias /usr/share/nginx/html/;
}
}
and
drf.conf
upstream docsapp {
server app:8000;
}
server {
listen 80;
location /admin/ {
proxy_pass http://docsapp/admin/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /api/ {
proxy_pass http://docsapp/api/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /api-token-auth/ {
proxy_pass http://docsapp/api-token-auth/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /docs/ {
proxy_pass http://docsapp/docs/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /media/ {
add_header Access-Control-Allow-Origin *;
alias /usr/local/src/app/media/;
internal;
}
location /static/ {
alias /usr/local/src/app/static/;
}
client_max_body_size 8M;
}
It also didn't work. Any help would be appreciated.
I think since you do not change request URI when you proxy requests to the docsapp upstream, you can replace four location blocks where proxy_pass directive used with the following one:
location ~ ^/(?:admin|api|api-token-auth|docs)/ {
proxy_pass http://docsapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
You can't split your server block in two, only one of them will work acting as default server (see the documentation).

Set basic auth on homepage only nginx

I have below configuration. I only want to authorize / because the only one that has a UI. Other URLs are already apis like /report/, /group/, /delete/ and so on.
upstream gofastdfs{
server localhost:8081;
keepalive 32;
}
server {
listen 8080;
server_name localhost;
gzip on;
gzip_types '*';
location / {
auth_basic "Caution";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
keepalive_timeout 620;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://gofastdfs;
proxy_set_header Host $host:$server_port;
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;
}
}
But my configuration authorizes every URL, I only want to limit to /
location / matches any URI that is not handled by some other location block - i.e. it is the default location.
location = / only matches the single URI /.
See this document for details.
You can split your configuration into two location blocks using one with authentication and the other without. Some statements will need to be duplicated between both location blocks, but most can be moved into the outer context.
For example:
keepalive_timeout 620;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host:$server_port;
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;
location = / {
auth_basic "Caution";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
proxy_pass http://gofastdfs;
}
location / {
proxy_pass http://gofastdfs;
}

Can't access parent directory through reverse proxy on subdomain

This is my current Nginx server block:
server {
listen 80;
server_name ~^(?<tenant>.+)\.mysalon\.test$;
gzip on;
gzip_types text/plain application/xml text/css application/javascript;
gzip_min_length 1000;
location / {
expires $expires;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x-Tenant $tenant;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_pass http://127.0.0.1:3000/subdomain/;
}
}
It's a reverse proxy for {tenant}.mysalon.test to http://127.0.0.1:3000/subdomain/.
The issue:
It works correctly, but it returns 404's for everything within {tenant}.mysalon.test/_nuxt/, that's because /_nuxt does not live in the /subdomain/ directory, but in the parent http://127.0.0.1:3000/.
So I added the following:
location ^~ /_nuxt/ {
proxy_pass http://127.0.0.1:3000/_nuxt/;
}
So that even on the subdomains, it can access /_nuxt.
However, this new location block makes the first location block inactive for some reason.
When visiting {tenant}.mysalon.test it returns http://127.0.0.1:3000 instead of http://127.0.0.1:3000/subdomain/.
I can't tell you why your second location block breaks the workflow, I didn't see any problems with this config, but you can try to use single location block and append the /subdomain prefix to the requested URI inside this block if the requested URI doesn't start with /_nuxt/:
location / {
expires $expires;
rewrite ^(?!/_nuxt)(/.*) /subdomain$1 break;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x-Tenant $tenant;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_pass http://127.0.0.1:3000;
}

How to configure NGINX not to cache specific URL?

I have a NGINX server as front-end cache server and I'd like to disable cache on specific urls.
Here is the configuration on NGINX:
proxy_cache_path /tmp/nginx levels=1:2 keys_zone=my_zone:10m inactive=120m max_size=1000m;
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
server {
listen 10.0.0.45:80 default_server;
server_name proxy2.jjd;
include /etc/nginx/default.d/*.conf;
location / {
client_max_body_size 20m;
proxy_cache my_zone;
proxy_cache_bypass $http_cache_control;
proxy_no_cache $http_pragma $http_authorization $cookie_nocache $arg_nocache;
add_header X-Proxy-Cache-NGINX $upstream_cache_status;
add_header X-Real-IP $remote_addr;
add_header Cache-Control "public";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_redirect off;
}
}
Add the following location to avoid an url:
location ^~ /your-url/ {
add_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_redirect off;
}
It just assigns this location to the proxy and doesn't enable caching for it.
As I get it, you just need a nested location with a single string proxy_cache off; inside to disable caching for nested URLs. Like this:
location / {
proxy_cache my_zone;
proxy_cache_bypass $http_cache_control;
// other stuff related to proxying or other processing
location /do/not/cache/this/url/ {
proxy_cache off;
}
}
you can just specify location do proxy_pass only for disable cache
location /will/not/cache {
proxy_pass http://127.0.0.1:8080;
..set_header ..
}

Resources