Gurkenkönig
Gurkenkönig

Reputation: 828

How to config nginx proxy pass using subfolder domain whith gunicorn Django

How can I configure ngnix to redirect a proxypass from a domain with subfolder to /?
Example:
https://example.com/yoursub/ to localhost without /yoursub/ prefix
At the moment the direct access to the server ip http://xxx.xxx.xxx.xx/ from the intranet works without problems.

my nginx config file:

upstream app_server {
    server unix:/home/myname/APP-Server/gunicorn/gunicorn.sock fail_timeout=0;
}

server {
    listen 80;

    # add here the ip address of your server
    # or a domain pointing to that ip (like example.com or www.example.com)
    server_name 123.456.789.1;

    keepalive_timeout 5;
    client_max_body_size 4G;

    access_log /home/myname/APP-Server/logs/nginx-access.log;
    error_log /home/myname/APP-Server/logs/nginx-error.log;

    location /static/ {
        alias /home/myname/APP-Server/static-root/;
    }

    # checks for static file, if not found proxy to app
    location / {
try_files $uri @proxy_to_app; 
    }

    location @proxy_to_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;
    }
}

If it's relevant: The backend is a django app with a gunicorn server.
Do I have to consider anything about the redirect from https to http?
I have no control over the base domain.

Upvotes: 5

Views: 10297

Answers (3)

2ps
2ps

Reputation: 15966

The way I handle this is with a rewrite rule:

location /yoursub {
    rewrite /yoursub(.*) $1;
    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;
}

The rewrite will convert your url from /yoursub/path/to/view to /path/to/view for your app server.

Upvotes: 0

Zenexer
Zenexer

Reputation: 19611

If I understand correctly, you want to remove the first part of the URI. There are multiple ways you can do that, but the easiest is probably with the alias directive, which will remove the portion of the URI that matches the current location block:

location /foo/ {
    alias /home/myname/APP-Server/static-root/;  # It doesn't really matter what you put here, since you're proxying everything.

    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;
}

If your Nginx server is running on foobar.example and you request http://foobar.example/foo/bar, the upstream server will see a request for http://foobar.example/bar.

The alias directive can be a bit buggy/unintuitive, so it's best to keep your location directive top-level (not nested within other location blocks) and as simple as possible.

If instead you want to add a prefix to the URI, you can do that within the proxy_pass directive itself:

location @proxy_to_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/foo$uri$is_args$args;
}

If your Nginx server is running on foobar.example and you request http://foobar.example/bar, the upstream server will see a request for http://foobar.example/foo/bar

Upvotes: 3

nebuler
nebuler

Reputation: 1545

Try this:

server {
    ...
    location @proxy_to_app {
        ...
        proxy_pass http://app_server/;  # note the trailing slash
    }
}

Explanation

As per the nginx docs:

If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive.

Since / location matches anything, then everything will be replaced by / (the trailing slash in proxy_pass) before being proxied to the upstream.

Upvotes: 2

Related Questions