The original

After exploring DRF (two: Djangos REST Framework Quickstart project interpretation – Simplified and Djangos REST Framework implements business APIS and automatically documents – simplified), it is time to live on a formal service, But also for the better implementation of some ideas later.

Preparing the server

At the beginning of the thought of ali cloud host, before also used for a period of time, but to tell the truth, the price is a little expensive. Because now I just realize some small ideas of my own, I choose foreign VPS with slightly higher cost performance. According to everyone’s recommendation, I chose the 5 knife version of Vultr, which is enough to use and supports Alipay payment, so it is particularly convenient.

However, there are still some problems in this process. For example, the IP address of the node may be blocked. The solution is to constantly try to switch instances. However, this wall method is more violent, using TCP truncation, you will find that you can ping through, but you cannot establish a TCP connection.

After the VPS startup is ok, create a new user and add sshkey to the new user to facilitate future SSH connections. The domain name can then be bound. Another advantage of using VPS is that no registration is required.

Install nginx

Direct installation can be, I see the version is not low.

apt-get install nginx
Copy the code

Main configuration file: /etc/nginx/nginx.conf

Start nginx service:

sudo service nginx start
Copy the code

By default, you can use the domain name to test whether access to nginx is enabled properly.

Install python3+ Virtualenv

Since I chose ubuntu18.04, python3.6 seems to be pre-installed by default, so I can skip this.

Install virtualenv:

sudo apt-get install python3-pip
pip3 install virtualenv
Copy the code

Higher versions of Ubuntu may install Virtualenv under $HOME/.local/bin/, so you need to add a PATH to your PATH.

Set up a virtual environment to run Django and install Django, etc

virtualenv -p /usr/bin/python3 env3
pip install djangorestframework django pymysql coreapi pygments markdown
git clone https://github.com/roubo/rouboApi.git
Copy the code

Mysql installation

sudo apt-get install mysql-server
Check the default username and password
sudo cat /etc/mysql/debian.cnf 
# # login
mysql -u xxxx -p yyyy
Copy the code

Change password:

mysql> use mysql; Database changed mysql> update user set plugin='mysql_native_password' where user='root'; Query OK, 1 row affected (0.00 SEC) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update user set authentication_string=password('xxx') where user='root'; Query OK, 1 row affected, 1 warning (0.00 SEC) Rows matched: 1 Changed: 1 Warnings: 1 mysql> flush PRIVILEGES; Query OK, 0 rows affected (0.01sec)Copy the code

Establish business related databases

create database rouboinfo default charset utf8 collate utf8_general_ci;
Copy the code

Djangos project database initialization

python manage.py makemigrations
python manage.py migrate
Copy the code

Test django-side services

Start the Django debug service

python manage.py runserver
Copy the code

Test interface, local access ok (Django service itself does not need to provide access to the Internet, and is eventually distributed via Nginx)

➜ ~ curl - I'http://127.0.0.1:8000/rouboapi/v1/report/'
HTTP/1.1 400 Bad Request
Date: Thu, 06 Sep 2018 03:42:23 GMT
Server: WSGIServer/0.2 CPython/3.6.5
Content-Type: application/json
Vary: Accept
Allow: GET, HEAD, OPTIONS
X-Frame-Options: SAMEORIGIN
Content-Length: 124

{"report_type": ["This field is required."]."device_id": ["This field is required."]."ip_address": ["This field is required."]} %Copy the code

Bridge nginx to Django

Now that both Nginx and Django services are available, the next step is to get through them, as we mentioned earlier with uWSGI. Here’s a look at the WSGI protocol.

WSGI agreement

WSGI (Web Server GateWay Interface) is a set of protocols used to connect the Web Server to the Web Application. Its emergence is also the need for the decoupling of Web server and application. For example, if we want to implement two apis, we can choose two Web application frameworks, such as Django and Flask, each API using one framework, and the client will feel nothing at all. The WSGI protocol acts as a bridge here, enabling multiple servers to single applications, or when servers to multiple applications.

UWSGI application

UWSGI is an application that can play two roles:

  • In the Nginx + uWSGI + Django scenario, it is middleware.
  • In the uWSGI + Django scenario, it is a Web Server.

When it is a middleware role, it needs to use its UWSGi protocol, and Nginx connects to UWSGi through this protocol. The role of the UWSGI protocol here can be simply understood as how to efficiently pass request and Response. The role of uWSGI middleware can also be simply understood as a gateway shielding the differences of protocols and development languages among Web applications, and effectively managing all kinds of concurrency, load balancing and logging.

Why Nginx + uWSGI + Django? It’s a reason to make the most of it. Nginx has the following advantages:

1. Security: The client must pass the reverse proxy server to access the Web server. This protects the Web server from direct attacks by external programs. 2. Load balancing: The reverse proxy server can dynamically transfer HTTP requests to different Web servers for processing according to the load of Web servers, provided that there are multiple Web servers. 3. Improve I/O performance of the Web server. An HTTP request takes N seconds to transmit from the client to the server. If the request is sent directly to the Web server, the Web server must block a process for N seconds to receive the I/O, which degrades the performance of the Web server. If a reverse proxy server is used, the performance of the Web server can be improved by enabling the reverse proxy server to receive the entire HTTP request and then sending the request to the Web server. There are also static file requests that can be handed over directly to a reverse proxy, without going through the Web server.

Install and configure uWSGI and Nginx

Note that I’m still installing the application in a virtual environment.

First install globally dependent packages in a non-virtual environment:

Sudo apt-get install python3.6-dev build-essentialCopy the code

Install uWSGI in a virtual environment

pip install uwsgi
Copy the code

Test uWSGI + Django to see if it works, run it in the project path and test port 8080 to see if it works:

uwsgi --http :8080 --module rouboinfo.wsgi
Copy the code

If all this works, you can start configuring Nginx to connect to uWSGI.

Add nginx configuration to rouboapi.conf:

# the upstream component nginx needs to connect to
upstream django {
    server unix:///data/django/rouboApi/rouboapi.scok; # for a file socket
    # server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
    # the port your site will be served on
    listen      80;
    # the domain name it will serve for
    server_name app.airoubo.com; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste

    # Django media
    #location /media {
    # alias /path/to/your/mysite/media; # your Django project's media files - amend as required
    #}

    #location /static {
    # alias /path/to/your/mysite/static; # your Django project's static files - amend as required
    #}

    # Finally, send all non-media requests to the Django server.
    location /roubo {
        uwsgi_pass  django;
        include     /etc/nginx/uwsgi_params; # the uwsgi_params file you installed}}Copy the code

Running uWSGI with configuration files:

# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /data/django/rouboApi
# Django's wsgi file
module          = rouboinfo.wsgi
# the virtualenv (full path)
home            = /data/django/env3

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = /data/django/rouboApi/rouboapi.scok
#... with appropriate permissions - may be needed
chmod-socket    = Awesome!
# clear environment on exit
vacuum          = true
Copy the code
Execute in virtual environment
uwsgi --ini rouboapi.ini
Copy the code

At this point, we see that the interface access is fine, and the Nginx <-> uWSGI <-> Django path is fine. But let’s take a look at the Django REST Framework documentation page:

Found that all styles are missing. This is because our nginx configuration does not expose static files to clients:

    #location /static {
    # alias /path/to/your/mysite/static; # your Django project's static files - amend as required
    #}

Copy the code

Django static file collection and Nginx static file configuration

Nginx error log:

2018/09/06 07:41:27 [error] 14754#14754: *23 open() "/usr/share/nginx/html/static/rest_framework/js/default.js" failed (2: No such file or directory), client: 116.231.148.176, server: app.airoubo.com, request: "GET /static/rest_framework/js/default.js HTTP/1.1", host: "app.airoubo.com", referrer: "http://app.airoubo.com/roubo/rouboapi/v1/report/"
Copy the code

The REST js file is 404.

Collect Django static files to the specified directory

Add the collection path to settings. py:

STATIC_ROOT = os.path.join(BASE_DIR, "static/")
Copy the code

Implemented under the project:

python manage.py collectstatic
Copy the code

After executing, you can see the static folder in the project directory:

static
|-- admin
|   |-- css
|   |-- fonts
|   |-- img
|   `-- js
`-- rest_framework
    |-- css
    |-- docs
    |-- fonts
    |-- img
    `-- js
Copy the code

Nginx configuration file static:

location /static {
        alias /data/django/rouboApi/static; 
}
Copy the code

Restart nginx and check the effect.

complete

With back-end deployment complete, you can happily add new interfaces and services.