How to Resolve Python Flask "WARNING: This is a development server. Do not use it in a production deployment."
When you start a Flask application using the standard flask run
command, you'll see a prominent warning: WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
This message is crucial – it indicates that the built-in server provided by Flask (Werkzeug's development server) is designed only for local development and testing, not for handling live traffic on a production website.
This guide explains why the development server is unsuitable for production and introduces recommended production-ready WSGI servers like Waitress and Gunicorn.
Understanding the Warning: Development vs. Production Servers
- Development Server (
flask run
): Provided by the Werkzeug library (Flask's dependency). It's optimized for ease of use during development, featuring:- Automatic code reloading (
--reload
flag). - An interactive debugger in the browser (if enabled).
- Relatively simple, single-process, often single-threaded operation.
- Automatic code reloading (
- Production WSGI Server: Applications like Waitress, Gunicorn, or uWSGI are specifically designed to run Python web applications (following the WSGI standard) in a live production environment. They focus on:
- Performance (handling multiple requests concurrently).
- Stability and Reliability.
- Security (fewer debugging features exposed).
- Scalability (often running multiple worker processes).
The warning exists because the development server lacks the performance, security, and robustness features required to handle real user traffic reliably.
When the Warning Appears (flask run
)
You will see this warning whenever you start your Flask application using the standard flask run
command in your terminal.
Example app.py
:
# app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1>Hello from Flask!</h1>"
No app.run()
here for production deployment via WSGI server
Running the Development Server:
# Set the Flask app (if not named app.py or wsgi.py)
export FLASK_APP=app # Linux/macOS
set FLASK_APP=app # Windows CMD
$env:FLASK_APP = "app" # Windows PowerShell
# Run the development server
flask run
# Or:
python -m flask run
Output:
* Environment: development
* Debug mode: off # (or on)
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead. # <<< THE WARNING
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
Why the Development Server is Not for Production
- Performance: It typically handles only one request at a time (single-threaded/process). Under load, requests will queue up, leading to slow response times.
- Security: If run with the debugger enabled (
FLASK_ENV=development
orflask run --debug
), it exposes a powerful debugger that could allow attackers to execute arbitrary code if accessible externally. - Stability: It's not designed for long-running, high-availability scenarios and may lack robustness compared to dedicated WSGI servers.
Solution: Use a Production WSGI Server
To deploy your Flask app, you need to use a production-grade Web Server Gateway Interface (WSGI) server. Popular choices include Waitress, Gunicorn, and uWSGI.
Option 1: Waitress (Cross-Platform)
Waitress is a pure-Python WSGI server that works well on Windows, macOS, and Linux. It's known for its simplicity.
Installation
Install Waitress into your project's virtual environment.
# Activate your virtual environment first!
pip install waitress
Running with waitress-serve
(Command Line)
This is a common way to start your app using Waitress from the terminal.
# Syntax: waitress-serve --host=<ip> --port=<port> module:application
# Example: Serve on all network interfaces on port 8080
waitress-serve --host=0.0.0.0 --port=8080 app:app
--host=0.0.0.0
: Makes the server accessible on your network (use127.0.0.1
for localhost only).--port=8080
: Specifies the port number.app:app
: Points to theapp
variable (yourFlask(__name__)
instance) inside theapp.py
file. Adjust if your filename or variable name differs (e.g.,my_project.main:my_flask_app
).
Running Programmatically (in app.py
)
You can also start Waitress from within your Python script. This is useful for simple deployments or embedding. Modify your app.py
:
# app.py (modified for programmatic Waitress start)
from flask import Flask
# Import serve from waitress AFTER installing it
from waitress import serve
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1>Hello from Flask via Waitress!</h1>"
if __name__ == "__main__":
# Run Waitress server when script is executed directly
print("Starting Waitress server on http://0.0.0.0:8080")
serve(app, host="0.0.0.0", port=8080)
Now, instead of flask run
, you run the script directly:
python app.py
Option 2: Gunicorn (Linux/macOS)
Gunicorn ('Green Unicorn') is a very popular WSGI server for Unix-like systems (Linux, macOS). It's known for its performance and ease of use. It does not run natively on Windows.
Installation
# Activate your virtual environment first!
pip install gunicorn
Running with gunicorn
(Command Line)
# Syntax: gunicorn --bind <ip>:<port> module:application
# Example: Serve on localhost port 8000 with 4 worker processes
gunicorn --bind 127.0.0.1:8000 --workers=4 app:app
--bind
: Specifies the address and port to listen on.--workers
: Number of worker processes to handle requests (adjust based on CPU cores).app:app
: Points to your Flask app instance within your module.
Other Production Options (uWSGI, etc.)
- uWSGI: Another powerful and widely used WSGI server, often paired with a reverse proxy like Nginx for high-performance deployments. Configuration can be more complex than Gunicorn or Waitress.
- Nginx/Apache + WSGI Server: In typical production setups, you often run Gunicorn or uWSGI behind a web server like Nginx or Apache, which handles incoming HTTP requests, serves static files, and forwards dynamic requests to the WSGI server.
Importance of Virtual Environments
Always install your Flask application dependencies, including your chosen WSGI server (Waitress, Gunicorn), inside a project-specific virtual environment (venv
). This isolates dependencies and avoids conflicts.
Conclusion
The Flask warning WARNING: This is a development server...
is a critical reminder not to use the server started by flask run
for live applications. It lacks the necessary performance, security, and stability.
To deploy your Flask application correctly:
- Choose a production WSGI server:
Waitress
(cross-platform) orGunicorn
(Linux/macOS) are excellent choices. - Install the chosen server into your project's virtual environment (
pip install waitress
orpip install gunicorn
). - Run your application using the command provided by the WSGI server (e.g.,
waitress-serve ... app:app
orgunicorn ... app:app
) instead offlask run
.
This ensures your application is served by a robust server capable of handling production loads.