If you do a search for UWSGi + Flask on Google or Baidu or some of the tech communities, you’ll find plenty of articles on how to build a website using UWSGi + Flask + Nginx. As shown below:
Strange situation
And these articles, all seem to be conventions, must start uWSGi with the command line, test whether UWSGi and Flask run properly, and then write the uWSGi configuration file. Then use Unix sockets to communicate between UWSGI and Nginx. So the uWSGi configuration file must be written like this:
socket = /xxx/yyy/zzz.sock
Copy the code
Nginx must have a configuration like the following:
location / {
include uwsgi_params;
uwsgi_pass unix:///xxx/yyy/zzz.sock;
}
Copy the code
Why would they write that? Because that’s what they read on other blogs! They know why, but they don’t know why.
What’s the problem?
There’s nothing wrong with this in itself, even Flask’s official documentation says it this way, as shown below:
The Flask application, UWSGi, and Nginx all run on the same server. With Docker, these three things even need to be run into a container.
If it is a small site with sufficient server resources, then this is no problem and Unix sockets are secure and fast.
So if you have three Docker containers on the same server, and each container has a different website, do you need to install an Nginx in each container?
For larger sites, Nginx needs to do load balancing. If you put Nginx and the site on the same server, either Nginx slows down the server or the site slows down the server, it can cause serious problems.
Can Nginx be installed on one server, and then the three sites on the server are stored in three Docker containers, each containing only Flask and UWSGi, but no Nginx?
How do you install UWSGi + Flask on server B, C, D, E, or F?
So get to the topic of today, install UWSGi + Flask(or Django), but not Nginx (Deploy Flask with UWSgi but without Nginx)
Uwsgi without Unix sockets
Unix sockets are essentially a file (Unix/Linux philosophy: Everything is a file) through which Nginx and UWSGI communicate. So you need Nginx on the same machine as UWSGi.
However, uWSGi is itself A server, and Nginx on server A can communicate with UWSGi on server B over HTTP.
To enable UWSGi to communicate using HTTP, we can modify the uWSGi configuration file xxx.ini:
[uwsgi]
module = wsgi:app
master = true
process = 5
threads = 100
gevent = 100
async = 100
http-socket = 0.0.0.0:5001
virtualenv = /Users/kingname/.local/share/virtualenvs/ActiveScoreApi-Ax_h-Y5w
Copy the code
The meaning of other parameters is not the focus of this article, we are concerned with http-socket = 0.0.0.0:5001. Its purpose is to deploy the web site on port 5001 of the native machine and allow external access via HTTP.
After writing the configuration file, start uWSGi with the following command:
uwsgi --ini xxx.ini
Copy the code
Then you use IP:5001 to access your site. At this point, if you have Nginx, simply set up a reverse proxy on Nginx to proxy requests from port 80 to port 5001.
Similarly, put the UWSGi and website inside the Docker image, and the container opens port 5001. Nginx on the host or other machine can access the UWSGI inside the container directly through IP: port, no need to set up Unix sockets.
In addition, if you read the official UWSGI documentation, you will see that in addition to http-socket = 0.0.0.0:5001, you can also change it to HTTP = 0.0.0.0:5001. So are these two ways the same?
The official documentation specifically distinguishes their use scenarios:
The http and http-socket options are entirely different beasts. The first one spawns an additional process forwarding requests to a series of workers (think about it as a form of shield, at the same level of apache or nginx), while the second one sets workers to natively speak the http protocol. TL/DR: if you plan to expose uWSGI directly to the public, use –http, if you want to proxy it behind a webserver speaking http with backends, use –http-socket.
In short, if you use UWSGi as a server, and uWSGi starts up and just gives the IP: port to someone else, you can use HTTP. If you have an Nginx in front of your UWSGI, use http-socket.