What is going on when I set app.wsgi_app = ProxyFix(app.wsgi_app) when running a Flask app on gunicorn?

Ashley Temple picture Ashley Temple · Dec 14, 2013 · Viewed 10.6k times · Source

I built a basic web app using Flask, and was able to run it from a virtual machine using its native http server. I quickly realized that with this set up, requests are blocking (I couldn't make concurrent requests for resources; any new request would wait until earlier requests had finished), and decided to try gunicorn to run the app to solve this problem. I followed the documentation, specifically running with this line:

gunicorn -w 4 -b 127.0.0.1:4000 myproject:app 

However, it failed to boot doing just this, and complained that there was no WSGI app. Poking around the internet, I found that a number of people had posted examples including the following:

from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)

I added that, and it resolved my problem. I am confused though because this is apparently meant to solve a problem serving behind an HTTP proxy, but would the addition of gunicorn impose an HTTP proxy? Or was I always behind a proxy, and it just didn't matter for Flask's built-in server?

Also, Werkzeug's documentation on Fixers warns "Do not use this middleware in non-proxy setups for security reasons." Considering the fix was clearly necessary, can I assume I'm on a proxy setup?

Answer

Steven Kryskalla picture Steven Kryskalla · Mar 6, 2014

You need to show the code that defines your Flask application "app".

Where is "app" defined? Are you importing it from another file?

Here is my attempt to reproduce the issue:

$ cat myproject.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "ok"

$ bin/gunicorn -w 4 -b 127.0.0.1:4000 myproject:app &
[1] 27435

2014-03-04 12:18:36 [27435] [INFO] Starting gunicorn 18.0
2014-03-04 12:18:36 [27435] [INFO] Listening at: http://127.0.0.1:4000 (27435)
2014-03-04 12:18:36 [27435] [INFO] Using worker: sync
2014-03-04 12:18:36 [27441] [INFO] Booting worker with pid: 27441
2014-03-04 12:18:36 [27442] [INFO] Booting worker with pid: 27442
2014-03-04 12:18:36 [27445] [INFO] Booting worker with pid: 27445
2014-03-04 12:18:36 [27448] [INFO] Booting worker with pid: 27448

$ curl http://127.0.0.1:4000/
ok

As you can see it works fine. You definitely don't need ProxyFix in this case.