Hosting Flask Apps on Nginx
Mbaoma
Posted on May 1, 2021
Hi there, in this article, we would be looking at how to host a Flask app on Nginx (a webserver) on an Ubuntu Virtual Machine.
A webserver is a computer that has web server software installed (Apache, Nginx, Microsoft IIS) and serves resources, which could be webpages or multimedia files, over the web, to fulfill client's requests over the internet.
Nginx is a webserver that can be used as reverse proxy, load balancer, mail proxy and HTTP Cache. It is widely used due to it's ability to scale websites better.
The first thing, we do is to provision an Ubuntu Virtual Machine (I use Microsoft Azure) and then login to it via SSH.
To follow along with this article, you are expected to have a flask application already built and in a git repository. If you don't, you could use this
We then run the following command to update our repositories:
sudo apt update
Dependig on the version of your Ubuntu VM, you might want to upgrade your Python version.
After this, we continue with the steps below:
- Step 1: We clone our app's GitHub repository into our VM:
sudo apt update
git clone <repo-url>
- Step 2: We change our directory's name to
app
ls
mv <repo-name>/ app
(The ls command is to list all the files and directories in our current work environment)
- Step 3: We cd into our directory, create a virtual environment and activate it
sudo apt-get install python3-venv
python3 -m venv <virtual-environment-name>
source <virtual-environment-name>/bin/activate
- Step 4: We install the requirements in our
requirements.txt
file
pip3 install -r requirements.txt
run
pip3 list
to see a list of all installed dependencies
If uWSGI does not install, run the following;
sudo apt-get install build-essential python3-dev
pip3 install uwsgi
So far, so good!
- Step 5: Now, we check if our app runs on uwsgi, but first we have to set our Uncomplicated Fire Wall (ufw) to allow both incoming and outgoing connections on port 9090, the port we would be making use of.
sudo ufw enable
sudo ufw allow 9090
Expected result:
Running
sudo ufw status
shows us the current state of our firewall; whether it is active or not and the ports our firewall gives us access to.
- Step 6: run the following
uwsgi dev.ini
- You might see the following in the output:
run this,
sudo apt-get install libpcre3 libpcre3-dev
pip3 install uwsgi -I --no-cache-dir
then re-run the command
uwsgi dev.ini
In your browser visit
<vmipaddress>:9090/
We expect to see our Flask app displayed via this port.
- Step 7: we delete the firewall rule and deactivate our virtual environment
sudo ufw delete allow 9090
deactivate
- Step 8: install nginx
sudo apt install Nginx
Now, we check the apps recognized by ufw and instruct it to allow for connection to Nginx:
sudo ufw app list
sudo ufw allow 'Nginx HTTP'
To confirm if Nginx was properly installed, we type our VM's IP address in our browser.
Omoshiroi...
- Step 9: we create systemd unit file to reboot the server running our app
sudo nano /etc/systemd/system/<custom-name-of-service-app>.service
Example:
sudo nano /etc/systemd/system/app.service
And type in the following contents in our file:
[Unit]
Description=A simple Flask uWSGI application
After=network.target
[Service]
User=<yourusername>
Group=www-data
WorkingDirectory=/home/<yourusername>/app
Environment="PATH=/home/<yourusername>/app/venv/bin"
ExecStart=/home/<yourusername>/app/venv/bin/uwsgi --ini <name-of-app-ini file>
[Install]
WantedBy=multi-user.target
- Step 10: we enable the service file we just created
sudo systemctl start <name-of-app>
sudo systemctl enable app <name-of-app>
To check if the file is running, type:
sudo systemctl status app
Also if a mistake is made in our service file and we correct it, we have to reload the daemon and restart systemctl
- Step 11: we configure nginx by creating a config file
sudo nano /etc/nginx/sites-available/<name-of-file>
And type in the following contents:
server {
listen 80;
server_name <your_ip_address> <your_domain_name>;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/<username>/app/app.sock;
}
}
*To check if there are any errors in our nginx configuration file, we run
sudo nginx -t
- Step 12: we link our config file to sites-enabled directory (Nginx server blocks configuration files are stored in /etc/nginx/sites-available directory, which are enabled through symbolic links to the /etc/nginx/sites-enabled/ directory):
sudo ln -s /<path-to-config-file>/<config-file-name> /etc/nginx/sites-enabled
Example:
sudo ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/
Running a syntax check at this point, comes in handy
- Step 13: we restart nginx for our changes to take effect
sudo systemctl restart nginx
In our browser, we type in our VM's IP address without adding a port becase in our nginx config file, we have defined a port for nginx to listen on
Feel free to share your IP address with friends to check out your app
Thank you for your time!!!
Find below the GitHub repo for this task:
Github repo
Feel free to connect with me via Linkedin
Gokigen'yō
Posted on May 1, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.