Prepare Flask for production
Learn how to prepare Flask for production
Introduction​
Flask is an open-source Python microframework used for building web applications. Emphasize its simplicity, flexibility, and wide adoption within the Python community.
Deployment is the process of making your Flask application accessible to users on a live server ensuring its stability, security, and optimal performance.
For this reference guide, we will be covering some things to be done before deploying your application to ensure the application is both safe and the deployment employ best practices
We will be making reference to Flask Berry dashboard for this tutorial.
✅ Setting up Flask Application​
Clone the repository to your machine
$ git clone https://github.com/app-generator/flask-berry-dashboard.git
$ cd flask-berry-dashboard
Create a virtual environment and activate it
On windows
$ virtualenv venv
$ .\venv\Scripts\activate
(venv) $
On Linux/Mac
$ virtualenv venv
$ source venv/bin/activate
(venv) $
Install the packages using pip
(venv) $ pip install -r requirements.txt
Once you have your application set up, we would start making changes to make the app fit for deployment.
✅ Codebase Update for Deployment
​
We will be going through some general setups for deployment and then some specific setups for deployment on different platforms.
✅ Update Environment
Variables​
- Create a file named
.env
in the root folder of your project, this file will hold environmental variables and their values.
# .env
FLASK_APP=run.py # application entry point
SECRET_KEY=<your-secret-key>
DB_ENGINE=<database-to-be-used>
DB_HOST=<db-host-name-or-ip>
DB_NAME=<database-name>
DEBUG=False
SECRET_KEY
is a random string that is used to protect your Flask application from attack.
It is used to encrypt cookies and other sensitive data. If an attacker can guess your secret key, they could potentially steal your users' session data or other sensitive information.
Using the python-dotenv
package, the contents of the .env
file are loaded into environmental variables when the application starts.
✅ Handle DataBase Migration
​
Migrations are a way to track changes to your database schema over time. This makes it easy to roll back changes if something goes wrong or to deploy your application to a new environment.
Flask-Migrate
is a Flask extension that provides support for database migrations.
- From the terminal install flask-migrate
(venv) $ pip install flask-migrate
- In the entry point of your application (
run.py
) add the following line of code
# run.py
...
from flask_migrate import Migrate
...
# after creating Flask and SQLAlchemy objects
Migrate(app, db)
...
- Next step is to create the migration directory and apply the migration to the current database schema
(venv) $ flask db init
(venv) $ flask db migrate --message "initial db migration"
By setting up flask-migrate
you can be able to move scale your application database and alter its schema without losing data.
✅ Compressing Assets via Flask-Minify
​
Flask-Minify
is a Flask extension that can be used to minify HTML, CSS, and JavaScript files.
Minifying files can help to improve the performance of your Flask application by reducing the size of the files that need to be downloaded by the user.
Install flask-minify from the terminal with the command
(venv) $ pip install flask-minify
Add the following to
run.py
to enable the application to useflask-minify
# run.py
...
from flask_minify import Minify
...
# after creating the Flask object
Minify(app=app, html=True, js=False, cssless=True)
...
Test the minification of your files to make sure that it does not break your application. Minification can sometimes introduce errors in your files, so it is important to test them thoroughly before you deploy your application.
✅ Increasing Security using Flask-Talisman
​
Flask-Talisman
is a Flask extension that helps to secure your Flask application by setting HTTP security headers. These headers can help to protect your application from a variety of common web attacks, such as cross-site scripting (XSS), clickjacking, and session hijacking.
- Install
Flask-Talisman
from the terminal
(venv) $ pip install flask-talisman
- Setup flask-talisman by adding this line of code in
run.py
# run.py
...
from flask_talisman import Talisman
...
talisman = Talisman(app)
...
With this, we have added a new layer of security to our application in a production environment.
✅ Serve Static Files via CDN
​
A content delivery network (CDN) is a network of servers that are distributed around the world. CDNs can be used to improve the performance of web applications by delivering static content, such as images and JavaScript files, from the server that is closest to the user.
To deploy a Flask application using a CDN, you will need to:
- Choose a CDN provider. There are many CDN providers available, such as Amazon CloudFront, Cloudflare, and Akamai.
- Create an account with the CDN provider.
- Upload your static content to the CDN provider in a compressed format. This will reduce the size of the files and improve the performance of your application.
- To configure your Flask application to use the CDN, add the following to the
.env
file
# .env
# CDN Support
# Note: Used only when DEBUG=False (production mode)
# CDN_DOMAIN="YYY.ZZZ.com/berry-bootstrap5-v101"
Install
Flask-cdn
from the terminal
(venv) $ pip install Flask-CDN
Adding
flask-cdn
to the flask application,apps/__init__.py
contain a function for creating a flask object, that is where we will be initializing our CDN
# apps/__init__.py
...
from flask_cdn import CDN
cdn = CDN()
...
def create_app():
...
if not DEBUG and 'CDN_DOMAIN' in app.config:
cdn.init_app(app)
return app
Add the CDN domain to your python flask configuration.
- Using a configuration file
apps/config.py
# apps/config.py
...
class Config:
...
CDN_DOMAIN = os.getenv('CDN_DOMAIN' , None)
...
...
- From the flask object "app" in run.py
# run.py
...
app.config['CDN_DOMAIN'] = os.getenv('CDN_DOMAIN' , None)
...
With this done, our application is ready to serve static files over a CDN.
✅ Deploying Flask Application​
Deploying a Flask application is a crucial step in turning your Python web application into a fully functional and accessible website. It involves the process of making your Flask application available to users on a live server, ensuring its stability, security, and optimal performance. Without proper deployment, your Flask application may not reach its intended audience or function as expected.
Deploying a Flask application goes beyond simply running it on your local development environment. It requires careful planning, configuration, and implementation of various steps to ensure a successful deployment.
Before you start the process of deploying your application, execute the command below on your terminal to create an updated requirements.txt
file.
(venv) $ pip freeze > requirements.txt
Deploy using Docker​
Docker is a popular containerization platform that allows you to package and distribute applications along with their dependencies in a portable and isolated environment. It provides a consistent and reproducible way to build, ship, and run applications, making it easier to deploy applications across different environments without worrying about compatibility issues.
For this tutorial, we will be using Nginx
as the reverse proxy server and `Gunicorn to serve the application.
A reverse proxy is a server that sits between the internet and a web application. It can be used to improve the performance, security, and reliability of the web application. Gunicorn is an application server that can be used to run web applications. It is designed to be used with a reverse proxy. If Gunicorn is exposed directly to the internet, it can be vulnerable to denial-of-service (DoS) attacks. A DoS attack is an attempt to make a computer or network resource unavailable to its intended users. In the case of Gunicorn, a DoS attack could be performed by creating a load that trickles data to the servers.
This type of attack is known as a Slowloris attack.
We will start by configuring our docker container.
- Create a file
docker-compose.yml
in the root folder of your project
# docker-compose.yml
version: '1.0' # the current version of your application
services:
appseed-app: # can be given any name
container_name: appseed_app
restart: always
build: .
networks:
- db_network
- web_network
nginx:
container_name: nginx
restart: always
image: "nginx:latest"
ports:
- "5085:5085"
volumes:
- ./nginx:/etc/nginx/conf.d # mapping nginx configuration to a configuration file we will be creating
networks:
- web_network
depends_on:
- appseed-app
networks:
db_network:
driver: bridge
web_network:
driver: bridge
- Create a Nginx configuration file named
appseed-app.conf
in a foldernginx
in the root of your project as seen under "volumes" from the docker-compose.yml file.
# nginx/appseed-app.conf
upstream webapp {
server appseed_app:5005; # the address and port of the Gunicorn server
}
server {
listen 5085;
server_name localhost;
location / {
proxy_pass http://webapp;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
- In the root of your project, create a file
gunicorn-cfg.py
. This is a gunicorn configuration file. Add the following contents to the file
# gunicorn-cfg.py
bind = '0.0.0.0:5005'
workers = 1
accesslog = '-'
loglevel = 'debug'
capture_output = True
enable_stdio_inheritance = True
Variables can be changed to meet the demands of your application.
- Create a
.dockerignore
file and add the following
# .dockerignore
.git
__pycache__
*.pyc
*.pyo
*.pyd
- Now we will be creating
Dockerfile
which contains the instructions that will be used to build a Docker image.
# Dockerfile
FROM python:3.9
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY .env .
COPY requirements.txt .
# install python dependencies
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# gunicorn
CMD ["gunicorn", "--config", "gunicorn-cfg.py", "run:app"]
- Execute the command to build the docker image and deploy the application on docker.
(venv) $ docker-compose up --build
Now your application is running on docker. If you are running the application on your machine, visit http://localhost:5085
to access your application.
Deploy on Render
​
Deploying Flask application on render is straightforward
Create an account on render
Ensure your code is present on Github, Gitlab or any public repository
After completing account creation and verification, open your dashboard, click "New", create a
Web Service
and connect the code repositoryUse the following values when creating the service
- Runtime - Python
- Build Command -
pip install requirements.txt
- Start Command -
gunicorn run:run
Create a web service and check it out with your browser on
https://<service-name>.onrender.com
Deploy on HEROKU
​
- Create an account with heroku
- After account creation, download and install Heroku cli here
- Once the installation is complete, you have to log in using the command
(venv) $ heroku login
- Create a file
Procfile
with the command for starting the application by executing the command
(venv) $ echo "web: gunicorn run:app" > Procfile
- Stage and commit the changes with git
(venv) $ git add .
(venv) $ git commit -m "Changes for deployment"
- Create the Heroku application by executing the command and push the code base to the Heroku repository that the application will be hosted from by executing the commands below
(venv) $ heroku create <webapp-name>
(venv) $ git push heroku master
This will set up the application and start the Gunicorn server.
- Open the application by executing the command
(venv) $ heroku open
✅ In Summary​
In this article, we have covered the steps involved in setting up, preparing, and deploying a Flask application. We have also discussed some of the best practices for securing and optimizing your application.
Here are some of the key takeaways from this article:
- Flask is a powerful Python micro framework that can be used to create a wide variety of web applications.
- When setting up a Flask application, it is important to configure your application's environment variables and enable database migration.
- You can improve the security of your application by using Flask-Talisman and serving static files using a CDN.
- There are a variety of deployment options available for Flask applications, including Docker, Render, and Heroku.
✅ Resources​
- 👉 Access AppSeed for more starters and support
- 👉 Deploy Projects on Aws, Azure and DO via DeployPRO
- 👉 Create landing pages with Simpllo, an open-source site builder
- 👉 Build apps with Django App Generator (free service)