Beginners guide to install a Flask (Python) web server on Raspberry PI


Last Updated on 2nd September 2023 by peppe8o

In this tutorial I’m going to show you how to setup flask on Raspberry PI to publish a simple web page.

Common web servers run on LAMP (Linux Apache MySql Php). With Python evolving into one of most loved programming language, Flask became a more and more important option in creating web application, as it runs also in our loved Raspberry PI computer boards.

What is Flask

Flask is a lightweight web application framework. Compared to LAMP servers, it can take the place of Apache and Php in web stack.

flask logo

It is designed to make simple the very first setup and publishing, leaving ability to scale with easy. Being one of the most popular Python web application frameworks, Flask doesn’t require specific dependencies to start your project. Developers are free to use their favourite libraries and a growing number of Flask extensions provided by community.

Whole web application can fit into a single Python file, keeping the core simple, but can also include extensions libraries in a logic compliant to python packages. Flask also gives freedom on choosing database, templates and static files. By default, As Flask doesn’t include a database abstraction layer, you can use extensions to add such functionality to your application as if it was implemented in Flask itself. Extensions provide database integration, form validation, upload handling, various open authentication technologies, and more.

Flask can be setup with many configuration values, with sensible defaults, and a few conventions when getting started. By convention, templates and static files are stored in subdirectories within the application’s Python source tree, with the names templates and static respectively. While this can be changed, you usually don’t have to, especially when getting started.

Flask can be considered a glue layer to the best that Python has to offer, also taking advantage of framework-agnostic tools built for WSGI, the Python web interface.

In this tutorial I’m going to use a cheap Raspberry PI Zero W, but procedure will be the same with newer Raspberry PI computer boards.

What We Need

Raspberry PI Zero W

As usual, I suggest adding from now to your favourite e-commerce shopping cart all the needed hardware, so that at the end you will be able to evaluate overall costs and decide if to continue with the project or remove them from the shopping cart. So, hardware will be only:

Check hardware prices with following links:

Amazon raspberry pi boards box
Amazon raspberry pi Zero W box
Amazon Micro SD box
Amazon Raspberry PI Power Supply box

Step-by-Step Procedure

Prepare Operating System

Start installing your OS. As it is a web server, I suggest to use Raspberry PI OS Lite (for a fast and performing OS). You can also use Raspberry PI OS Desktop (in this case working from its internal termina).

Make your operating system updated. From terminal, use following command:

sudo apt update -y && sudo apt upgrade -y

Flask team also suggest to use Python virtual environments for creating your web server. For this reason we need following package:

sudo apt install python3-venv

Install Flask

Create your project directory and enter it:

mkdir myproject
cd myproject

Create and activate a virtual environment named “development”:

python3 -m venv development
. development/bin/activate
pip install Flask

Create your web application. I will name it “”, but you aree free to use your favourite name, caring to NOT use “” in order to avoid name conflicts:


Copy following content:

from flask import Flask
app = Flask(__name__)

def hello_world():
    return 'Hello, Peppe8o users!'

First line imports Flask library.

After this, we create an “app” instance and pass a “name” variable that Python will fill for us when program is running. This variable will be “main”, if this file is being directly run through Python as a script. If we are importing a different file to enrich our application (for example an “”), this value will get the name of imported file (“external”).

The @app.route(“/”) line defines what to answer when root document is required by client browser. The @ is a decorator, which allows the following function, property, or class to be dynamic.

The hello_world method is where we put the code to run, in our example simply answering with “Hello, Peppe8o users!” text. This text can be enriched with html tags.

Final folder structure is:


Next step is running hello application. After exporting file name to FLASK_APP variable, we can run it with flask command:

flask run --host=

NOTE: if you don’t specify “–host” parameter, it will start running on local host, making page visible only from an internal browser in your Raspberry PI. You can also use a different port by appending “–port” option.

Terminal will start showing something like following:

(development) pi@raspberrypi:~/myproject $ flask run --host=     
 * Serving Flask app ""
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on (Press CTRL+C to quit)

Using your Raspberry PI’s IP address instead of mine ( and correct port as from terminal log, you can browse from a remote computer resulting page:

raspberry pi flask running

And requests from remote clients will be logged in your terminal with following lines (where first IP address is the one of your remote client): - - [01/Apr/2021 13:57:20] "GET / HTTP/1.1" 200 -

Last “200” code means that connection has been answered corretcly.

Daemonize Flask With Gunicorn

Using flask from terminal is not so confortable, because it will go down when terminal session will be closed. Gunicorn is one of options to get flask daemonized. Install it from your virtual environment:

(development) pi@raspberrypi:~/myproject $ pip install gunicorn

Basic gunicorn usage (to check thta all is ok) is with following command:

gunicorn -w 1 -b hello:app
  • “-w” optin identifies how many workers (processes) are used.
  • “-b” option identified the address/port to bind
  • hello:app calls our hello(.py) file and its internal app (“app = Flask(__name__)” row). Please note that we are executing this command inside the “myproject” folder. If you run this from upper level, you will need to use “myproject.hello:app” instead.

Commands will still show in terminal:

[2021-04-01 14:01:55 +0100] [574] [INFO] Starting gunicorn 20.1.0
[2021-04-01 14:01:55 +0100] [574] [INFO] Listening at: (574)
[2021-04-01 14:01:55 +0100] [574] [INFO] Using worker: sync
[2021-04-01 14:01:55 +0100] [577] [INFO] Booting worker with pid: 577

And from browser:

raspberry pi flask running gunicorn

Now that we are sure all is ok, we can move to daemonized version by appending “-D” option and saving logs with “–log-file” option:

gunicorn -w 1 -b hello:app -D --log-file=gunicorn.log

This will create a background process (available from “ps -ef” list) that can be killed with the command:

pkill gunicorn

A useful final note is how to activate the whole after a system reboot. Commands will be:

cd myproject
python3 -m venv venv
. venv/bin/activate
gunicorn -w 1 -b hello:app -D --log-file=gunicorn.log

Final toughts

Previous steps allow to create a development environment. The main difference between development and production is that latter will be usually exposed to port 80 (http) or 443 (https). For this, please refer to Flask deployment on production docs page.


How useful was this post?

Click on a star to rate it anonymously!

Average rating 4.3 / 5. Vote count: 4

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?