Setup Django + uWSGI + Nginx
Prologue
In this article, I’d like to demonstrate on how to setup backend service of Django using uWSGI and Nginx. It mainly focus on the configurations of uWSGI and Nginx, rather than how to build Django project.
I use Ubuntu server. :)
Prerequisites
Before you start, you should have a Linux server, with conda environment.
Quick References
Here are some quick references for uWSGI and Nginx. You can expand it optianlly.
Quick References
uWSGI
1 | uwsgi --ini uwsgi.ini # start uwsgi service |
Nginx
1 | # start Nginx |
Procedures
Step 1. Prepare Django
You should have your Django project ready. You should configure the virtual environment using conda
. For example, your environment for this project is django
. For the root directory of your project, here I use /home/server/backend
as an example. This directory is where manage.py
located.
Step 2. Setup uWSGI
Introduction
“uWSGI (source code), pronounced “mu wiz gee”, is a Web Server Gateway Interface (WSGI) server implementation that is typically used to run Python web applications.”
- From https://www.fullstackpython.com/uwsgi.html
Install uWSGI
Go to the root folder of your Django project, where manage.py
is located. Activate your corresponding environment, here, I use django
. Then, you can download and install uWSGI.
1 | conda install -c conda-forge uwsgi |
If you use
pip
to installuwsgi
, you may encounter some errors due togcc
version. So aconda
install is preferred.Important! Notice that, a global
uwsgi
won’t work! In that case,uwsgi
wouldn’t locate correct Python environment. So you have to download it in this way.
Add uwsgi.ini
To use uwsgi
as a host of our Django project, we need a uwsgi.ini
.
1 | [uwsgi] |
Some explanation to it. Technically, you can use relative path here. But absolute path can make sure no path related problem happens.
socket
, http
: For these two, only one is needed. If you use Nginx, then use socket
, and there will be no need to add port number. If you use uwsgi
to run Django directly, use http
, and you need add port number here.
You may need to replace
127.0.0.1
with0.0.0.0
if you could not access the server remotely.
chdir
: This indicates the root folder of the backend project. This is where manage.py
locates.
wsgi-file
: This is the wsgi.py
file of your project.
processes
: This specifies the process number of uWSGI.
daemonize
: Well, this is the log file. Daemon process of uWSGI will put logs here.
pidfile
: This file stores the pid
of uWSGI process, can be used to shut down uWSGI service.
virtualenv
: The virtual environment of your Django project. This can be found under your conda installation location. Usually ${conda_home}/env/${env_name}
.
The others are not that important, so I’m not going to spend time on them.
Launch uWSGI
Now that we haven’t setup Nginx yet, we should comment socket
in uwsgi.ini
out, and use http
instead.
In your Django project root folder, run this to launch uWSGI. This tells it to use uwsgi.ini
file to initialize, then it will run automatically.
1 | uwsgi --ini uwsgi.ini |
You can check it by find its processes.
1 | ps aux | grep uwsgi |
If no process, you can check uwsgi.log
file for more information. If you installed uwsgi
the same way as me, you should encounter no error.
Stop uWSGI
Well, start and end always come together. If you set pidfile
, it will be quite easy.
1 | uwsgi --stop uwsgi.pid |
Step 3. Setup Nginx
Introduction
Well, Nginx, pronounced “Engine-X”, is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server.
Basically, it works like this. For front end, it monitors certain ports, such as the common 80
. Then, depending on the url, it will redirect access to other ports, such as /api
.
Install Nginx
Emm… Quite easy, huh.
1 | sudo apt install nginx |
Configure Nginx
Usually, Nginx configuration file locates here: /etc/nginx/conf.d/default.conf
. The name of it can vary. If it doesn’t exist, just create one. And this operation need root permission.
1 | sudo vim /etc/nginx/conf.d/default.conf |
Tips: Almost all Nginx commands need root permission.
Then, add the following configurations to it. This configuration will set frontend to xx.xx.xx.xx:80
, or simply xx.xx.xx.xx
. And backend to xx.xx.xx.xx/api
.
1 | server { |
Some explanations.
listen
: The port of front end. Usually 80.
server_name
: The public IP address of your server.
location
: This is used to redirect access. For example, /
here means xx.xx.xx.xx/
, and /api
means xx.xx.xx.xx/api
. So, if a url is like xx.xx.xx.xx/api/login
, it will redirect it to xx.xx.xx.xx:4000/api/login
.
Notice! We could not access
xx.xx.xx.xx:4000
directly.
More about location
. Here, location /
is for front end. root
is the root folder of your front end project. And others can remain the same. location /api
is for backend. Here, since we use uwsgi
, so we should add a include for it. Then, is our uwsgi_pass
, it should be the same as what we assigned in uwsgi.ini
. It tells Nginx to redirect requests to uWSGI port.
/api
here is just a prefix that we set in Django project. You can change it, of course. But make sure it is consistent with the url pattern in Django.
Launch Nginx
Now that we have configured Nginx, we can start it. Before we start, make sure you change uwsgi.ini
to use socket
instead of http
. Remember?
First, launch Nginx service. You can use either of these. Perhaps it is already online.
1 | sudo nginx |
Then, if any modification is made to the configuration file, a reload would be necessary.
1 | sudo nginx -s reload |
Now, you can access both frontend and backend.
Stop Nginx
Emm… Again, start and end. Here is how to stop Nginx.
1 | sudo nginx -s quit # stop after current process finishes its work |
Well, this is it. Configuring internet service is really… annoying… Barnacles. 😵💫