Flask: How do I automatically turn off debugging when program is in production?

I’m using Python 3.9 for this tutorial, and the latest version of Flask, on a Windows 10 machine. EDIT: When I’m done with tutorials of various aspects of web dev, I’ll be making apps on the MS Azure platform. But that’s probably 4-6 months away.

I’m doing a long video tutorial on Python since I’m still fairly new to Python. I’m learning Flask in this section of the tutorial. The last statement in my Flask program app.py is app.run(debug=True) # Run the web server. But the teacher says not to use debugging in production as it is a major security problem.

In my tutorial I’m running a web server on 127.0.0.1:5000. In production I will be using an MS Azure service with it’s own server and IP address.

How can I turn off debugging when I put my program into production on the other server? Can I check the IP somehow to turn debugging off? I try to make things like this automatic so there’s one less thing I have to remember.

if IP == '127.0.0.1':
    app.run(debug=True) # Run the web server
else: 
    app.run() # Run the web server

Or is there a more secure way to do this?

Your solution isn’t good, unfortunately.

What if you want to run locally with debug turned off? What if you want to run on a remote server with debug turned on?

A fairly conventional solution is to read all the Flask configuration information, as well as configuration information for your program, from some configuration file that you pass into your program somehow (env variable, a command line argument, etc).

Then you have one configuration file called e.g. debug.json, another called e.g. production.json, and you can create new config files for the two cases I mentioned at the top.

(Configuring programs is a huge can of worms and much more could be written but I wanted to keep this short.)

1 Like

There’s more to it than that, though. The default web server that Flask provides, Werkzeug, is definitely not designed for production, and it won’t scale well. The best solution is to use Werkzeug in development and leave debug mode active, and then in production, use something like gunicorn. The server will load up your app and feed requests to it, and app.run() will never actually be called.

Thanks. Maybe the teacher will cover this issue in a future video.

1 Like

Werkzeug provides the dev server, but also the entire wsgi and http handling framework. Only the dev server is not for production.

I’m aware of that, but I’m not aware of a separate name for just the dev server. If you know of a better wording for what I said, I’m happy to correct it.

The warning the dev server prints out, “Don’t use the dev server in production, use a production WSGI server instead.” should be enough. I’ve had confused users come asking “Werkzeug is only for development, how do I stop installing it in production?” which just doesn’t make sense. They don’t stop using Werkzeug in production, only the dev server.

Okay, but how is that different from what I said about using gunicorn?

Makes it sound like “Werkzeug is definitely not designed for production”. I know you didn’t mean it that way (and that you wrote more around it), but less experienced users tend to misinterpret that wording and then ask questions about “Why is Werkzeug installed if it’s not for production”.

In the end, I’m sure someone will misinterpret any wording we come up with, but it doesn’t hurt to try :sweat_smile:

And to answer @c-rob, you’ll want to check out Flask’s documentation about deploying, it explains both that the development server is only for development, and how to configure some common servers or deployment services. Deploying to Production — Flask Documentation (3.0.x)

Well, like I said, I’m open to suggestions…