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.
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
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
pip install uwsgi
pip install django
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
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
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