×
Community Blog Serving Flask Applications with uSWGI on Ubuntu

Serving Flask Applications with uSWGI on Ubuntu

In this tutorial we'll build a sample Python application using Flask and deploy the application using uWSGI and Nginx.

By Kunal Relan, Alibaba Cloud MVP

Introduction

In this tutorial, we'll build a sample Python application using Flask and deploy the application using uWSGI and Nginx. Flask is a popular micro framework widely used in web development using Python. It is called a microframework as it doesn't required any other tools or library to create a web application, and all other resources needed in the process are imported as third party libraries including database abstraction layer.

To start with the basics, we'll create a hello world application using Flask. We'll use uWSGI application server and Nginx to act as front end reverse proxy server.

To learn more detailed operations with your Flask installation, such as updating Python with Pyenv and daemonizing the log process, check out this tutorial.

Prerequisites

To complete this tutorial, you will need:

  • Alibaba Cloud Elastic Compute Service (ECS) Ubuntu server with a non-root user with sudo privileges.
  • Basic working knowledge of Nginx and uWSGI.

Step 1 - Setting Up Required Components and Tools

In the first step we'll install all the dependencies needed to setup the application from Ubuntu repositories and we'll start with installing python-pip which is a package manager for Python, python-dev which contains the header files needed to compile python extensions and Nginx which will work as a front end reverse proxy server for us.

bash
sudo apt-get update
sudo apt-get install python-pip python-dev nginx

After this step completes, we should have pip, python-dev tools and nginx installed in the system. Now lets setup a python virtual environment to create our flask application. Python virtual environments are useful to have a self-contained directory tree that contains a specific version of python and required components ensuring that we don't install them globally as other apps in the same system might need another version of the same library.

So new we'll install virtualenv package using pip to be able to create a virtual environment.

bash
sudo pip install virtualenv

Now we shall have virtualenv package installed in our system.

After this we can go ahead and create the project directory and activate our virtual environment.

bash
mkdir ~/samepleapp
cd ~/sampleapp

Next we'll create a virtual environment to store our python modules using the following command.

bash
user@instance:~/samepleapp $ virtualenv venv

This command will install a local copy of python and pip in a directory called venv within sampleapp directory which we just created.

Before we install any more components in our virtual environment we need to activate the environment so that pip install the components in our virtual environment. To do so enter the following command.

bash
user@instance:~/samepleapp $ source venv/bin/activate

After this command is successfully executed, your terminal prompt will indicate that you are now inside the virtual environment and it will look something like (venv)user@host:~/sampleapp.

Step 2 - Creating a Sample Flask Application

Now that we have our virtual environment activated, lets install Flask and uWSGI and get started on creating our Hello World Application.

Use the local version of pip in your virtual instance to install Flask and uWSGI using the following command.

bash
(venv) user@instance:~/samepleapp $ pip install flask uwsgi

After install Flask and uWSGI we can start creating our Flask Application, for the sake of this tutorial we'll just create one route which will return Hello World in the response and thus we'll just create a single file called app.py.

We'll keep our sample application in this file, now add the following code to import Flask and initiate the Flask Object to create an instance of Flask.

bash
(venv) user@instance:~/samepleapp $ nano app.py

Now edit the following code using the nano code editor, save the file and exit.

bash
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "It Works!"

if __name__ == "__main__":
    app.run(host='0.0.0.0',port=3000)

The above code basiically, imports the local Flask library and initiates an object called app and then defines the root route which will execute the function when the root domain is accessed and in our case it'll return Hello World and then we run the app Object on all the network adapters of the instance using 0.0.0.0 address.

reStructuredText
Note: Make sure your port 3000 is open over the Internet.

Now, if everything went well you can start the Python server using the following command and then access the web server on PORT 3000 using your browser or terminal.

bash
(venv) user@instance:~/samepleapp $ python app.py

The above command should start the Python server and you can now access the application by visiting http://YOUR_IP:3000 in your browser or terminal.

After you have tested the same, exit the Python server by pressing Ctrl+C .

Next we'll create wsgi.py that will serve as the entry point to our application which directs the uWSGI server on how to interact with the python application.

Step 3 - Configuring uWSGI

So now that we have our application ready to be deployed, we'll move on to uWSGI and configure uWSGI to serve our application. To start with we'll check if uWSGI is able to start our application using the command line.

Now edit the following code in wsgi.py file in your app directory, save and exit.

python
from app import app

if __name__ == "__main__":
    app.run()

The above code imports the app object from our app.py and runs the application, wsgi.py will serve as entry point to our application.

Now lets test if our entry point starts the application, enter the following code in your terminal.

bash
(venv) user@instance:~/samepleapp $ uwsgi --socket 0.0.0.0:3000 --protocol=http -w wsgi:app

This command will try to call app object in wsgi.py and run the application.

Now visit the server's IP on port 5000 and you should be able to see the same output and once it's working properly you can exit the application by pressing CTRL+C.

Once we have tested that uWSGI is working for us, we'll start with creating a WSGI configuration file and provide it the options we need.

Create another file in the same directory and name it sampleflask.ini and edit the file to put the following configurations to run our application.

ini
[uwsgi]
#python module to import
module = wsgi:app
#enable the master process
master = true
#spawn number of workers
processes = 5
#socket file's location
socket = sampleflask.sock
#permissions for the socket file
chmod-socket = 660

When finished, save and exit the file.

Step 4 - Creating systemd unit file

Once we have the configuration file, next we need to create a systemd unit file which will make ubuntu's init system to start our application everytime the server boots.

Now we need to create sampleflask.service file inside /etc/systemd/system where all the ubuntu init files exist.

Edit the following code in the sampleflask.service file

ini
#Metadata and dependencies section
[Unit]
Description=Sampleflask service
After=network.target
#Define users and app working directory
[Service]
User=<your_user>
Group=www-data
WorkingDirectory=/home/<your_user>/sampleflask
Environment="PATH=/home/<your_user>/sampleflask/venv/bin"
ExecStart=/home/<your_user>/sampleflask/venv/bin/uwsgi --ini sampleflask.ini
#Link the service to start on multi-user system up
[Install]
WantedBy=multi-user.target

Next, save the file and exit.

After this, we can now start our uWSGI service we just created using systemctl command, let's enable our service to start at boot using the following command:

bash
(venv) user@instance:~/samepleapp $ sudo systemctl start sampleflask
(venv) user@instance:~/samepleapp $ sudo systemctl enable sampleflask

Step 5 - Configuring Nginx to Proxy requests

Our uWSGI service should now be up and running on port 3000, next we need to configure Nginx to proxy the requests on port 80. To do so we'll need to configure Nginx to pass the web requests to the socket using uwsgi protocol. Nginx comes with native support for passing uwsgi protocol traffic and works out of the box with uwsgi.

Let's begin by adding a new server block in a new file called sampleflask and put the following code in it.

nginx
server {
    # the port your site will be served on
    listen 80;
    # the IP Address your site will be served on
    server_name <your_ip>;
    # Proxy connections to application server
    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/<your_user>/sampleflask/sampleflask.sock;
    }
}

So that's all we need to pass Nginx requests to our uWSGI server, next we need to enable the newly created server block using the following command.

bash
(venv) user@instance:~/samepleapp $ sudo ln -s /etc/nginx/sites-available/sampleflask /etc/nginx/sites-enabled

The above command links our newly created server file to the enabled websites directory, now lets test if everything went well with our latest change using Nginx Test Configuration.

bash
(venv) user@instance:~/samepleapp $ sudo ngnix -t

If everything went well, you should see the following output ini your terminal.

bash
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

After this, we are all set to get everything to work and as the last step we need to restart our Nginx server in order for it to load our new changes.

bash
(venv) user@instance:~/samepleapp $ sudo systemctl restart nginx

Now if you open the browser with your IP on port 80, you should be able to see the response from our flask server.

Conclusion

In this tutorial, we created a simple flask application which runs on uWSGI and is reverse proxied through Nginx, Flask is a simple yet powerful micro framework which can enable you to create complex web application and services. uWSGI and Nginx are again powerful tools which enables you to deploy and manage your Flask application for your users as they grow.

0 0 0
Share on

Alibaba Clouder

2,605 posts | 747 followers

You may also like

Comments