Kenshō - Configuring nginx for Reverse Proxy

Nginx is an open source software that is used for numerous tasks in web development and deployment inclusive of, but not limited to:




  • web serving, i.e. serve static resources of the web app (client sources)
  • reverse proxing, i.e. connect client with backend application
  • HTTP caching, i.e. store a response associated with a request, and reuses it for subsequent requests to improve load performance by reducing unnecessary network requests
  • loading balancing, i.e. distribute traffic across multiple servers in a server farm
  • meadia streaming, i.e. send compressed media (audio/video file) over the Internet and play it immediately instead of storing it.

In this article, we will talk about the configurations written for Nginx such that we can:

  • Serve our JS Framework (such as React/Vue/Nuxt/Angular/etc.) based front-end on Nginx.
  • Connect the client on Nginx with the backend application (such as Django/Nodejs/etc.).
  • Transfer domain calls to inner web server, for example working on another port (proxy). This is beneficial when the frontend and backend applications are being served on different ports, but need to be configured on a single server.

Frontend deployment

Most JS frameworks are built with a command resembling npm run build or npm run serve, which eventually deploy the webste. We willl assume our local frontend deployment is at https://localhost:3000/.

Backend deployment

Deploying and serving backend varies extensively depending on the framework choice. I write my backend application in Python with Django, hence I serve my backend application locally with the command python manage.py runserver which serves the application on https://localhost:8000 by default.

Also, this article is based on the assumption that all APIs follow a pattern of being prefixed by the keyword /api and the static media files are stored in the .media/ directory available in the root of the backend application directory.

What we aim to do

We want that the two applications, frontend and backend, that are being served separately be delegated to one port on the localhost, that is, https://localhost:4000.

Prerequisites

Unless otherwise mentioned, the given commands are to run on termminal for execution.

Useful commands

These commands are for an OSX based system and a linux distribution like Ubuntu.

To Install

  • brew install nginx for OSX, or
  • sudo apt-get install nginx for a linux distro.

To Test

  • sudo nginx -t for OSX.

A successful test should return:

nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
  • systemctl status nginx for a linux distro.

To stop

  • sudo nginx -s stop for OSX, or
  • sudo systemctl stop nginx for a linux distro.

To start, if stopped

  • sudo nginx for OSX, or
  • sudo systemctl start nginx for a linux distro.

To restart

  • sudo nginx -s quit && sudo nginx or sudo nginx -s stop && sudo nginx for OSX, or
  • sudo systemctl restart nginx for a linux distro.

To reload

This is useful when configuration changes are made and we want to reload Nginx without dropping connections. - sudo nginx -s reload for OSX, or - sudo systemctl reload nginx for a linux distro.

To disable Nginx from starting up on boot.

  • sudo systemctl disable nginx for a linux distro.

To re-enable Nginx from starting up on boot.

  • sudo systemctl enable nginx for a linux distro.

Locating the nginx/ directory

The usual locations are as follows: - /usr/local/etc/nginx/ for OSX, or - /etc/nginx/ for a linux distro.

Steps to configure Nginx

The steps to confgure are given below. Information under the 'prerequisites' heading will help to perform the given instructions.

  1. Install Nginx.
  2. Test if it's working properly.
  3. Change directoy into the nginx/ folder.
  4. There should be two folders available, sites-enbled and sites-available. The sites-enabled directory will contain a default nginx configuration under the name nginx.conf. This folder shall contain nginx configurations for all the applications to be active. If you want a certain configuration to exist but not be active, then you can move its file to sites-available directory.
  5. Create a new .conf file with a name of your choice, preferably your application's name in the sites-enabled directory.
  6. Write the following server configuration into the file. Here, frontend on port 3000 and backend on port 8000 are collectively being listened on port 4000. You can keep this port of your choice.

    server {
        listen       4000;
    
        client_max_body_size 100M;  
        location / {
        proxy_pass http://localhost:3000; 
        }
        location /api/ {
            proxy_pass http://localhost:8000;
        }
        location /media/ {
            alias path/to/backend_application/.media/;
        }
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
    include servers/*;
    
  7. Now reload the nginx server.

  8. Finally, build and serve both frontend and backend applications, and check them out on https://localhost:4000/.