Hello Coders,
This article explains How to Deploy Flask in production using multiple configurations (Nginx/Gunicorn, Nginx/Waitress, Docker), and different sample apps. The concepts can be adapted with a minimum effort also on Django, the Flask's big brother.
Thank you! Content provided by App Generator.
What is Deployment
Software deployment is all of the activities that make a software system available for use. Most of the time, developers code their apps using a workstation and later publish the product on a public domain/subdomain to be used by end-users. The process of making the software available for production use is called deployment.
What is Flask
For newcomers, Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications.
Classified as a microframework, Flask is written in Python and it does not require particular tools or libraries. It has no database abstraction layer, form validation, or any other components where pre-existing third-party libraries provide common functions.
WSGI (Web Server Gateway Interface) it is just an interface specification by which server and application communicate.
Flask, for instance, implements this communication protocol under the hood and let us code the upper level of our web app (features, login, database information manipulation).
WSGI Simple App (no Flask)
Probably the most simple WSGI app ever coded is this one:
def app(environ, start_response):
data = b"Hello! This is a simple WSGI web app.\n"
start_response("200 OK", [
("Content-Type", "text/plain"),
("Content-Length", str(len(data)))
])
return iter([data])
Please save this code snippet in a file named
myapp.py
(or choose another name). We will refer this file in the next section.
This code snippet defines a method named app
(we can choose another name) that returns a simple string Hello! This is a simple WSGI web app
The syntax used to define the method and the response pattern is defined in the WSGI protocol, section The Application/Framework Side.
On the other side, the server should also respect the WSGI protocol and implement The Server/Gateway Side.
This complex part is handled by Flask, Gunicorn, uWSGI, and all other WSGI-ready servers that we can use in production.
What is Gunicorn
At this point, we have a super simple WSGI app that echos a Hello world!
.. and that's all. To see the message in the browser we need a WSGI server (Gunicorn) able to execute our app and serve browser request.
Install Gunicorn
The most convenient way is to use PIP, the official package manager for Python.
$ pip install gunicorn
Once the Gunicorn is available we can execute our simple app.
$ gunicorn myapp:app
Gunicorn being a WSGI server, expect the WSGI object to execute as argument, witch in our case is defined in myapp.py
file in method app
.
By default Gunicorn
starts on port 8000. To use another port, use -b
argument (b
comes from bind
).
$ gunicorn myapp:app -b :8001
The Browser effect
Waitress
Gunicorn is for sure an amazing server that we can use without issues on production .. but has a small limitation. Cannot be used on windows stations. This problem is solved by Waitress, a powerful WSGI-ready server.
Install waitress
$ pip install waitress
We can execute our simple WSGI app under waitress using a single line:
$ waitress-serve myapp:app
By default, waitress starts on port 8080, but we can adjust the port using --port
argument:
$ waitress-serve --port=8000 myapp:app
That was pretty simple, right?
WSGI App - Flask version
If we take a second look at myapp.py
, we can see that our code delivers only a simple text and nothing else. How about setting a database, a fancy UI, some forms, security maybe?
Well, using Flask we can re-use many modules and features coded by open-source enthusiasts across the globe.
Before using Flask
, we need to install it. PIP
comes to the rescue:
$ pip install flask
A super simple (WSGI) Flask app might be this one:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello WSGI ... from Flask!'
Save the content as
flask_app.py
for later reference.
flask_app.py does the following:
- Import the Flask module
- Defines the WSGI object with the name
app
- Define a default
route
that returns a simple string
Execute with Gunicorn
$ gunicorn flask_app:app
[3445] [INFO] Starting gunicorn 19.10.0
[3445] [INFO] Listening at: http://127.0.0.1:8000 (3445)
[3445] [INFO] Using worker: sync
[3449] [INFO] Booting worker with pid: 3449
The Browser effect
Execute using waitress is super simple. We need to write just a single line:
$ waitress-serve --port=8000 flask_app:app
If we visit the app in the browser, we should see the same dummy
message Hello WSGI ... from Flask!
.
What is Nginx
At this point, we are able to start the app using Gunicorn and Waitress but the production environment requires a secure HTTPS connection, the recommended way to expose services in current times. To achieve this, we need a proxy
server configured in front of Gunicorn/Waitress to secure the connection with the browser. Nginx can be used as reverse-proxy
.
For newcomers, A reverse proxy is a server that sits in front of web servers and forwards client (e.g. web browser) requests to those web servers. Reverse proxies are typically implemented to help increase security, performance, and reliability.
Cloudfare provides a good intro to this useful concept - What Is A Reverse Proxy.
How to set up Nginx
Before using Nginx, we need to install it. If your production server uses Ubuntu, here is the magic line:
$ sudo apt install nginx
On CentOS servers, the syntax is slightly different:
$ sudo yum install epel-release
$ sudo yum install nginx
Start the Nginx server
$ systemctl status nginx
Nginx now serves a welcome page, and we need to add a simple configuration to link the default port 80
to forward the requests back & fort to our WSGI app.
If we assume that WSGI app runs on port 8000
using Gunicorn or Waitress, Nginx must be configured to bind that address. We can do this with ease, by editing a single file.
$ vi /etc/nginx/sites-enabled/default [On Debian/Ubuntu]
$ vi /etc/nginx/nginx.conf [On CentOS/RHEL]
Before editing anything, is recommended to backup the current file, in case something is not configured properly. Once we did this, the file should contain the following snippet:
server {
listen 80;
server_name www.my-domain.com;
location / {
proxy_pass http://127.0.0.1:8000;
include proxy_params;
}
}
To load this new configuration, we need to restart Nginx:
$ sudo systemctl reload nginx
By accessing the port 80
in the browser, we should see the same message previously served by the WSGI apps.
With all those concepts understood, we can move further with this presentation and mention a few starters already configured for Nginx/Gunicorn, HEROKU, and Docker.
In case you have issues using the samples, just drop any questions in the comments area or join the AppSeed Discord server and ask for help.
Flask Black Dashboard
Open-Source admin dashboard coded in Flask Framework - Features:
- LIVE Demo
- Product Page
- DBMS: SQLite, PostgreSQL (production)
- DB Tools: SQLAlchemy ORM, Alembic (schema migrations)
- Modular design with Blueprints
- Session-Based authentication (via flask_login), Forms validation
- Deployment scripts: Docker, Gunicorn / Nginx, Heroku
Flask Datta Able
Open-Source admin dashboard coded in Flask Framework - Features:
- LIVE Demo
- Product Page
- DBMS: SQLite, PostgreSQL (production)
- DB Tools: SQLAlchemy ORM, Alembic (schema migrations)
- Modular design with Blueprints
- Session-Based authentication (via flask_login), Forms validation
- Deployment scripts: Docker, Gunicorn / Nginx, Heroku
Flask Corona Dark
Open-Source admin dashboard coded in Flask Framework - Features:
- LIVE Demo
- Product Page
- DBMS: SQLite, PostgreSQL (production)
- DB Tools: SQLAlchemy ORM, Alembic (schema migrations)
- Modular design with Blueprints
- Session-Based authentication (via flask_login), Forms validation
- Deployment scripts: Docker, Gunicorn / Nginx, Heroku
Flask Atlantis Lite
Open-Source admin dashboard coded in Flask Framework - Features:
- LIVE Demo
- Product Page
- DBMS: SQLite, PostgreSQL (production)
- DB Tools: SQLAlchemy ORM, Alembic (schema migrations)
- Modular design with Blueprints
- Session-Based authentication (via flask_login), Forms validation
- Deployment scripts: Docker, Gunicorn / Nginx, Heroku
Flask CoreUI
CoreUI is an Open Source Bootstrap Admin Template. But CoreUI is not just another Admin Template. It goes way beyond hitherto admin templates thanks to transparent code and file structure. And if that's not enough, let’s just add that CoreUI consists bunch of unique features and over 1000 high-quality icons.
- LIVE Demo
- Product Page
- DBMS: SQLite, PostgreSQL (production)
- DB Tools: SQLAlchemy ORM, Alembic (schema migrations)
- Modular design with Blueprints
- Session-Based authentication (via flask_login), Forms validation
- Deployment scripts: Docker, Gunicorn / Nginx, Heroku
Thank you for reading! Let me know your thoughts in the comments.
Thanks for reading! For more resources, feel free to access:
- 👉 More Flask Dashboards crafted in Django, Flask, and
React
- 👉 More Flask Apps - free & PAID
Top comments (5)
Nice intro! How about setting up SSL in that Nginx?
Hello!
Digital Ocean has a nice tutorial on this point, using self-signed certs.
Create a Self-Signed SSL Certificate for Nginx on CentOS 7
By using the console, via OpenSSL, the certs can be easily created.
Once you have the certificate and private key, the Nginx should be configured to use them.
Sounds like an easy set up! Thank you!
Great List.👍
Thank you!