Flask app gives ubiquitous 404 when proxied throug

2019-04-24 07:13发布

问题:

I've got a flask app daemonized via supervisor. I want to proxy_pass a subfolder on the localhost to the flask app. The flask app runs correctly when run directly, however it gives 404 errors when called through the proxy. Here is the config file for nginx:

upstream apiserver {
    server 127.0.0.1:5000;
}

location /api {
            rewrite /api/(.*) /$1 break;
            proxy_pass_header Server;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Scheme $scheme;
            proxy_pass http://apiserver;
            proxy_next_upstream error timeout http_502;
            proxy_buffering off;

}

For instance, when I go to http://127.0.0.1:5000/me, I get a valid response from the app. However when I go to http://127.0.0.1/api/me I get a 404 from the flask app (not nginx). Also, the flask SERVER_NAME variable is set to 127.0.0.1:5000, if that's important.

I'd really appreciate any suggestions; I'm pretty stumped! If there's anything else I need to add, let me know!

回答1:

Since Flask is handling the request, you could just add a little bit of information to the 404 error to help you understand what's passing through to the application and give you some real feedback about what effect your nginx configuration changes cause.

from flask import request

@app.errorhandler(404)
def page_not_found(error):
    return 'This route does not exist {}'.format(request.url), 404

So when you get a 404 page, it will helpfully tell you exactly what Flask was handling, which should help you to very quickly narrow down your problem.



回答2:

I suggest not setting SERVER_NAME.

If SERVER_NAME is set, it will 404 any requests that don't match the value.



回答3:

I ran into the same issue. Flask should really provide more verbose errors here since the naked 404 isn't very helpful.

In my case, SERVER_NAME was set to my domain name (e.g. example.com).

nginx was forwarding requests without the server name, and as @Zoidberg notes, this caused Flask to trigger a 404.

The solution was to configure nginx to use the same server name as Flask.
In your nginx configuration file (e.g. sites_available or nginx.conf, depending on where you're defining your server):

server {
    listen       80;
    server_name  example.com;  # this should match Flask SERVER_NAME

    ...etc...