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 https://github.com/<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. gunicorn.sh.
  • An example draft template of this gunicorn script should look like this:
#!/bin/bash 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>> PORT=<8500> LOCAL_IP=<127.0.0.1> echo "Starting $NAME as `whoami`" cd $DJANGODIR 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 \ --logo-file=- 
Enter fullscreen mode Exit fullscreen mode
  • Run the gunicorn shell script by executing ./gunicorn.sh

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 gunicorn.sh 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 (0)