Skip to content

Commit 01f42ee

Browse files
committed
2 parents 259f7c3 + ad4eee9 commit 01f42ee

File tree

2 files changed

+654
-229
lines changed

2 files changed

+654
-229
lines changed

docs/technologies/flask/production-checklist.mdx

Lines changed: 372 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,382 @@ import SubHeading from "@site/src/components/SubHeading";
1010

1111
## Introduction
1212

13-
ToDO
13+
Flask is an open-source Python microframework used for building web applications. Emphasize its simplicity, flexibility, and wide adoption within the Python community.
14+
15+
Deployment is the process of making your Flask application accessible to users on a live server ensuring its stability, security, and optimal performance.
16+
17+
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
18+
19+
We will be making reference to [Flask Berry dashboard](https://github.com/app-generator/flask-berry-dashboard) for this tutorial.
20+
21+
## Setting up Flask application
22+
- Clone the repository to your machine
23+
```bash
24+
$ git clone https://github.com/app-generator/flask-berry-dashboard.git
25+
$ cd flask-berry-dashboard
26+
```
27+
- Create a virtual environment and activate it
28+
29+
On windows
30+
```bash
31+
flask-berry-dashboard$ virtualenv venv
32+
flask-berry-dashboard$ .\venv\Scripts\activate
33+
(venv) flask-berry-dashboard$
34+
```
35+
On Linux/Mac
36+
```bash
37+
flask-berry-dashboard$ virtualenv venv
38+
flask-berry-dashboard$ source venv/bin/activate
39+
(venv) flask-berry-dashboard$
40+
```
41+
42+
- Install the packages using pip
43+
```bash
44+
(venv) flask-berry-dashboard$ pip install -r requirements.txt
45+
```
46+
47+
Once you have your application set up, we would start making changes to make the app fit for deployment.
48+
49+
## Preparing Flask application for deployment
50+
We will be going through some general setups for deployment and then some specific setups for deployment on different platforms.
51+
52+
### Configuring application environmental variables
53+
- Create a file named `.env` in the root folder of your project, this file will hold environmental variables and their values.
54+
55+
```bash
56+
# .env
57+
FLASK_APP=run.py # application entry point
58+
SECRET_KEY=<your-secret-key>
59+
DB_ENGINE=<database-to-be-used>
60+
DB_HOST=<db-host-name-or-ip>
61+
DB_NAME=<database-name>
62+
DEBUG=False
63+
```
64+
`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.
65+
66+
Using the `python-dotenv` package, the contents of the `.env` file are loaded into environmental variables when the application starts.
67+
68+
### Enabling database migration for application
69+
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.
70+
`Flask-Migrate` is a Flask extension that provides support for database migrations.
71+
72+
- From the terminal install flask-migrate
73+
```bash
74+
(venv) flask-berry-dashboard$ pip install flask-migrate
75+
```
76+
77+
- In the entry point of your application (`run.py`) add the following line of code
78+
```py
79+
# run.py
80+
...
81+
from flask_migrate import Migrate
82+
...
83+
# after creating Flask and SQLAlchemy objects
84+
Migrate(app, db)
85+
...
86+
```
87+
88+
- Next step is to create the migration directory and apply the migration to the current database schema
89+
90+
```bash
91+
(venv) flask-berry-dashboard$ flask db init
92+
(venv) flask-berry-dashboard$ flask db migrate --message "initial db migration"
93+
```
94+
95+
By setting up `flask-migrate` you can be able to move scale your application database and alter its schema without losing data.
96+
97+
### Minifying application files using `Flask-Minify`
98+
`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.
99+
100+
- Install flask-minify from the terminal with the command
101+
```bash
102+
(venv) flask-berry-dashboard$ pip install flask-minify
103+
```
104+
105+
- Add the following to `run.py` to enable the application to use `flask-minify`
106+
```py
107+
# run.py
108+
...
109+
from flask_minify import Minify
110+
...
111+
# after creating the Flask object
112+
Minify(app=app, html=True, js=False, cssless=True)
113+
...
114+
```
115+
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.
116+
117+
### Increasing Application security using `Flask-Talisman`
118+
119+
`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.
120+
121+
- Install `Flask-Talisman` from the terminal
122+
```bash
123+
(venv) flask-berry-dashboard$ pip install flask-talisman
124+
```
125+
126+
- Setup flask-talisman by adding this line of code in `run.py`
127+
```py
128+
# run.py
129+
...
130+
from flask_talisman import Talisman
131+
...
132+
talisman = Talisman(app)
133+
...
134+
```
135+
With this, we have added a new layer of security to our application in a production environment.
136+
137+
### Serve static files using CDN
138+
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.
139+
140+
To deploy a Flask application using a CDN, you will need to:
141+
142+
- Choose a CDN provider. There are many CDN providers available, such as Amazon CloudFront, Cloudflare, and Akamai.
143+
144+
- Create an account with the CDN provider.
145+
146+
- 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.
147+
148+
- To configure your Flask application to use the CDN, add the following to the `.env` file
149+
```
150+
# .env
151+
# CDN Support
152+
# Note: Used only when DEBUG=False (production mode)
153+
# CDN_DOMAIN="YYY.ZZZ.com/berry-bootstrap5-v101"
154+
```
155+
156+
- Install `Flask-cdn` from the terminal
157+
```
158+
(venv) flask-berry-dashboard$ pip install Flask-CDN
159+
```
160+
161+
- 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
162+
```py
163+
# apps/__init__.py
164+
...
165+
from flask_cdn import CDN
166+
167+
cdn = CDN()
168+
...
169+
170+
def create_app():
171+
...
172+
if not DEBUG and 'CDN_DOMAIN' in app.config:
173+
cdn.init_app(app)
174+
175+
return app
176+
```
177+
178+
- Add the CDN domain to your python flask configuration.
179+
180+
* Using a configuration file `apps/config.py`
181+
```py
182+
# apps/config.py
183+
...
184+
class Config:
185+
...
186+
CDN_DOMAIN = os.getenv('CDN_DOMAIN' , None)
187+
...
188+
...
189+
```
190+
* From the flask object "app" in run.py
191+
```py
192+
# run.py
193+
...
194+
app.config['CDN_DOMAIN'] = os.getenv('CDN_DOMAIN' , None)
195+
...
196+
```
197+
198+
With this done, our application is ready to serve static files over a CDN.
199+
200+
## Deploying Flask Application
201+
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.
202+
203+
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.
204+
205+
Before you start the process of deploying your application, execute the command below on your terminal to create an updated `requirements.txt` file
206+
```
207+
(venv) flask-berry-dashboard$ pip freeze > requirements.txt
208+
```
209+
210+
### Deploy using Docker
211+
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.
212+
213+
For this tutorial, we will be using `Nginx` as the reverse proxy server and `Gunicorn to serve the application.
214+
215+
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.
216+
217+
We will start by configuring our docker container.
218+
219+
- Create a file `docker-compose.yml` in the root folder of your project
220+
```yml
221+
# docker-compose.yml
222+
version: '1.0' # the current version of your application
223+
services:
224+
appseed-app: # can be given any name
225+
container_name: appseed_app
226+
restart: always
227+
build: .
228+
networks:
229+
- db_network
230+
- web_network
231+
nginx:
232+
container_name: nginx
233+
restart: always
234+
image: "nginx:latest"
235+
ports:
236+
- "5085:5085"
237+
volumes:
238+
- ./nginx:/etc/nginx/conf.d # mapping nginx configuration to a configuration file we will be creating
239+
networks:
240+
- web_network
241+
depends_on:
242+
- appseed-app
243+
networks:
244+
db_network:
245+
driver: bridge
246+
web_network:
247+
driver: bridge
248+
```
249+
250+
- Create a Nginx configuration file named `appseed-app.conf` in a folder `nginx` in the root of your project as seen under "volumes" from the docker-compose.yml file.
251+
```
252+
# nginx/appseed-app.conf
253+
upstream webapp {
254+
server appseed_app:5005; # the address and port of the Gunicorn server
255+
}
256+
257+
server {
258+
listen 5085;
259+
server_name localhost;
260+
261+
location / {
262+
proxy_pass http://webapp;
263+
proxy_set_header Host $host:$server_port;
264+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
265+
}
266+
267+
}
268+
```
269+
270+
- 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
271+
```py
272+
# gunicorn-cfg.py
273+
274+
bind = '0.0.0.0:5005'
275+
workers = 1
276+
accesslog = '-'
277+
loglevel = 'debug'
278+
capture_output = True
279+
enable_stdio_inheritance = True
280+
```
281+
Variables can be changed to meet the demands of your application.
282+
283+
- Create a `.dockerignore` file and add the following
284+
```
285+
# .dockerignore
286+
287+
.git
288+
__pycache__
289+
*.pyc
290+
*.pyo
291+
*.pyd
292+
```
293+
294+
- Now we will be creating `Dockerfile` which contains the instructions that will be used to build a Docker image.
295+
```
296+
# Dockerfile
297+
FROM python:3.9
298+
299+
# set environment variables
300+
ENV PYTHONDONTWRITEBYTECODE 1
301+
ENV PYTHONUNBUFFERED 1
302+
303+
COPY .env .
304+
COPY requirements.txt .
305+
306+
# install python dependencies
307+
RUN pip install --upgrade pip
308+
RUN pip install --no-cache-dir -r requirements.txt
309+
310+
COPY . .
311+
312+
# gunicorn
313+
CMD ["gunicorn", "--config", "gunicorn-cfg.py", "run:app"]
314+
```
315+
316+
- Execute the command to build the docker image and deploy the application on docker.
317+
```bash
318+
(venv) flask-berry-dashboard$ docker-compose up --build
319+
```
320+
Now your application is running on docker. If you are running the application on your machine, visit [`http://localhost:5085`](http://localhost:5085) to access your application.
321+
322+
### Deploy on Render
323+
Deploying Flask application on render is straightforward
324+
325+
- Create an account on [render](https://render.com)
326+
327+
- Ensure your code is present on Github, Gitlab or any public repository
328+
329+
- After completing account creation and verification, open your dashboard, click "New", create a `Web Service` and connect the code repository
330+
331+
- Use the following values when creating the service
332+
333+
* **Runtime** - Python
334+
* **Build Command** - `pip install requirements.txt`
335+
* **Start Command** - `gunicorn run:run`
336+
Create a web service and check it out with your browser on `https://<service-name>.onrender.com`
337+
338+
### Deploy on Heroku
339+
- Create an account with [heroku](https://signup.heroku.com/login)
340+
341+
- After account creation, download and install Heroku cli [here](https://signup.heroku.com/login)
342+
343+
- Once the installation is complete, you have to log in using the command
344+
```bash
345+
(venv) flask-berry-dashboard$ heroku login
346+
```
347+
348+
- Create a file `Procfile` with the command for starting the application by executing the command
349+
```
350+
(venv) flask-berry-dashboard$ echo "web: gunicorn run:app" > Procfile
351+
```
352+
353+
- Stage and commit the changes with git
354+
```bash
355+
(venv) flask-berry-dashboard$ git add .
356+
(venv) flask-berry-dashboard$ git commit -m "Changes for deployment"
357+
```
358+
359+
- 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
360+
```
361+
(venv) flask-berry-dashboard$ heroku create <webapp-name>
362+
(venv) flask-berry-dashboard$ git push heroku master
363+
```
364+
This will set up the application and start the Gunicorn server.
365+
366+
- Open the application by executing the command
367+
```
368+
(venv) flask-berry-dashboard$ heroku open
369+
```
370+
371+
## Conclusion
372+
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.
373+
374+
Here are some of the key takeaways from this article:
375+
376+
- Flask is a powerful Python micro framework that can be used to create a wide variety of web applications.
377+
- When setting up a Flask application, it is important to configure your application's environment variables and enable database migration.
378+
- You can improve the security of your application by using Flask-Talisman and serving static files using a CDN.
379+
- There are a variety of deployment options available for Flask applications, including Docker, Render, and Heroku.
380+
381+
I hope this article has been helpful. For more information on Flask, please visit the official website: https://flask.palletsprojects.com/en/2.1.x/
14382

15383
<br />
16384

17385
## Resources
18-
386+
- 👉 [Flask-Migrate](https://flask-migrate.readthedocs.io/en/latest/) documentation
387+
- 👉 [Flask-Minify](https://github.com/mrf345/flask_minify/) Homepage
388+
- 👉 [Flask-Talisman](https://github.com/wntrblm/flask-talisman) Homepage
19389
- 👉 [Replit](https://replit.com/) - the official website
20390
- 👉 Free [Support](https://appseed.us/support/) via Email & Discord
21391
- 👉 [Custom Development Services](https://appseed.us/custom-development/) provided by experts

0 commit comments

Comments
 (0)