What is gunicorn?

Guincorn or Green Unicorn is a HTTP Server which supports WSGI (WSGI are a bunch rules that allow a web framework, in this case Django, to talk with the server). Django by default generates a WSGI config for your project wsgi.py, and from the comments "It should expose a module-level variable named ``application``. " Keep this in mind for later. Gunicorn is an app server. Its primary job is to work with the web application and serve up "processed" data to web servers and sometimes other app servers. Based on the pre-forker model, there is a master process which manages the workers who handle all the requests and responses.

What is Nginx?

Nginx is a web server. Its primary job is to serve the static content from a web application (HTML, images, videos etc.) to us (browsers or mobile applications). As a reverse proxy server, it's the public face for the application, it can direct requests from the browsers to the appropriate backend server (Gunicorn). Nginx handles load balancing, web acceleration and security.

Why do we need guincorn OR NGINX?

The Django server by itself is great for development but wouldn't survive in production. It's not meant to handle a lot of traffic. That's where Guincorn and Nginx come in. While we could Guincorn to run the web application, create workers and sockets, server static content, Ngnix just does a better job of handling the stress of the web as a reverse proxy. Gunicorn recommends having a proxy server in front of it (and Nginx is strongly preferred).

If your application is a fancy upscale restaurant, Ngnix would be the dedicated expeditor and Gunicorn the Chef who directs the rest of the kitchen in this case your Django applications.

Setting up Gunicorn

pip install gunicorn

Gunicorn requires an application object, remember the wsgi.py generated by Django and a socket file to communicate with Nginx (the socket file is automatically created the first time the application is run with Gunicorn). You can also specify the number and type of workers you want.

gunicorn --workers 3 --bind unix:myproject.sock wsgi:app

Setting up Nginx

The default welcome site you see is at /usr/share/nginx/html

It's specified in the default server block configuration file /etc/nginx/nginx.conf

A server block to used to receive requests from a particular domain and port. A location block is defined in a server block and can be used to match the request URI. The bare minimum to set up Gunicorn with Nginx is this:

  server {
    listen 80;
    server_name example.org;
    access_log  /var/log/nginx/example.log;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
  }

Here a server block has been defined for example.org which listens to requests from port 80 and passes it on to the proxied server http://127.0.0.1:8000. But in our case the proxied server is the socket at myproject.sock (http://unix:/home/user/myproject/myproject.sock;)

References

https://www.nginx.com/resources/glossary/application-server-vs-web-server/

https://www.digitalocean.com/community/tutorials/django-server-comparison-the-development-server-mod_wsgi-uwsgi-and-gunicorn

https://serverfault.com/questions/331256/why-do-i-need-nginx-and-something-like-gunicorn

http://docs.gunicorn.org/en/stable/design.html