I knew that uWSGI would be used to deploy a Python-implemented application to a production environment, but I didn't know why or how to use it. So, let's run it on Raspberry Pi 3 Model B + using Nginx, uWSGI, Python + Flask.
In the first place, WSGI is an abbreviation for Web Server Gateway Interface. As described in Abstruct of PEP 3333, it is an interface that connects a web server and a Python application, and enhances the portability of the web application between various web servers.
This document specifies a proposed standard interface between web servers and Python web applications or frameworks, to promote web application portability across a variety of web servers.
Deploy the application created by Python + Flask using uWSGI of WSGI application container that conforms to this WSGI.
The order of implementation is as follows.
First, the directory of the development environment is as follows.
$ tree
.
├── README.md
├── conf
│ └── uwsgi.ini
├── requirements.txt
└── src
└── main.py
The required libraries are listed in requirements.txt. You can use it to install the library with pip install -r requirements.txt
.
$ cat requirements.txt
flask
isort
flake8
ipython
uwsgi
src / main.py is:
$ cat src/main.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!'
if __name__ == '__main__':
app.run()
You can see that the development server is started on port 5000 with python src / main.py
and the application is actually running.
When actually operating the application, it is necessary to make various settings. For example, the output destination of the socket, the number of processes, the number of threads, and the like can be mentioned. Since it is troublesome to specify these settings in combination with the uwsgi command options, the options are summarized in the following uwsgi.ini file.
Then you can check if the application is actually running with ʻuwsgi --ini uwsgi.ini`.
$ cat conf/uwsgi.ini
[uwsgi]
wsgi-file = ../src/main.py
; module = main
callable = app
chmod-socket = 666
socket = /tmp/%n.sock
;http = 0.0.0.0:8080
;daemonize = /var/log/uwsgi/flask/%n.log
;pidfile = /tmp/app.pid
;harakiri = 600
After accessing Nginx port 80 with an HTTP request, proxy to uWSGI using UNIX domain socket. The settings on the Nginx side are as follows.
server {
listen 80;
#Reverse proxy to Flask app when accessing port 80
#This way you don't waste ports
location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/uwsgi.sock;
}
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_http_version 1.1;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
send_timeout 600;
uwsgi_read_timeout 600;
}
By the way, a UNIX domain socket is a socket for interprocess communication running on the same machine. Therefore, it cannot communicate with other machines. On the other hand, a socket that communicates with other machines via a network by relying on IP and port number is called an INET domain socket. UNIX domain sockets can only communicate with processes on the same machine, but they are faster than INET domain sockets.
There are several ways to daemonize uWSGI. The first is to add the daemonize
option to the uwsgi command options. The second method is to register uWSGI in systemctl and make it start automatically. The second one was adopted in this implementation.
--Creating a service (/etc/systemd/system/app.service)
[Unit]
Description=uWSGI instance to serve myapp
After=network.target
[Service]
;User==www-data
Group=www-data
WorkingDirectory=/home/pi/WorkSpace/DeployFlask/conf
ExecStart=/home/pi/.pyenv/shims/uwsgi --ini /home/pi/WorkSpace/DeployFlask/conf/uwsgi.ini
[Install]
WantedBy=multi-user.target
--Starting the service
$ sudo systemctl start app
--Service auto-start settings
$ sudo systemctl enable app
--Understanding the service status
$ sudo systemctl status app
● app.service - uWSGI instance to serve myapp
Loaded: loaded (/etc/systemd/system/app.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2020-05-12 18:22:25 JST; 7min ago
Main PID: 2615 (uwsgi)
Tasks: 1 (limit: 2200)
Memory: 10.9M
CGroup: /system.slice/app.service
└─2615 /home/pi/.pyenv/versions/DeployFlask/bin/uwsgi --ini /home/pi/WorkSpace/DeployFlask/conf/uwsgi.ini
--Since daemonize = /var/log/uwsgi/flask/%n.log was described in the uwsgi.ini file, the server itself returned 502 after a certain period of time. It was the first method I took to make uwsgi a daemon, but I deleted it because the description was bad.
Deploy
-Introduction to uWSGI -Note that I got a timeout error many times after starting uWSGI from systemd
-I can't sleep without checking! The story of the socket that I couldn't sleep anymore
Recommended Posts