DEV Community

Cover image for Deploying react and django with nginx and guincorn
King Tobi
King Tobi

Posted on

Deploying react and django with nginx and guincorn

react djang.png
Deploying react and django with nginx and guincorn
Deploying react with django isn't straight forward but I am here to assist you with that. We will be going through how to deploy both react and django as the main and subdomain using the same server/ubuntu instance. What this means is you will deploy your frontend and backend separately on two different subdomains such as the frontend will be accessed via www.example.com while the django backend api will be accessed via www.api.example.com
Prerequisite knowledge

  • Experience with ubuntu
  • Experience with GitHub
  • Linux based system with ubuntu 16 and above Tools
  • GitHub
  • AWS/DigitalOcean/Cloudcone i.e a cloud provider
  • Domain **First login to your server using putty and your root access **Use terminal and run:
apt update && apt upgrade -y
Enter fullscreen mode Exit fullscreen mode

Set hostname for server. I used test-server. You can use whatever you want.

hostnamectl set-hostname test-server
Enter fullscreen mode Exit fullscreen mode

Create a limited user and give sudo privileges
run

 

adduser USERNAME .
Enter fullscreen mode Exit fullscreen mode


 
Enter password and skip through the rest of the questions.
then run

 

adduser USERNAME sudo
Enter fullscreen mode Exit fullscreen mode

logout as root by typing ** exit **and log in with your username: ssh username@IP
Pull both frontend and backend code from github using

git clone
Installing some important packages

sudo apt-get install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx
Enter fullscreen mode Exit fullscreen mode

** Set Up Nginx Server Blocks**
Creating the First Server Block File For React Frontend
Install NodeJS and npm
Use Current Release

sudo apt-get install curl
curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -
sudo apt-get install nodejs
Enter fullscreen mode Exit fullscreen mode

As mentioned above, we will create our first server block config file by copying over the default file:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
Enter fullscreen mode Exit fullscreen mode

Now, open the new file you created in your text editor with sudo privileges:

sudo nano /etc/nginx/sites-available/example.com
Enter fullscreen mode Exit fullscreen mode

Ignore the commented lines, and look at the code similar to this:

server {
 listen 80 ;
 listen [::]:80;
root /home/username/react-frontend/build;
 index index.html index.htm;
server_name your_IP domain.com www.domain.com;
location / {
 try_files $uri /index.html =404;
 }
}
Enter fullscreen mode Exit fullscreen mode

Then Enable the file by linking to the sites-enabled dir

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled
Enter fullscreen mode Exit fullscreen mode

Test NGINX config

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

Restart Nginx Server

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

Create the Second Server Block File which will be for django
First Install some dependencies

run sudo apt install virtualenv ufw
Enter fullscreen mode Exit fullscreen mode

Change to your virtualenv
run

 

virtualenv venv -p python3
Enter fullscreen mode Exit fullscreen mode

run

 

source venv/bin/activate
Enter fullscreen mode Exit fullscreen mode

Back out to the directory that has manage.py
Run

 

python manage.py collectstatic
Enter fullscreen mode Exit fullscreen mode

Install Gunicorn
run

 

pip install gunicorn
Enter fullscreen mode Exit fullscreen mode

Check to see if gunicorn can host your django project. Change **DjangoProject **to whatever your project is called
run

 

gunicorn - bind 0.0.0.0:8000 DjangoProject.wsgi
Enter fullscreen mode Exit fullscreen mode

Create gunicorn systemd file
run

 

sudo nano /etc/systemd/system/gunicorn.service
Enter fullscreen mode Exit fullscreen mode

Paste the following and be sure to update your project name, path and username accordingly:

[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=username
Group=www-data
WorkingDirectory=/home/username/DjangoProject
ExecStart=/home/username/venv/bin/gunicorn - access-logfile - - workers 3 - bind unix:/home/username/DjangoProject/DjangoProject.sock DjangoProject.wsgi:application
[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

Step : Run the following commands to enable gunicorn:

sudo systemctl start gunicorn
sudo systemctl enable gunicorn
sudo systemctl status gunicorn
sudo systemctl daemon-reload
sudo systemctl restart gunicorn
Enter fullscreen mode Exit fullscreen mode

Now that we have our initial server block configuration, we can use that as a basis for our second file. Copy it over to create a new file:

sudo cp /etc/nginx/sites-available/example.com /etc/nginx/sites-available/test.com
Enter fullscreen mode Exit fullscreen mode

Open the new file with sudo privileges in your editor:

sudo nano /etc/nginx/sites-available/test.com
Enter fullscreen mode Exit fullscreen mode

Paste the following and be sure update your own IP, username, path and project name
This covers http, https will be covered below

server {
 listen 80;
 server_name IP;
 location = /favicon.ico { access_log off; log_not_found off; }
 location /static/ {
 root /home/username/DjangoProject;
 }
 location / {
 include proxy_params;
 proxy_pass http://unix:/home/username/DjangoProject/DjangoProject.sock;
 }
 }
Enter fullscreen mode Exit fullscreen mode

Link and test nginx config
Link:

 

sudo ln -s /etc/nginx/sites-available/django-project/etc/nginx/sites-enabled
Enter fullscreen mode Exit fullscreen mode

Test:

 

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

Reload Nginx and Gunicorn

sudo systemctl restart gunicorn
sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

In order to avoid a possible hash bucket memory problem that can arise from adding additional server names, we will also adjust a single value within our **/etc/nginx/nginx.conf **file. Open the file now:

sudo nano /etc/nginx/nginx.conf
Enter fullscreen mode Exit fullscreen mode

Within the file, find the** server_names_hash_bucket_size directive. Remove the **# symbol to uncomment the line:
/etc/nginx/nginx.conf

http {
 . . .
 server_names_hash_bucket_size 64;
 . . .
}
Enter fullscreen mode Exit fullscreen mode

Now, let's activate SSL and bind the domains to their respective proxies
Install Certbot and it's Nginx plugin with apt:

sudo apt install certbot python3-certbot-nginx
Enter fullscreen mode Exit fullscreen mode

Certbot is now ready to use, but in order for it to automatically configure SSL for Nginx, we need to verify some of Nginx's configuration.
Obtain an SSL Certificate
First we obtain SSL certificate for the react url

sudo certbot - nginx -d example.com -d www.example.com
Enter fullscreen mode Exit fullscreen mode

This runs certbot with the - nginx plugin, using -d to specify the domain names we'd like the certificate to be valid for.
If that's successful, certbot will ask how you'd like to configure your HTTPS settings.
Output
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1–2] then [enter] (press 'c' to cancel):
Enter fullscreen mode Exit fullscreen mode

Select your choice then hit ENTER. The configuration will be updated, and Nginx will reload to pick up the new settings. certbot will wrap up with a message telling you the process was successful and where your certificates are stored:
Let's finish by testing the renewal process.

Verify Certbot Auto-Renewal

You can query the status of the timer with systemctl:

sudo systemctl status certbot.timer
Enter fullscreen mode Exit fullscreen mode

To test the renewal process, you can do a dry run with certbot:

sudo certbot renew - dry-run
Enter fullscreen mode Exit fullscreen mode

If you see no errors, you're all set. When necessary, Certbot will renew your certificates and reload Nginx to pick up the changes. 
If the automated renewal process ever fails, Let's Encrypt will send a message to the email you specified, warning you when your certificate is about to expire.
Now, repeat the same SSL process for the django domain
Credits:
Credits to

  1. Ousseynou Diop for the react deployment guide
  2. Satssehgalfor the django deployment guide
  3. Digitaloceanfor all their articles

Top comments (1)

Collapse
 
caloybae07 profile image
Caloy

After doing all the steps, it somehow worked. but my djangi backend does not work. Cant Login to my react app.

Any fix for this please.