Setup Django behind uWSGI and NGINX on CentOS 7

0

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

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
virtualenv -p python3 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/cioenglish.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 http://www.cioenglish.com but this is totally fine.

2.2. Create Django project

# Make sure we are in right place
cd /var/www
django-admin.py startproject cioenglish
# Also allow domain (cioenglish.com) or IP in Django settings (/var/www/cioenglish/cioenglish/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 cioenglish.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 cioenglish_uwsgi.ini file and create symlink from the default config directory to your config file

ln -s /var/www/cioenglish/cioenglish_uwsgi.ini /etc/uwsgi/vassals/

Quick test if the configuration is good by start uWSGI server and navigate to http://www.cioenglish.com. 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 stop nginx
systemctl start uwsgi
systemctl start 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 cioenglish_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/

Share.

About Author

A QA guy who is trying to learn some dev's skills as well as English by blogging his development notes in English. Hey, please let me know if you see any spelling mistake or I should write things in another better way.