Django is a python web framework used for developing web applications. It is fast, secure and scalable. Let us see how to configure the Django app using gunicorn.
Before proceeding to actual configuration, let us see some intro on the Gunicorn.
Gunicorn (Green Unicorn) is a WSGI (Web Server Gateway Interface) server implementation commonly used to run python web applications and implements PEP 3333 server standard specifications, therefore, it can run web applications that implement application interface. Web applications written in Django, Flask or Bottle implements application interface.
pip3 install gunicorn
Gunicorn coupled with Nginx or any web server works as a bridge between the web server and web framework. Web server (Nginx or Apache) can be used to serve static files and Gunicorn to handle requests to and responses from Django application. I will try to write another blog in detail on how to set up a django application with Nginx and Gunicorn.
Please make sure you have below packages installed in your system and a basic understanding of Python, Django and Gunicorn are recommended.
- Python > 3.5
- Gunicorn > 15.0
- Django > 1.11
Configure Django App Using Gunicorn
There are different ways to configure the Gunicron, I am going to demonstrate more on running the Django app using the gunicorn configuration file.
First, let us start by creating the Django project, you can do so as follows.
django-admin startproject webapp
After starting the Django project, the directory structure looks like this.
The simplest way to run your django app using gunicorn is by using the following command, you must run this command from your manage.py folder.
This will run your Django project on 8000 port locally.
Now let’s see, how to configure the django app using gunicorn configuration file. A simple Gunicorn configuration with worker class `sync` will look like this.
import sys BASE_DIR = "/path/to/base/dir/" sys.path.append(BASE_DIR) bind = '127.0.0.1:8000' backlog = 2048 import multiprocessing workers = multiprocessing.cpu_count() * 2 + 1 worker_class = 'sync' worker_connections = 1000 timeout = 300 keepalive = 2 # # spew - Install a trace function that spews every line of Python # that is executed when running the server. This is the # nuclear option. # # True or False # spew = False #errorlog = '-' accesslog = '/var/log/webapp_access_log' loglevel = 'debug' errorlog = '/var/log/webapp_error_log' def post_fork(server, worker): server.log.info("Worker spawned (pid: %s)", worker.pid) def pre_fork(server, worker): pass def pre_exec(server): server.log.info("Forked child, re-executing.") def when_ready(server): server.log.info("Server is ready. Spawning workers") def worker_int(worker): worker.log.info("worker received INT or QUIT signal") ## get traceback info import threading, sys, traceback id2name = dict([(th.ident, th.name) for th in threading.enumerate()]) code =  for threadId, stack in sys._current_frames().items(): code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,""), threadId)) for filename, lineno, name, line in traceback.extract_stack(stack): code.append('File: "%s", line %d, in %s' % (filename, lineno, name)) if line: code.append(" %s" % (line.strip())) worker.log.debug("\n".join(code)) def worker_abort(worker): worker.log.info("worker received SIGABRT signal")
Let us see a few important details in the above configuration file.
- Append the base directory path in your systems path.
- You can bind the application to a socket using
- `backlog` Maximum number of pending connections.
- `workers` number of workers to handle requests. This is based on your machine’s CPU count. This can be varied based on your application workload.
- `worker_class`, there are different types of classes, you can refer here for different types of classes. `sync` is the default and should handle normal types of loads.
You can refer more about the available Gunicorn settings here.
Running Django with gunicorn as a daemon PROCESS
Here is the sample systemd file,
[Unit] Description=webapp daemon After=network.target [Service] PIDFile=/var/run/webapp.pid WorkingDirectory=/path/to/base/dir/ ExecStart=/usr/local/bin/gunicorn --config /path/to/gunicorn/config.py --pid /var/run/webapp.pid webapp.wsgi:application ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target
After adding the file to the location
/etc/systemd/system/. To reload new changes in file execute the following command.
NOTE: MAKE SURE TO INSTALL REQUIRED PACKAGES, GUNICORN FAILS TO START IF THERE ARE ANY MISSING PACKAGES. YOU CAN REFER TO MORE INFO IN ERROR LOGFILE MENTIONED IN CONFIGURATION FILE.
Start, Stop and Status of Application using systemctl
Now you can simply execute the following commands for your application.
To start your application
systemctl start webapp
To stop your application.
systemctl stop webapp
To check the status of your application.
systemctl status webapp
Please refer to a short complete video tutorial to configure the Django app below.