The Flask Application Template contains the framework for quickly building a full stack application using your choice of database (PostgreSQL, MySQL, SQLite3) along with both Flask Login and OAuth Login, Bootstrap 5.2.2 HTML components, and Font Awesome Pro 6.0 icons.
The instructions below describe how to commission a (Raspberry Pi) microcomputer system running (Raspberry Pi OS) Linux with the Flask micro-framework that supports a full stack embedded application.
It is assumed that you are starting from scratch and that removable media (i.e., SD cards) will be completely erased.
If you have issues setting up either the wireless LAN connection or SSH, you may also need:
- Computer monitor
- Wireless USB keyboard/mouse/dongle
- USB Micro to USB adapter
- Micro-HDMI to HDMI adapter
And you'll usually need some form of development station, assuming a laptop computer.
In one of the steps below, you'll need a known SSH public key that you use with Secure Shell. You'll need to open the key file and then copy the contents to the clipboard so that you can paste it into a field during OS configuration below.
Note: The Raspberry Pi Imager program version 1.7.3 (and earlier) does not correctly configure the OS for a hidden wireless network. So you cannot use the Advanced options to setup your hidden network. Instead, follow the directions below under Fix Raspberry Pi Imager Broken WLAN Config to work around this issue.
- Insert MicroSD card into the card reader
- Insert the USB card reader into the laptop
- Download and install Raspberry Pi OS imager software on the laptop
- Launch the imager program
- Select CHOOSE OS then Raspberry Pi OS (other) then Raspberry Pi OS Lite (32-bit)
- Select CHOOSE STORAGE then select the USB mass storage device for your card reader
- Type CTRL + Shift + X to preconfigure the OS as follows:
- Select Set hostname then enter a short name for the Raspberry Pi
- Select Enable SSH then Allow public-key authentication only
- Select Set authorized_keys for 'username' and paste your known SSH public key here
- Select Set username and password then enter a username of choice and a password for that user
- Select Configure wireless LAN then enter the SSID (name) and password for your wireless network
- Set locale settings as necessary
- Finally, select SAVE
- Select WRITE and then confirm the write operation
- After the write operation is complete, exit the imager program
- Eject the USB card reader and remove the MicroSD card from the reader
- Make sure power is OFF on the Raspberry Pi
- Insert the MicroSD card into the Raspberry Pi memory card slot
- Turn power ON to the Raspberry Pi and wait ~5 minutes for the initial boot
The Raspberry Pi imager program (v1.7.3) does not correctly configure the wireless network adapter for hidden networks. There are two issues:
- The Raspberry Pi imager program fails to insert the
scan_ssid=1
line into thewpa_supplicant.conf
file so the OS fails to find the WLAN. - When you attempt to manually configure a separate
wpa_supplicant.conf
file (as given below), the OS, upon first boot, fails to recognize the WLAN country code setting, so the WLAN cannot function properly.
To correctly configure the wireless LAN interface, follow these two steps:
- Manually create a
wpa_supplicant.conf
file by following these instructions: Headless Raspberry Pi Setup - Manually setup the WLAN country code by following these instructions:
- You need to add a single line to the end of the
firstrun.sh
file located in the root (/) folder of the SD card holding the OS image. - Locate the
firstrun.sh
file on the SD card, and then open the file with your favorite editor (like Notepad on Windows). - Add the following line toward the end of the file before the script exits, replacing
xx
with your two letter country code (e.g., US):
sudo raspi-config nonint do_wifi_country xx
- Save the file, exit the editor.
- The WLAN country code should now be set correctly after the OS boots for the first time.
Preconfiguring the Raspberry Pi may result in the WLAN and SSH working, but probably not. So, you'll want to connect the monitor and keyboard to the Raspberry Pi so that you can log into the OS and make changes.
- Connect the monitor to the Raspberry Pi using the micro-HDMI adapter and a standard HDMI cable
- Connect the wireless USB keyboard/mouse dongle to the Raspberry Pi using the USB micro adapter
- Apply power to the Raspberry Pi (should see green lights flash as OS is loaded)
You should be able to log into the Raspberry Pi using the default credentials: Username='pi' Password='raspberry'
$ sudo apt -y update
$ sudo apt -y upgrade
$ sudo apt -y autoremove
$ cat /etc/os-release
$ sudo raspi-config
- Select Localisation Options
- Select WLAN Country
- Select US United States (or your country)
- Select Finish
Replace the contents of the wpa_supplicant.conf file with the following.
$ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=US
network={
ssid="yourwlanid"
scan_ssid=1
psk="yourwlanpassphrase"
key_mgmt=WPA-PSK
}
Reboot the Raspberry Pi to load the WLAN settings.
https://garywoodfine.com/setting-up-ssh-keys-for-github-access/
$ sudo raspi-config
- Select Interface Options
- Select SSH
- Select Yes
- Select Ok
- Select Finish
$ mkdir ~/.ssh
$ chmod 0700 ~/.ssh
$ cd ~/.ssh
$ ssh-keygen -t rsa
- Hit enter to accept default settings for all prompts
$ mv id_rsa.pub authorized_keys
$ chmod 0600 authorized_keys
$ ssh -T git@github.com
- Answer Yes to question about wanting to connect
- This should add GitHub to ~/.ssh/known_hosts file
Install PuTTY from https://www.putty.org/
Follow the instructions at the link below to add your private key generated above (id_rsa) to use in your PuTTY session.
https://docs.oracle.com/en/cloud/paas/goldengate-cloud/tutorial-change-private-key-format/
- Launch the PuTYTGen program
- Under Parameters, select RSA and use 2048 for bits in generated key
- Load your existing private key that you generated above (and saved locally)
- After you've loaded your existing private key, save the new key as a .ppk file that can be loaded by PuTTY
- Exit PuttyGen
- Launch PuTTY
- Configure settings for a new session
- Under Connection -> SSH -> Auth, find and open the .ppk file you just saved
- You should now be able to connect to your Raspberry Pi using SSH
Follow the instructions at the link below to add your public key to GitHub so that you can manage your Raspberry Pi software.
- Log into your GitHub account
- Select the dropdown menu (top-right) to acccess your account
- Select Settings
- Select SSH and GPG keys
- Select New SSH key
- Fill in the fields regarding the key (use id_rsa.pub key from previous step)
- Select Add SSH key
$ sudo apt -y install python3 python3-venv python3-dev python3-pip libmariadb-dev
$ sudo apt -y install build-essential libssl-dev libffi-dev cargo
$ sudo apt -y install supervisor nginx git
$ sudo pip install --upgrade pip
First on GitHub:
Create a new repository on GitHub
You'll need the URL for the new repository below; it has the form git@github.com:USERNAME/REPONAME.git
Then on the local development machine:
$ mkdir ~/flaskapp
$ cd ~/flaskapp
Verify that your email address and username are correct in the .gitconfig file.
$ git config --global user.name "FIRST_NAME LAST_NAME"
$ git config --global user.email "MY_NAME@example.com"
$ git clone git@github.com:lairdrt/flaskapp.git .
$ git remote remove origin
$ git remote add origin git@github.com:USERNAME/REPONAME.git
$ git remote -v
Target your new application by changing all references to flaskapp with the name of your app (e.g., myapp).
$ git push -u origin master
The Python Cryptography package is required for the pyOpenSSL package which is required for OAuth authorization. OAuth is used to log into the Flask application via third-party providers such as GitHub. The Python Cryptography package is built using the Rust compiler.
$ sudo curl https://sh.rustup.rs -sSf | sh
- Select option 1 (the default)
$ source $HOME/.cargo/env
When the Python packages are installed below, the Cryptography package will be built using the Rust compiler. On a Raspberry Pi Zero W (not Zero 2 W), the build can take up to four (4) hours!
You can uninstall the Rust compiler AFTER the Python packages are installed below by issuing the command:
$ sudo rustup self uninstall
$ cd ~/flaskapp
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install -r requirements.txt
Restore .env file typically to ~/flaskapp/app/instance
.
https://www.postgresql.org/download/linux/debian/
https://www.postgresql.org/files/documentation/pdf/15/postgresql-15-US.pdf
https://linuxize.com/post/how-to-install-postgresql-on-debian-10/
$ sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
$ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
$ sudo apt update
$ sudo apt -y install postgresql
- Find the
pg_hba.conf
file. - Change the access method for all "local" users for Unix domain socket connections.
- Change the method from peer to md5.
$ sudo nano /etc/postgresql/13/main/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
#
# Database administrative login by Unix domain socket
local all postgres peer
# "local" is for Unix domain socket connections only
#local all all peer
local all all md5
$ sudo -u postgres psql
postgres=# create database database_name;
postgres=# create user database_user_name with encrypted password 'database_user_password';
postgres=# grant all privileges on database database_name to database_user_name;
postgres=# \q
$ cd ~/flaskapp
$ source ~/flaskapp/venv/bin/activate
(venv) $ flask database create
https://www.digitalocean.com/community/tutorials/how-to-install-mariadb-on-debian-11
https://mariadb.com/kb/en/sql-statements/
$ sudo apt update
$ sudo apt -y install mariadb-server
$ sudo mysql_secure_installation
- Enter current password for root (enter for none): <enter>
- Switch to unix_socket authentication: Y
- Change the root password? N
- Remove anonymous uesrs? Y
- Disallow root login remotely? Y
- Remove test database and access to it? Y
- Reload privelege tables now? Y
$ sudo mysql -u root -p
> create database database_name;
> create user 'database_user_name'@'localhost' identified by 'database_user_password';
> grant all privileges on database_name.* to 'database_user_name'@'localhost';
> flush privileges;
> exit
First you'll have to install a MySQL connector for Python and then change the SQLAlchemy URI for the database in your config file.
$ pip install mysql-connector-python
URI for MySQL with the connector has the following format:
"mysql+mysqlconnector://{username}:{password}@{server}/databasename"
Next, if you're using Flask-Migrate, then you have to initialize the database and create the migrations folder:
$ flask db init
$ flask db migrate -m "Baseline"
$ flask db upgrade
Now create the Flask database tables.
$ cd ~/flaskapp
$ source ~/flaskapp/venv/bin/activate
(venv) $ flask database create
$ sudo cp ~/flaskapp/deployment/nginx/flaskapp /etc/nginx/sites-enabled/flaskapp
$ sudo cp ~/flaskapp/deployment/supervisor/flaskapp.conf /etc/supervisor/conf.d/flaskapp.conf
sudo chmod 600 ~/flaskapp/app/instance/.env
sudo chmod 700 ~/flaskapp/backup
sudo chmod 700 ~/flaskapp/deployment
sudo chmod 700 ~/flaskapp/logs
sudo chmod 700 ~/flaskapp/uploads
sudo chmod 700 ~/flaskapp/dnloads
https://deliciousbrains.com/ssl-certificate-authority-for-local-https-development/
Steps involved and what they produce:
- Generate a private key for the root certificate -> sdrCA.key
- Generate the root certificate using the private key -> sdrCA.pem
- Install the root certificate on Windows 10 -> sdrCA.pem added to Trusted Root Certification Authorities
- Generate a private key for the dev site certificate -> flaskapp.key
- Generate a certificate signing request for the dev site certificate -> flaskapp.csr
- Create an X509 V3 certificate extension config file to set the Subject Alternative Names (SAN) for the dev site certificate
- Generate the dev site certificate using the CSR, the CA private key, the CA certificate, and the config file -> flaskapp.crt
- Configure dev site web server to use private key and signed certificate
File summary:
- sdrCA.key : CA root certificate private key (requires passphrase)
- sdrCA.pem : Signed CA root certificate (installed on machines wanting access to your dev site over HTTPS)
- flaskapp.key : Dev site certificate private key
- flaskapp.csr : Dev site certificate signing request
- flaskapp.crt : Signed dev site certificate (installed on dev site HTTPS web server)
$ cd ~/flaskapp/deployment/certs
$ sudo openssl genrsa -des3 -out sdrCA.key 2048
Enter pass phrase for sdrCA.key:yourpassphrase
RESULTS IN: sdrCA.key
$ sudo openssl req -x509 -new -nodes -key sdrCA.key -sha256 -days 1825 -out sdrCA.pem
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
Locality Name (eg, city) []:San Diego
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Same Day Rules
Organizational Unit Name (eg, section) []:DevOps
Common Name (e.g. server FQDN or YOUR name) []:Same Day Rules IoT Root
Email Address []:support@samedayrules.com
RESULTS IN: sdrCA.pem
Open the Microsoft Management Console by using the Windows + R keyboard combination, typing mmc and clicking Open
- Go to File -> Add/Remove Snap-in
- Select Certificates and Add
- Select Computer Account and click Next
- Select Local Computer then click Finish
- Select OK to go back to the MMC window
- Double-click Certificates (local computer) to expand the view
- Select Trusted Root Certification Authorities, right-click on Certificates in the middle column under Object Type and select All Tasks then Import
- Select Next then Browse. Change the certificate extension dropdown next to the filename field to All Files (*.*) and locate the sdrCA.pem file, click Open, then Next
- Select Place all certificates in the following store > Trusted Root Certification Authorities (the default store)
- Select Next then click Finish to complete the wizard
Verify that the CA certificate is listed under Trusted Root Certification Authorities > Certificates.
$ sudo openssl genrsa -out flaskapp.key 2048
RESULTS IN: flaskapp.key
$ sudo openssl req -new -key flaskapp.key -out flaskapp.csr
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
Locality Name (eg, city) []:San Diego
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Same Day Rules
Organizational Unit Name (eg, section) []:DevOps
Common Name (e.g. server FQDN or YOUR name) []:Same Day Rules Flask App Cert
Email Address []:support@samedayrules.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:yourpassword
An optional company name []:Same Day Rules
RESULTS IN: flaskapp.csr
We’ll be running openssl x509
because the x509 command allows us to edit certificate trust settings, and allows us to set the Subject Alternative Names (SAN) for the dev site certificate.
$ sudo nano flaskapp.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = samedayrules.com
DNS.3 = *.samedayrules.com
IP.1 = 127.0.0.1
IP.2 = 192.168.1.250
RESULTS IN: flaskapp.ext
Using the CSR, the CA private key, the CA certificate, and the config file, generate the signed dev site certificate.
$ sudo openssl x509 -req -in flaskapp.csr -CA sdrCA.pem -CAkey sdrCA.key -CAcreateserial -out flaskapp.crt -days 825 -sha256 -extfile flaskapp.ext
RESULTS IN: flaskapp.crt
We can configure local web servers to use HTTPS with the private key and the signed certificate.
Edit the Nginx configuration file for your dev web site to use the new private key and certificate.
$ sudo nano /etc/nginx/sites-enabled/flaskapp
ssl_certificate /home/webapp/flaskapp/deployment/certs/flaskapp.crt;
ssl_certificate_key /home/webapp/flaskapp/deployment/certs/flaskapp.key;
sudo systemctl status nginx
sudo systemctl stop nginx
sudo systemctl start nginx
sudo systemctl reload nginx
sudo systemctl restart nginx
alias lal='ls -al --group-directories-first'
alias cls="clear"
alias ave='source ~/flaskapp/venv/bin/activate'
alias frn='flask run -h localhost -p 8000'
alias grn='gunicorn -b localhost:8000 -w 1 -t 120 app:app'
alias sv='sudo supervisorctl stop flaskapp'