Paul Baumgarten

Computer Scientist, teacher, freelance programmer and self confessed geek

Deploy Flask to Nginx webserver

Throughout this guide, where you see mycoolproject, replace it with a short alpha-numeric code that represents your project.

These instructions have been written for a Debian system in 2021. Other distributions may require alterations.

1. Install

From the terminal,

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install -y python3-pip python-dev nginx

2. Create a dedicated project folder

From the terminal,

mkdir ~/mycoolproject
cd ~/mycoolproject

3. Copy your project files into that folder

4. Register your domain name to point to your server

5. Setup NGINX

Create file /etc/nginx/sites-available/mycoolproject

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name mycoolproject.com;
    location / {
        include uwsgi_params;
        uwsgi_pass unix:/tmp/mycoolproject.sock;
        access_log on;
        error_log on;
    }
}

6. Create uwsgi ini file

Create file ~/mycoolproject/mycoolproject.ini

Ensure the reference to the .sock file here matches the one in your nginx conf in the previous step.

[uwsgi]
module = app:app
master = true
processes = 5
socket = /tmp/mycoolproject.sock
chmod-socket = 666
vacuum = true
die-on-term = true

7. Create app.py

The app.py file will be called by the uwsgi manager. It will import your main project and start Flask. By starting this method it means the...

if __name__=="__main__":

... section of your mycoolproject.py file is ignored, so make sure it doesn't do anything other than launch Flask.

Your ~/mycoolproject/app.py file should resemble...

# Use whatever the name of your project main python file is for the import
from mycoolproject import app
if __name__ == "__main__":
   app.run()

The above assumes that within mycoolproject.py you are using app = Flask(), otherwise replace app with whatever you call your Flask object variable.

8. Create the virtual environment

From the terminal,

cd ~/mycoolproject
python3 -m venv venv
source venv/bin/activate
pip install uwsgi flask
pip install -r requirements.txt
deactivate

9. Change file permissions

Replace my username with yours (obviously... I hope)

cd ~/mycoolproject
chown pbaumgarten.pbaumgarten -R .

9b. Test the uwsgi install

Optional. You should now be able to test the uwsgi install

cd ~/mycoolproject
source /venv/bin/activate
uwsgi --socket 0.0.0.0:8080 --protocol=http -w app:app
deactivate

You probably won't be able to access it without nginx and let's encrypt setup but you will be able to check there are no start up errors. Use Ctrl C to quit.

10. Create the system service

This will enable the project to auto-start when the system reboots.

Create /etc/systemd/system/mycoolproject.service

Ensure the user and folder names are also correct.

You can add whatever secrets you wish to pass via environment variables here. See the example below.

These would be available in Python via os.environ["SECRET"].

[Unit]
Description=mycoolproject
After=network.target

[Service]
User=pbaumgarten
WorkingDirectory=/home/pbaumgarten/mycoolproject
Environment="PATH=/home/pbaumgarten/mycoolproject/venv/bin"
ExecStart=/home/pbaumgarten/mycoolproject/venv/bin/uwsgi --ini mycoolproject.ini
Environment="SECRET=90wer809wr832ourlkwsdfs"

[Install]
WantedBy=multi-user.target

Enable the service. From the terminal,

sudo systemctl enable mycoolproject
sudo systemctl start mycoolproject
sudo systemctl status mycoolproject

11. Nginx link the available site to the enabled sites

From the terminal,

ln -s /etc/nginx/sites-available/mycoolproject /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx

The nginx -t checks the config file.

12. Let's encrypt

If you don't have certbot installed you will need to follow the instructions here

  • https://certbot.eff.org/lets-encrypt/debianbuster-nginx

From the terminal,

certbot --nginx -d mycoolproject.com