Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?

like image 460
Ashley Temple Avatar asked Dec 14 '13 14:12

Ashley Temple


People also ask

What is Proxyfix?

This module provides a middleware that adjusts the WSGI environ based on X-Forwarded- headers that proxies in front of an application may set. When an application is running behind a proxy server, WSGI may see the request as coming from that server rather than the real client.

What are standalone WSGI containers?

There are popular servers written in Python that contain WSGI applications and serve HTTP. These servers stand alone when they run; you can proxy to them from your web server. Note the section on Proxy Setups if you run into issues.


2 Answers

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.

like image 89
Steven Kryskalla Avatar answered Sep 30 '22 14:09

Steven Kryskalla


A little late to the party, but here is what the documentation says about ProxyFix.

To paraphrase: Deploying your server using gunicorn behind an HTTP proxy you will need to rewrite some of the headers so that the application can work. And Werkzeug ships with a fixer that will solve some of the common setups.

like image 42
tgdn Avatar answered Sep 30 '22 14:09

tgdn