Introduction
Welcome to this guide on how to install and deploy your very own Flask web application. For this example I will be using Ubuntu Server and Python 3.12. This has been tested on Python 3.12, it might work on older versions too.
Prerequisites
- A domain - to host your backend on
- A server with Ubuntu - to run/host your backend
- Some basic knowledge of Linux commands
Example terminology
- Domain:
<example.com>
Step 1 - Set up your domain
We first have to point our DNS records to our server, this is because we want to have the Flask backend hosted on our domain.
Go to your DNS provider and create a new A record like this:
Type | Name | Value |
---|---|---|
A | example.com | YourServerIP |
Save the new record and wait 24 hours for the DNS to propagate.
Now that your domain is good to go, we can move on with the tutorial.
Step 2 - Install Python (if needed)
To start, we first need to install Python if this is not already done. Usually Python is pre-installed on Ubuntu. You can check this by running these commands:
python3 --version
python3 -m venv --help
python3 -m ensurepip --version # In python3.12-venv
dpkg -s build-essential
dpkg -s python3-dev
If you see output containing a version with 3.12.x
, venv (virtual environments) works, and the other packages are also installed, it means you are good to go and you can now move on to step 4.
If you do not see any output you can install Python by following these commands:
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.12
sudo apt install python3.12-venv
sudo apt install build-essential python3-dev
The commands above will add the Python repository, update your package list, and install Python from the repository.
Step 3 - Create and set up the working directory
Then we are going to create a directory and a virtual environment. In this case we will use /home/YourUser/flaskbackend
.
mkdir ~/flaskbackend # Create a directory in /home/YourUser
cd ~/flaskbackend # Move into the created directory
python3 -m venv venv # Create a Python virtual environment. Doing this without a venv can kill your system.
source venv/bin/activate # Activate the virtual environment
Now you should see (venv)
before your name. This means that your venv (virtual environment) is sucessfully activated. We can now move on with installing the required Python packages.
Install Flask and uWSKI for Python. uWSGI is the WSGI server we will use to deploy the backend.
pip install flask
pip install uWSGI
Now we are going to create the application/Python file. For this you can use your favorite text editor. For this tutorial we are going to use Nano.
-
Create
app.py
and open a text editornano app.py
-
Paste your Flask code in there
If you don't already have a Flask Python script, you can create one or use the example script below. For this tutorial, we will use a basic script that returns "Hello, World!" and "Hi". This is the code we will use and deploy:
# Import the modules from flask import Flask # Setting the app variable app = Flask(__name__) # Creating our "homepage" @app.route("/") def hello_world(): return "Hello, World!" # Creating our hello-world route @app.route("/some-route") def say_hi(): return "Hi" # Setting the run command if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)
Step 4 - Testing the Flask application
Now we are going to test if the script works. For the example above, run this command to start your backend in development mode:
python3 app.py
This should return:
* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://YourServerIP:5000
Press CTRL+C to quit
Restarting with stat
* Debugger is active!
* Debugger PIN: 351-930-704
Now you can go to http://YourServerIP:5000
and see if your web application is there. If it is, we can move on.
Step 5 - Test if uWSGI works
-
Create
uwsgi.py
and open a text editor. Creatingwsgi.py
will tell uWSGI what to do.nano wsgi.py
-
Paste this code in there:
from app import app if __name__ == "__main__": app.run()
Now we are going to test if uWSGI can actually serve the application.
Replace
YourPort
with the port you want to have it on
uwsgi --socket 0.0.0.0:YourPort --protocol=http --processes=2 -w wsgi:app
Now (again) go to http://YourServerIP:YourPort
See if you can see the standard backend page. If you can, we can move on.
Type and enter deactivate
— this will make you exit the venv.
Step 6 - Set up a systemctl service for our Flask backend
-
Create the service file
A service file tells your system what your application is and what it needs to do.
sudo nano /etc/systemd/system/flaskbackend.service
-
Paste this in the service file:
In the content below change:
YourUser
➔ to your usernameNumberOfProcesses
➔ to the number of processes you want to have
[Unit] Description=A uWSGI instance to serve the Flask backend After=network.target [Service] User=YourUser Group=www-data WorkingDirectory=/home/YourUser/flaskbackend Environment="PATH=/home/YourUser/flaskbackend/venv/bin" ExecStart=/home/YourUser/flaskbackend/venv/bin/uwsgi --socket /home/YourUser/flaskbackend/flaskbackend.sock --module wsgi:app --master --processes NumberOfProcesses --chmod-socket=660 --vacuum --py-autoreload 1 [Install] WantedBy=multi-user.target
-
Start the service
sudo systemctl daemon-reload # Reload the service files sudo systemctl start flaskbackend # Start your backend sudo systemctl enable flaskbackend # Tell your system to start the Flask backend at boot
-
Check the status of your running backend
sudo systemctl status flaskbackend
The output should look like this:
● flaskbackend.service - A uWSGI instance to serve the Flask backend Loaded: loaded (/etc/systemd/system/flaskbackend.service; enabled; preset: enabled) Active: active (running) since Sat 2024-11-23 20:32:32 CET; 2 weeks 1 day ago Main PID: 1547894 (uwsgi) Tasks: 82 (limit: 38366) Memory: 307.1M (peak: 1.1G) CPU: 2d 2h 7min 35.756s CGroup: /system.slice/flaskbackend.service ├─1547894 /home/YourUser/flaskbackend/venv/bin/uwsgi --socket /home/YourUser/flaskbackend/flaskbackend.sock --module wsgi:app --master --processes numberofprocesses --chmod-socket=660 --vacuum --py-autoreload 1 ├─1548580 /home/YourUser/flaskbackend/venv/bin/uwsgi --socket /home/YourUser/flaskbackend/flaskbackend.sock --module wsgi:app --master --processes numberofprocesses --chmod-socket=660 --vacuum --py-autoreload 1
Step 7 - Set up Nginx
Now this is running, we are going to setup a Nginx proxy.
-
Update your packages and install Nginx:
sudo apt update # Update your package list sudo apt install nginx # Install Nginx sudo systemctl start nginx # Start Nginx sudo systemctl enable nginx # Start Nginx at boot sudo unlink /etc/nginx/sites-enabled/default # Remove the standard Nginx site
-
Change the Nginx configuration to avoid permission issues.
sudo nano /etc/nginx/nginx.conf
Change
user www-data;
touser YourUser;
(you need to replace YourUser with your actual user) -
Create the Nginx configuration file
sudo nano /etc/nginx/sites-available/flaskbackend # Create the Nginx configuration file
-
Paste the following configuration:
Replace
example.com
andYourUser
with your actual domain and username.server { listen 80; server_name example.com www.example.com; location / { include uwsgi_params; uwsgi_pass unix:/home/YourUser/flaskbackend/flaskbackend.sock; } }
-
Create a symbolic link to
/etc/nginx/sites-enabled
(where the enabled sites are located)If you update the file in
/etc/nginx/sites-enabled
, the changes will be automatically reflected in/etc/nginx/sites-available
.sudo ln -s /etc/nginx/sites-available/flaskbackend /etc/nginx/sites-enabled sudo nginx -t
With the last command, you should get:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
-
Restart Nginx
sudo systemctl restart nginx # Restart Nginx
Now go to your domain, e.g. http://example.com
, and you should see your web application
Step 8 - Set up a SSL certificate using Certbot
Now that this is all set up we are going to secure the web application with a SSL certificate using Certbot
sudo apt update # Update your list of packages
sudo apt install python3-certbot-nginx # Install Certbot for Nginx
sudo certbot --nginx -d example.com -d www.example.com
The last command will change example.com
to example.com
. This will request an SSL certificate for www.example.com
and example.com
. Answer the questions and you should have installed your certificate
Now you can go to https://example.com
and see your Flask web application.
Conclusion
That's it! You have now done the following things:
- Installed Python on your Ubuntu system
- Installed uWSGI and Flask in your venv
- Created a Nginx reverse proxy
- Set up a working SSL certificate
I hope this guide has helped you. Thanks for following along!