DEV Community

King Isaac Nsengiyunva
King Isaac Nsengiyunva

Posted on

Deploy a python django and reactJS restful app with gunicorn, supervisor and nginx on a linux ubuntu server.

The task is to deploy a decoupled Application with 2 seperate services that communicate with each other using API. The frontend app written with ReactJS - a popular Javascript library - and a backend app that handles the database written in Python using the Django restframework library. The 2 apps are also hosted on the github server repository.
The React app communicates with the Django/ Server over REST HTTP methods such as POST, GET, PUT, PATCH, DELETE etc.

Step 1: staging the apps on the server

  • Git clone your django app on the Ubuntu server e.g. $ git clone<your username>/<your git repo>
  • Git clone your reactJS app too. You should have 2 folders listed on the server with all the files.

Step 2: Manual compile and prepare the reactJS frontend.

  • $ cd into your reactJS frontend folder by typing. cd <frontend folder name>
  • $ yarn install or $ npm install to add dependencies and packages to your app. if yarn or node is not installed on the ubuntu server, make sure you install these libraries first.
  • $ yarn run build to transpile the final static and bundled files.
  • Your frontend app will now include a build folder with the static and bundled files.

Step 3: Staging and Preparing the Django app

  • Create a new virtual environment for the django app by running python3 m venv <virtual env name>
  • Activate the virtual environment by running: source <virtual env name>/bin/activate
  • Install all dependencies for the django app by running: pip install -r requirements.txt
  • Install Gunicorn if not already installed by running: pip install gunicorn

Step 4: Create a Gunicorn shell script to execute the django app

  • Change user to root by logging as root user.
  • Create a gunicorn shell script preferably in the same folder as the django app e.g.
  • An example draft template of this gunicorn script should look like this:
NAME="<service name>" #name of the service to be run by supervisor
DJANGODIR=<path/to/django app>
USER=<user e.g. root> #you can see your user name by running command whoami
GROUP=<usergroup e.g. root>
NUM_WORKERS=<number of workers e.g. 2>
TIMEOUT=<e.g 500>
DJANGO_SETTINGS_MODULE=<app.settings<the django settings file>>
DJANGO_WSGI_MODULE=<app.wsgi< the wsgi file>>

echo "Starting $NAME as `whoami`"

source <path/to/virtualenv/bin/activate> #run the virtual environment
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE #set the global variable to the settings file
export PYTHONPATH=$DJANGODIR:$PYTHONPATH #set your django app directory as python path

exec <path/to/virtualenv/bin/gunicorn ${DJANGO_WSGI_MODULE} >
--name $NAME \
--workers $NUM_WORKERS \
--timeout $TIMEOUT \
--user=$USER --group=$GROUP \
--pythonpath=<path/to/virtualenv/bin \
--log-level=debug \
--bind=$LOCAL_IP:PORT \
Enter fullscreen mode Exit fullscreen mode
  • Run the gunicorn shell script by executing ./

Step 5: Configure the Supervisor

  • Supervisor in this case scenario is responsible for running the django service. Before you proceed, make sure the supervisor library /package is correctly installed on the Ubuntu VPS.
  • check the current service list by running $ sudo supervisorctl status This will display a list of service names available.
  • Add a New Service as set in the script above by navigating to $ cd /etc/supervisor/conf.d. Then create your service conf file e.g sudo nano <name.conf>
  • To update the supervisor list. Run supervisorctl reread. This command will make your configuration changes available.

Step 6: Add Nginx to serve the applications

  • Nginx will serve both our applications on the default port 80. Make sure the nginx library or package is installed on the Ubuntu machine.
  • Navigate to the nginx folders as: $ cd /etc/nginx/sites-available and create a new conf file for your application configuration.
  • Create a conf file as <sudo nano name.conf>
  • Add a server block as shown below:
server {

        server_name <name/your preferred domain name>;

        proxy_read_timeout 300;
        proxy_connect_timeout 300;
        proxy_send_timeout 300;

        location / {
            root /path/to/react/frontend/build;
        location /api/v1 {
            proxy_pass http://<localhost>:<port name configured in gunicorn shell script >;
Enter fullscreen mode Exit fullscreen mode
  • The server block above shows includes 2 location directives.
  • The root folder directive serves the reactjs build folder that includes the index.html file.
  • The location directive <server name/ap1/v1> will serve the django rest server using a proxy pass address.

Happy Coding!

Top comments (1)