Welcome to another Raspberry Pi Tutorial! In the last tutorial, I showed you How to run a Flask App on a Raspberry Pi In today's tutorial, we will take another step run a Flask app behind an Apache web server. Why? In the next tutorial, we'll use a simple web app to make an AJAX request to turn on and off an LED from a browser. A flask app runs on port 5000 and if we serve the web page through Flask, then it's fine, but no one wants to go to a website with a Port number. So because of that, we will run the Flask app behind Apache so that we can simpley hit our Pi's IP address and control our LED. There are ways to enable Flask to accept CORS requests and resources for that are easy to find. If there's enough interest, I can create a separate tutorial covering that.
I showed you how to turn on an LED using two different libraries in a previous tutorial. At the end of this mini-series, we'll turn our LED on and off with our browser.
Some of the steps in this tutorial are repeats because I quickly go over how to set up your virtual environment and run a Flask app again. So feel free to skim through these.
To get started, let's install our venv
where our Apache is installed by doing these commands:
cd /var/www
This will take us to our Apache's www
folder. Then let's create a simple folder to house our Flask app, feel free to call it anything you want but I called it piapp
:
sudo mkdir piapp cd piapp
If you don't already have venv
installed, install it now:
sudo apt install python3-venv
This creates a blank folder called piApp
. You can call this anything you want. Now we'll install venv
:
sudo python3 -m venv venv
You can name the virtual environment folder anything you want, I called it venv
. We need to then activate our virtual environment with this command:
. venv/bin/activate
Your terminal should now be prefixed with (venv), which means that any action you take here, will only happen in your virtual environment. There's one quirk that I ran into while installing flask. You may also run into a weird permission error when trying to install flask. When your venv is created, the environment is owned by root. So if you run into this issue, deactivate
your virtual environment then run this command to change the owner of the environment before proceeding:
sudo chown -R pi:pi venv
Then reactivate your venv and continue. Now let's install Flask:
pip install flask
If everything goes well, you'll get a success message at the end. Now let's create a simple Python script that will serve as our root Flask app. I called it piapp.py
but you can call it anything you want.
sudo nano piapp.py
In the file, add this:
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!'
The code is taken directly from the Flask documentation found here: http://flask.pocoo.org/docs/1.0/quickstart/
If you want to test your app before proceeding with Apache, run it with:
flask run --host=0.0.0.0
We need one additional dependency before we can move forward with Apache. In the past the venv package came with a file called activate_this.py which allowed external processes to activate and run scripts from a particiular virtual environment. I'm not sure when this was removed but we need to put the file in the venv/bin/ directory:
cd venv/bin/ wget https://raw.githubusercontent.com/naztronaut/RaspberryPi-RGBW-Control/master/utils/activate_this.py
This will grab a working version of the activate_this.py script. Note that I've updated the link to one of my own Repos because the original posted doesn't have the script anymore and I wasn't able to locate one.
Why do we need this?
Because Flask is not installed globally and is only accessible through our virtual environment, Apache (as a global user and install) will not be able to access our virtual environment. Let's make some changes to our Apache configs (you may want to deactivate your virtual environment now but I have not noticed any issues either way):
cd /etc/apache2/sites-available sudo nano piapp.conf
We go into the sites-avaialble directory which contains our Apache configurations. We can edit the default confg but I've decided to create a brand new one called piapp.conf. Edit the file and input these values:
<VirtualHost *:80> ServerName nazberrypi WSGIDaemonProcess piapp user=pi group=www-data threads=5 WSGIScriptAlias /piapp /var/www/piapp/piapp.wsgi <Directory /var/www/piapp> WSGIProcessGroup piapp WSGIApplicationGroup &{GLOBAL} Require all granted </Directory> </VirtualHost>
If you installed your Flask app in a diffrent directory, make sure you make those edits above before saving. As the WSGIScriptAlias suggests, we need a piapp.wsgi file. But before we create it, let's make sure that our Pi can run this configuration by installing a libapache module:
sudo apt install libapache2-mod-wsgi-py3 -y
I've learned that Apache or Pi doesn't come with this enabled by default. Once this is installed, we can enable our configuration and disable the default one with these commands:
sudo a2ensite piapp.conf sudo a2dissite 000-default.conf sudo service apache2 restart
If everything went well, you'll be able to enable your new config, disable the old default one, and restart Apache without any errors. After making those changes, let's go back and create that .wsgi file:
cd /var/www/piapp sudo nano piapp.wsgi
Then in the file, input this:
#!/usr/bin/env python3 activate_this = '/var/www/piapp/venv/bin/activate_this.py' with open(activate_this) as file_: exec(file_.read(), dict(__file__=activate_this)) import sys sys.path.insert(0, '/var/www/piapp') from piapp import app as application
This file will be accessed by Apache (user www-data), it will use the activate_this.py script and import then run the Flask app on port 80. Since it's port 80, we don't need to specify it in our browser when we visit the page. Again, if you placed your files in a different locations, make the necessary edits above.
If all went well, you can restart Apache and see if you are able to access your Flask App:
sudo service apache2 restart
Now you can try to visit your Flask app without the App and see the magic work: http://{{ip_addr}}/piapp
In the next tutorial, I will show you how to turn on an LED using your browser! We are finally getting there.
That's all!
Giveaway
Now if you're here about the giveaway, keep reading:
This is my fourth Raspberry Pi giveaway. Here are the official rules:
Here are a list of official rules:
Past winners are welcome to try again! Comments on YouTube and EasyProgramming will earn you one entry each. Patrons on Patreon will get 5 entries per tier! Meaning you can get up to 15 entries on Patreon alone. Look to becoming a patron: https://www.patreon.com/nazmus.
Bonus entry can be made on the EP subreddit, so be on the lookout for that thread: https://www.reddit.com/r/EasyProgramming/
I apologize again for opening up to US residents only. Since I'm covering the costs myself, I need to be able to minimize costs so that give away more of these. International shipping is just so expensive! I do hope to open it to international folks at some point.
Enjoy the tutorial and good luck in the drawing!
Remember to checkout the Resources section below for associated downloadable content, JSFiddle links, and other resources. Watch the video and follow along!
No resources from Easy Programming for this video! Follow me on Github for other resources https://github.com/naztronaut
But be sure to check out the Flask documentation here for a better understanding of how to use Flask: http://flask.pocoo.org/docs/1.0/quickstart/