user14584663
user14584663

Reputation:

Flask + gunicorn proxy setup?

I try to wire Flask, gunicorn and nginx together but it ends up with 400 Bad request and 500 Errors. Hope that anyone can help.

nginx conf

server {
    listen 8000;
    server_name 127.0.0.1;

    location /Hello {
        uwsgi_pass 127.0.0.1:8081;
    }
}

wsgi.py snippet:

from app import app

app.run(host="127.0.0.1", port=8081)

app.py

app = Flask(__name__)
app.secret_key = "Not A Secret Anymore By Now"

@app.route('/Hello')
def hello():
  return("Hello")


#if __name__ == "__main__":
#  app.run(host='0.0.0.0', port=8000)

run cmd

export FLASK_APP=app
export FLASK_ENV=development
gunicorn --bind 0.0.0.0:8081 wsgi:app

test cases

  1. curl http://localhost/ >>> returns nginx homepage
  2. curl http://localhost/Hello >>> returns 404 Not found
  3. curl http://localhost:8000/ >>> returns nginx homepage
  4. curl http://localhost:8000/Hello >>> returns 502 Bad Gateway
  5. curl http://localhost:8081 >>> return Connection refused

I try to get the test cases working, but have not clue why the errors appears, (nginx is restarted).

Thank you.

Upvotes: 0

Views: 1906

Answers (1)

v25
v25

Reputation: 7656

A few problems here...

Your view function ends without a return statement, which is probably the cause of the first 500 error. Better use:

@app.route('/Hello')
def hello():
  print("Hello")
  return 'success'

Also as you metntion uwsgi.py is emtpy, there's no app object to import there. Best point the gunicorn command at a valid app object:

gunicorn --bind 0.0.0.0:8081 app:app

Also the nginx location block expects the request to go to http://example.com/Hello/Hello. So better make the location block like the following. (Also ensure the port is the same one you provded to gunicorn's --bind flag).

location / {
    proxy_pass http://127.0.0.1:8081;
}

Here I've also used proxy_pass as per the gunicorn deployment (with nginx) docs.

Now the request should work:

# Direct to app server...
curl -i  http://localhost:8081/Hello
HTTP/1.1 200 OK
Server: gunicorn/20.0.4
# ...
success

and also:

# Via nginx:
curl -i http://localhost/Hello
HTTP/1.1 200 OK
Server: nginx
...
success

Beware that running gunicorn on all interfaces (0.0.0.0) means external requests could reach the app server directly (bypassing nginx) if no firewall is in place to prevent this. Might be worth instead binding gunicorn to the local interface: --bind 127.0.0.1:8081.

Also be careful in general, there's lots of ways to make security slip-ups when configuring stuff like this yourself. Good luck.

Upvotes: 1

Related Questions