Search code examples
socketsnginxgunicornsubdirectoryproxypass

Running a proxy_pass on a subpath in NGINX


I am trying to run a Flask app on Gunicorn through an Nginx server. I would like the app to run on a sub-directory instead of through a different port, if possible, but all I get are 404 errors. Here is my conf file, which is an included file in the conf.d folder:

server {
    listen          80;
    server_name     127.0.0.1;
    location / {
        root /var/www/html;
    }
    location /chess/ {
        proxy_pass http://unix:/usr/share/nginx/sockets/chess.sock;
        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;
    }
}

Could someone please tell me how to do this? I have looked all over and tried a lot of different things, to no avail. It runs fine on a different port, but that is not what I want. A subdomain is also a suitable option, but I can only get that to work in production, not development, for some reason. Someone posed the question here but the link they gave to the solution is dead.


Solution

  • Two methods are available. The first method involves adding the subpath to both the NGINX configuration and the Flask app, as suggested in the answer by Yarin_007. Set up NGINX like so:

    server {
        listen localhost:80;
        location / {
            root /var/www/html;
        }
        location /chess/ {
            proxy_pass http://unix:/usr/share/nginx/sockets/chess.sock;
            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;
       }
    }
    

    And alter the Flask app to include the subpath:

    from flask import Flask, request
    ...
    @app.route("/chess/", methods=["GET", "POST"])
    ...
    

    The alternative, as suggested in this answer is to run the Gunicorn service on a non-privileged port (or maybe a subdomain) and use two proxy_pass directives to direct from the port 80 subpath like so:

    server {
        listen  localhost:80;
        location / {
            root /var/www/html;
        }
        location /chess/ {
            proxy_pass http://localhost:8080/;
        }
    }
    
    server {
        listen  localhost:8080;
        location / {
            proxy_pass http://unix:/usr/share/nginx/sockets/chess.sock;
            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;
        }
    }
    

    The Flask app can remain as it was originally:

    from flask import Flask, request
    ...
    @app.route("/", methods=["GET", "POST"])
    ...