This tutorial is aimed at beginners and is a part of a series where we learn to run a django app with Gunicorn and Nginx, and manage it with the help of the Supervisord. Basically, we are trying to emulate a production environment.
We are all very well aware that we can run our django app simply by executing a
./manage.py runserver command. We also know that it is
called a development server for a reason. You know it is not robust, security issues, thread issues and etc. So, how do we really run
our app then?
Enter Gunicorn, a simple, light and speedy Python WSGI HTTP Server for UNIX. We will see how to use gunicorn now but it is not the main reason I wrote this tutorial. The main reason is this: back in the day I was terrified at the thought of anything related to production vs development stuff because I thought, you know, THESE ARE NGINX and GUNICORN which can support millions of requests per second and are very secure/robust/reliable and thus should be very difficult to learn and configure. I want to prevent others from experiencing the same and demonstrate that it is really simple and simple.
Enough talk, let's fight! (YAY, always wanted to quote Kung Fu Panda)
First, let's go ahead and update/upgrade our packages:
sudo apt-get update sudo apt-get upgrade
If you are using python2, type the following:
sudo apt-get install python-pip
If you are instead using python3, type the following:
sudo apt-get install python3-pip
sudo pip install virtualenv
sudo pip3 install virtualenv
Let's go ahead now and install a virtual environment at
/opt/envs/myprojenv. You can install it anywhere you like and in real life use
a more descriptive name for the virtualenv:
You should now see
(myprojenv) at the beginning of your command line.
Now, install Django. By the way, we will only use
pip from now on, not
pip3, as we are inside a virtual environment:
pip install django
Create a project:
django-admin startproject myproject
Apply migrations and run the development server:
cd myproject ./manage.py migrate ./manage.py runserver
localhost:8000/admin and make sure that it is running. Is it running? Cool! Easy right?!
Now we will replace this development server with gunicorn and you will see that it is as easy.
pip install gunicorn
Run this, go to
localhost:8000and behold the magic:
DO YOU SEE IT? It is this easy.
Now you might be wondering what is that
wsgi thing is. Well, it stands for Web Server Gateway Interface and basically is a way how
apps/frameworks and servers talk to each other. If the server(like Gunicorn) has
wsgi implemented and so has your framework(Django),
it means that you can run your app with that server. And the entry point of communication for these two is the variable
which is located in
myproject/wsgi.py in our case. You can read more about this in PEP 333.
Let's play with it a little bit to see what it got.
We can bind it to a specific port:
gunicorn --bind 0.0.0.0:8030 myproject.wsgi
You can increase the number of workers to serve requests, which you probable will in real life as your users increase:
gunicorn --workers 3 myproject.wsgi
Run it in a daemon mode:
gunicorn --daemon myproject.wsgi
Or all of them altogether(a shorter version):
gunicorn -d -b 0.0.0.0:8030 -w 3 myproject.wsgi
Read more about these options in the docs
If these options get too long, you can create an
ini file and run it like this:
gunicorn -c /path/to/config/file myproject.wsgi
After running your app with gunicorn, go to the django admin panel at
localhost:8000/admin. You will see that all styles are gone.
The reason is that gunicorn is an application server and it does not serve static files. In order to solve this problem, we will take a look
Nginx next and use it as a reverse proxy for gunicorn. We will talk about what
reverse proxy is as well so don't think about it for now.
Well, that's it for now. This is a brief overview of django with gunicorn. Go to docs and read more.