I’ve been working on a new dev platform using nginx/gunicorn and Flask for my application.
Ops-wise, everything works fine – the issue I’m having is with debugging the Flask layer. When there’s an error in my code, I just get a straight 500 error returned to the browser and nothing shows up on the console or in my logs.
I’ve tried many different configs/options.. I guess I must be missing something obvious.
import os bind = '127.0.0.1:8002' workers = 3 backlog = 2048 worker_class = "sync" debug = True proc_name = 'gunicorn.proc' pidfile = '/tmp/gunicorn.pid' logfile = '/var/log/gunicorn/debug.log' loglevel = 'debug'
An example of some Flask code that borks- testserver.py:
from flask import Flask from flask import render_template_string from werkzeug.contrib.fixers import ProxyFix app = Flask(__name__) def index(): n = 1/0 return "DIV/0 worked!"
And finally, the command to run the flask app in gunicorn:
gunicorn -c gunicorn.conf.py testserver:app
The acception solution doesn’t work for me.
Gunicorn is a pre-forking environment and apparently the Flask debugger doesn’t work in a forking environment.
Even though the interactive debugger does not work in
forking environments (which makes it nearly impossible to use on
production servers) […]
Even if you set
app.debug = True, you will still only get an empty page with the message Internal Server Error if you run with
gunicorn testserver:app. The best you can do with gunicorn is to run it with
gunicorn --debug testserver:app. That gives you the trace in addition to the Internal Server Error message. However, this is just the same text trace that you see in the terminal and not the Flask debugger.
if __name__ ... section to the testserver.py and running
python testserver.py to start the server in development gets you the Flask debugger. In other words, don’t use gunicorn in development if you want the Flask debugger.
app = Flask(__name__) app.config['DEBUG'] = True if __name__ == '__main__': app.run()
Tip for Heroku users:
Personally I still like to use
foreman start, instead of
python testserver.py since it sets up all the env variables for me. To get this to work:
bin/web, file is relative to project root
#!/bin/sh if [ "$FLASK_ENV" == "development" ]; then python app.py else gunicorn app:app -w 3 fi
In development, create a
.env file relative to project root with the following contents (docs here)
Also, dont forget to change the
app.config['DEBUG']... line in
testserver.py to something that won’t run Flask in debug mode in production.
app.config['DEBUG'] = os.environ.get('DEBUG', False)
The Flask config is entirely separate from gunicorn’s. Following the Flask documentation on config files, a good solution would be change my source to this:
app = Flask(__name__) app.config.from_pyfile('config.py')
And in config.py:
DEBUG = True
For Heroku users, there is a simpler solution than creating a bin/web script like suggested by Nick.
foreman start, just use
foreman run python app.py if you want to debug your application in development.
I had similiar problem when running flask under gunicorn I didn’t see stacktraces in browser (had to look at logs every time). Setting DEBUG, FLASK_DEBUG, or anything mentioned on this page didn’t work. Finally I did this:
app = Flask(__name__) app.config.from_object(settings_map[environment]) if environment == 'development': from werkzeug.debug import DebuggedApplication app_runtime = DebuggedApplication(app, evalex=False) else: app_runtime = app
Note evalex is disabled because interactive debbugging won’t work with forking (gunicorn).
I used this:
gunicorn "swagger_server.__main__:app" -w 4 -b 0.0.0.0:8080
Try setting the debug flag on the run command like so
gunicorn -c gunicorn.conf.py --debug testserver:app
and keep the
DEBUG = True in your Flask application. There must be a reason why your debug option is not being applied from the config file but for now the above note should get you going.