nginx + gunicorn + Django = Production-ready

Django gives a local server but this is not a recommended solution for production environment… For this we’ll use nginx+gunicorn to make it more fault tolerant and robust.

How to create your own django project?

  • Create a directory and a virtual environment in it
mkdir dummyproj && cd dummyproj
python3 -m venv newenv
source newenv/bin/activate
  • Install Django.
pip3 install Django
  • Create and start your project
django-admin.py startproject hello

cd hello/

python manage.py runserver 0.0.0.0:8000

This will run your test project. If you are not testing it locally then you’ll have to allow hosts to connect to this project by editing hello/settings.py file.

ALLOWED_HOSTS = ['*']

Now you have your django project running successfully.

Making it production ready…

Django has a single threaded testing server which can not meet the requirements of the production environment. So we’ll use a dedicated service called gunicorn.

  • Install gunicorn in your virtual environment
pip3 install gunicorn
  • check if it works fine with the django project
gunicorn hello.wsgi:application --bind 0.0.0.0:8000
  • Open another terminal and check if you can access it from the public IP on port 8000
  • Install nginx on your machine (I am using a debian based system so this worked for me fine.)
  • Once nginx and gunicorn are ready, we can make our django code production ready.

Let’s first gather all the details we’ll need to connect everything together.

  • Nginx will forward the request to gunicorn, so we need a proxy_pass which points to gunicorn (Basically points to gunicorn socket)
  • gunicorn will request the data from django project (via socket). And gunicorn is present inside the virtual environment here.

Let’s begin with connecting the dots.

First, I’ll create a gunicorn service file that can use socket to connect to django project and make requests to it.

sudo vim /etc/systemd/system/gunicorn-hello.service

And add the below lines to it.

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=ayedaemon ## User who has permissions to the WorkingDirectory
Group=www-data
## Directory where the project resides
WorkingDirectory=/home/ayedaemon/dummyproj/

## What command will start by this service
ExecStart=/home/ayedaemon/dummyproj/newenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/home/ayedaemon/dummyproj/hello.sock\
hello.wsgi:application

[Install]
WantedBy=multi-user.target

(Note) These values might change as per your project structure

Once a socket is created. Check it using curl.

curl --unix-socket /home/ayedaemon/dummyproj/hello.sock localhost

Now you have a gunicorn --> Django connection established. Let's go for Nginx --> gunicorn now.

Create a sites file for nginx (configuration file).

sudo vim /etc/nginx/sites-available/helloproj.conf

Now add below configuration to it.

server
listen 1234;
server_name <your domain name>; ## Add your domain name or ip on which it'll be hosted

location /static/ {
alias /home/ayedaemon/dummyproj/hello/static/;
}

location / {
include proxy_params;
proxy_pass http://unix:/home/ayedaemon/dummyproj/hello.sock;
}
}

make a soft link of this file in sites-available.

sudo ln -s /etc/nginx/sites-available/helloproj.conf /etc/nginx/sites-enabled

Restart the servers and reload all configurations.

sudo systemctl daemon-reload
sudo systemctl restart gunicorn-hello.service
sudo systemctl restart nginx

How to install certbot ssl certificate?

This is very simple and straight forward thing to do. Thanks to certbot for all the automation they have done. There are 3 simple steps to be followed.

  1. Install certbot for your system.
  2. Configure certbot to install certificate for your site.
  3. Check it.

You can use this to get all the instructions to follow.

--

--

--

Connecting the dots and rest is magic. https://ayedaemon.github.io/

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How to bridge ZEFI cross-chain

Haze Finance Frequency Mining Competition: $30000 USD Reward For One Winner

Vagrant Error “Your VM has become inaccessible” : how to fix that ?

Code Coverage, Java Debugger API and Full Integration in Building DDJT — Day 3

Docker Out-Side Docker

Spring Boot Microservices + Apache Camel Hello World Example

Why I don’t use NoSQL databases for new projects

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Rishabh Umrao

Rishabh Umrao

Connecting the dots and rest is magic. https://ayedaemon.github.io/

More from Medium

Test-Driven-Development with Django: Unit Testing & Integration testing with Docker, Flask & Github…

Django Github CI/CD

Playing around with Django JWT

Razorpay payment gateway integration with Django 💳 👨‍💻

How to connect a Django project with MongoDB?