wissel.net

Usability - Productivity - Business - The web - Singapore & Twins

learning how nginx proxy works


A common approach for web applications is to serve them behind a reverse proxy. My favorite there is nginx. It has a fairly understandable configuration, supports http/2 and is fully supported by Letsencrypt's certbot.

proxy_pass can be tricky

The configuration for reverse proxying is a combination of location and a proxy_pass statement, as well as some headers. In it simplest form the URL path and the proxy_path URL are the same, so you don't need a translation between direct access (e.g. local testing) and access through nginx. A configuration could look like this:

location /someurl {
        proxy_pass http://127.0.0.1:3000/someurl;
        proxy_http_version 1.1;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
    }

The headers ensure your application knows the original request source and allow upgrade from http to websockets.

It gets interesting when location and proxy_pass don't match. Differences can range from different url path to regex and rewrites. Especially when inheriting (or googling) configurations, understanding can be a challenge.

Express to the rescue

A few lines of expressjs will echo back what ends up at the backend. Together with curl it provides you a practical learning and testing environment.

const express = require('express');
const app = express();
const port = 3010;

app.get('*', (req, res) => {
  res.setHeader('Content-Type', 'text/json');
  let result = JSON.stringify(
    {
      headers: req.headers,
      url: req.url,
      query: req.query,
      hostname: req.hostname
    },
    null,
    2
  );
  res.send(result);
  console.log(result);
});

app.listen(port, () => {
  console.log(`Echo app listening for GET on port ${port}`);
});

Enjoy, as usual YMMV!


Posted by on 09 January 2023 | Comments (0) | categories: nginx WebDevelopment

Comments

  1. No comments yet, be the first to comment