Concept

WSGI

The Web Server Gateway Interface (WSGI) is a specification for simple and universal interface between web servers and web applications or frameworks for the Python programming language.

WSGI是一種通用的接口標準或者接口協議. 實現了python web process 與 server 之間的互通. 有了這個標準,一些python web framework 就可以輕鬆地部署在不同的Web服務器上了.

uWSGI

The uWSGI project aims at developing a full stack for building hosting services.

一種python Web server or server/gateway, uWSGI是實現了uwsgi和WSGI兩種協議的Web服務器,負責響應python的web請求. 為什麼有了uWSGI為什麼還需要nginx? 因為nginx具備優秀的靜態內容處理能力,然後將動態內容轉發給uWSGI服務器,這樣可以達到很好的客戶端響應.

所以總而言之,所有的流量會先進入 Nginx. 其中如果是靜態需求,像是圖片 HTML 檔案等等,就由 Nginx 處理,如果是動態需求,例如 Python、PHP 等等,就轉發給 uWSGI 處理,uWSGI 處理完之後會再轉發回 Nginx。

Install the Python Components and Nginx

$ sudo apt-get update
$ sudo apt-get install python-pip python-dev nginx
$ sudo pip install virtualenv

Create a Python Virtual Environment

$ mkdir ~/myproject
$ cd ~/myproject
$ virtualenv myprojectenv
$ source myprojectenv/bin/activate
# Then it will look something like this (myprojectenv)[email protected]:~/myproject$

獨力的Python 環境的工具,只是虛擬(獨立)標的不同。Virtualenv 可以隔離函數庫需求不同的專案,讓它們不會互相影響。在建立並啟動虛擬環境後,透過 pip 安裝的套件會被放在虛擬環境中,專案就可以擁有一個獨立的環境。

Set Up a Flask Application

# under ur project folder 
$ pip install uwsgi flask
# create the Flask app
$ vim ~/myproject/myproject.py

myproject.py

from flask import Flask
application = Flask(__name__)

@application.route("/")
def hello():
    return "<h1 style='color:blue'>Hello World!</h1>"

if __name__ == "__main__":
    application.run(host='0.0.0.0')

You can test your Flask app by typing:

python myproject.py

And Type server's domain name or IP address:5000 in your web browser. You will see the result.

Create the WSGI Entry Point

$ vim ~/myproject/wsgi.py
from myproject import application

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

After that, we need to test uWSGI Serving

$ uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi

And Type server's domain name or IP address:8000 in your web browser. You will see the result.

press CTRL-C to stop process and now we need it deactivate it.

$ deactivate

Creating a uWSGI Configuration File

$ vim ~/myproject/myproject.ini

myproject.ini

[uwsgi]
module = wsgi

master = true
processes = 4

socket = myproject.sock
chmod-socket = 660
vacuum = true

die-on-term = true

Create an Upstart Script

Creating an Upstart script will allow Ubuntu's init system to automatically start uWSGI and serve our Flask application whenever the server boots.

$ sudo vim /etc/init/myproject.conf

myproject.conf

description "uWSGI server instance configured to serve myproject"

start on runlevel [2345]
stop on runlevel [!2345]

setuid user
setgid www-data

env PATH=/home/user/myproject/myprojectenv/bin
chdir /home/user/myproject
exec uwsgi --ini myproject.ini

You can start the process immediately by typing:

sudo start myproject

Configuring Nginx to Proxy Requests

First you should remove default in sites-available and sites-enabled directory. Then add myproject in both directory.

$ sudo vim /etc/nginx/sites-available/myproject

myproject

server {
    listen 80;
    server_name server_domain_or_IP;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/user/myproject/myproject.sock;
    }
}

link the file to the sites-enabled directory

sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
# Test for syntax errors
sudo nginx -t
# If no error, restart nginx
sudo service nginx restart

And Type server's domain name or IP address in your web browser. You will see the result.

Other

If you create an ubuntu instance on AWS, you should add some inbound rules in your security group. After that you can run these process correctly.

Reference