Setup Django behind uWSGI and NGINX on CentOS 7

Django behind uWSGI and NGINX

Setting up a web server for Django could be challenging and headache. Let’s try to make it simple: Django behind uWSGI and NGINX on CentOS 7 from scratch. At the end, our complete stack of components will look like this:

the web client <-> the web server <-> the socket <-> uwsgi <-> Django

1. Install Dependencies

Assuming that you are working on a smallest VPS like mine (1GB of RAM, 1 vCPU, 25GB SSD). I am currently use Linode and DigitalOcean.

1.1. NGINX

yum install epel-release -y
yum install nginx -y

1.2. Python 3 & PIP

yum install python34-devel gcc -y
curl -O https://bootstrap.pypa.io/get-pip.py
/usr/bin/python3.4 get-pip.py

1.3. Create VirtualEnv with Python3

pip install virtualenv
mkdir -p /var/www && cd /var/www
python3.7 -m venv p3venv

If you are up-to-dated person, you can install 3.6.2 (latest python version as of now – Aug 28, 2017) follow this instruction https://janikarhunen.fi/how-to-install-python-3-6-1-on-centos-7.html

1.4. Install uWSGI & Django

# Activate virtual environment
source p3venv/bin/activate
pip install uwsgi
pip install django

2. Configurations

2.1. Basic NGINX config

For simplest & testing purposes, let’s create NGINX server block by issuing “vi /etc/nginx/conf.d/django.conf”. Any *.conf file inside this folder will be loaded as per instructed by main & default NGINX configuration (/etc/nginx/nginx.conf).

Save NGINX config and start NGINX service: systemctl start nginx

As of now, we have NGINX serves static files and by pass others to Django Server which will be configured shortly. It means you will get 502 bad gateway when accessing the site but this is totally fine.

2.2. Create Django project

# Make sure we are in right place
cd /var/www/example
django-admin.py startproject djangodemo
# Also allow domain or IP in Django settings (/var/www/example/djangodemo/djangodemo/settings.py)

Test if they look good by starting Django Development and uWSGI server. You will get “It worked! Congratulations on your first Django-powered page.”

python manage.py runserver 0.0.0.0:8000 ("ctrl + c" to terminate)
uwsgi --http :8000 --module djangodemo.wsgi ("ctrl + c" to terminate)

Alright, let’s configure uWSGI as service so we don’t have to keep terminal open.

2.3. Configure uWSGI as service

Save djangodemo_uwsgi.ini file and create symlink from the default config directory to your config file

ln -s /var/www/example/djangodemo/djangodemo_uwsgi.ini /etc/uwsgi/vassals/

Quick test if the configuration is good by start uWSGI server and navigate to the site. You should get “It worked! Congratulations on your first Django-powered page.”
/var/www/p3venv/bin/uwsgi --emperor /etc/uwsgi/vassals
Ctrl + C to terminate uWSGI server and let’s make it runs as a service

Start uWSGI and NGINX services and you should be able to access to your Django app without having to hold terminal open.

systemctl start uwsgi
systemctl restart nginx

Final thought

Congratulations. You’ve completed setting up NGINX, uWSGI to serve Django application. I know this is not so easy, especially when you are new to Django and uWSGI like me. It took me almost 2 weeks to search and try things out before writing this article.

I am still stuck at djangodemo_uwsgi.ini with chmod-socket = 666. Whenever I change it to chmod-socket = 664, I get 502 bad gateway. If someone knows the cause and how to fix it, please let me know.

Any input or comment are more than welcomed and appreciated. So why not leave a comment now, huh?

Image credit: http://technerd.tistory.com/55

References:
– https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html
– https://www.youtube.com/watch?v=DzXCHAuHf0I
http://ask.xmodulo.com/install-python3-centos.html
– https://stackoverflow.com/questions/41588925/pip-install-django-on-python3-6
– https://www.nginx.com/resources/admin-guide/gateway-uwsgi-django/

, ,

2 responses to “Setup Django behind uWSGI and NGINX on CentOS 7”

  1. It appears to me that you are accessing your site via uWSGI directly. If you want to use it (uWSGI), then just change the port from 8000 to 80 or you can serve all requests via nginx (proxy). If you send me your configuration, I’ll try my best to figure out what happens

Leave a Reply