Deploying react and django with nginx and guincorn
Published: 2022-01-21 22:07:23

![react djang.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1642801058743/DuuxMbZhc.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
```
Set hostname for server. I used test-server. You can use whatever you want.
```
hostnamectl set-hostname test-server
```
**Create a limited user and give sudo privileges**
run 
```
adduser USERNAME .
``` 
Enter password and skip through the rest of the questions.
then run 
```
adduser USERNAME sudo
```
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 <repo link>
Installing some important packages
```
sudo apt-get install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx
```
** 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
```
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
```
Now, open the new file you created in your text editor with sudo privileges:
```
sudo nano /etc/nginx/sites-available/example.com
```
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;
 }
}
```
Then Enable the file by linking to the sites-enabled dir
```
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled
```
Test NGINX config
```
sudo nginx -t
```
Restart Nginx Server
```
sudo systemctl restart nginx
```
**Create the Second Server Block File which will be for django**
First Install some dependencies
```
run sudo apt install virtualenv ufw
```
Change to your virtualenv
run 
```
virtualenv venv -p python3
```
run 
```
source venv/bin/activate
```
Back out to the directory that has manage.py
Run 
```
python manage.py collectstatic
```
Install Gunicorn
run 
```
pip install gunicorn
```
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
```
Create gunicorn systemd file
run 
```
sudo nano /etc/systemd/system/gunicorn.service
```
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
```
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
```
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
```
Open the new file with sudo privileges in your editor:
```
sudo nano /etc/nginx/sites-available/test.com
```
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;
 }
 }
```
Link and test nginx config
Link: 
```
sudo ln -s /etc/nginx/sites-available/django-project/etc/nginx/sites-enabled
```
Test: 
```
sudo nginx -t
```
Reload Nginx and Gunicorn
```
sudo systemctl restart gunicorn
sudo systemctl restart nginx
```
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
```
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;
 . . .
}
```
**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
```
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
```
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):
```
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
```
To test the renewal process, you can do a dry run with certbot:
```
sudo certbot renew - dry-run
```
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](https://dev.to/xarala221) for the react deployment guide
2. [Satssehgal](https://github.com/satssehgal)for the django deployment guide
3. [Digitalocean](https://www.digitalocean.com/community)for all their articles