sebastiandaschner blog


Using Nginx as Browsersync proxy

#productivity #frontend #docker wednesday, february 09, 2022

For frontend development, Browsersync is a helpful tool that reduces the turnaround time to a minimum while coding. While serving local files and listening to changes it can also proxy your backend URL and forward requests, which, however, doesn’t work in all scenarios. If you have cases in which Browsersync’s proxying functionalities aren’t sufficient, you can use a small Nginx docker instance that proxies both Browsersync and your backend(s).

The reasons why I look into a solution like were that a) Browsersync doesn’t seem to support to proxy server-sent events, and b) after some recent update, Browsersync’s proxy mechanism stopped working and didn’t forward the backend calls anymore. In the video, I’m describing the rational and how to use Nginx as a remedy.

 

 

How the setup looks like that there is a frontend project, which might or might not get packaged into the backend project during deployment, and which is served locally with Browsersync via localhost:3001. Additionally, the backend is running as well (port 8080) and the Nginx instance (port 3000) serves as the entry point and proxies both processes. By doing this, we can navigate our browser to localhost:3000 and get the best of both worlds, being able to control which proxy settings are required to serve our API requests, potential server-sent events or Websocket connections correctly, and also see the frontend updates quickly.

nginx browser sync proxy

You can setup the Nginx proxy quite quickly, with the following nginx.conf:

worker_processes    4;

events {}

http {
    # for Websocket
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    server {
        listen          3000;

        # this regex controls what goes to Browsersync, define your static files here
        location ~ (\.html|\.css|\.js|/images/|^/$)  {
            proxy_set_header        Host $host;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_pass              http://127.0.0.1:3001$request_uri;
        }

        # Browsersync Websocket
        location ~ /browser-sync/  {
            proxy_pass              http://127.0.0.1:3001$request_uri;
            proxy_http_version      1.1;
            proxy_set_header        Upgrade $http_upgrade;
            proxy_set_header        Connection $connection_upgrade;
            proxy_set_header        Host $host;
        }

        # this proxies your backend
        # for all remaining requests, or you can change the location as well
        location / {
            proxy_set_header        Host $host;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_pass              http://127.0.0.1:8080$request_uri;
        }

    }

}

You start the Nginx container and Browsersync with the following script that can reside in your frontend project:

#!/bin/bash
set -euo pipefail
cd ${0%/*}

trap cleanup EXIT

# stop container on script exit
function cleanup() {
  echo "shutting down"
  docker stop nginx-proxy &> /dev/null || true
}

# start Nginx with our config, use host network
docker run --rm \
  --name nginx-proxy \
  --network host \
  -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf \
  nginx:1.13.6 &

# open browser pointing to our proxy url
chromium 'http://localhost:3000/' &> /dev/null &

# serve and watch our frontend directories test/ src/
browser-sync 'test' 'src' --port 3001 --no-open -w

 

Found the post useful? Subscribe to my newsletter for more free content, tips and tricks on IT & Java: