0

I have an Ubuntu server, and I am trying to deploy an express.js/node based Rest API. All the documents I have read say use Nginx as a reverse proxy to get it working so I have attempted that a dozen different ways and I am endlessly getting 502 errors. Its like anything beyond the root of the domain just doesn't want to load and throws a 502.

As you can imagine with any Restful API you have GET, PUT, POST, DELETE, etc.. with dynamic URLs. Example I might have a URL for verifying a user exist http://example.com/api/verify-user/johndoe@example.net.

Running this through the proxy and a multitude more API endpoints similar doesn't seem to work no matter how I try to define the proxy, headers, and so on. No matter how many locations I put in, or variants thereof. So I am truly lost, how do I setup a RESTFul API in a production environment with node/express? So its accessible from an App as an example.

My Latest run at the nginx config for the domain is

server {
        listen 80;
        server_name api.example.net;

        location /api/v1/ {
            proxy_pass http://localhost:3030;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_buffering off;
        }
}

and my server.js from express looks like this currently

const express       = require('express');
const bodyParser    = require('body-parser');
const cors          = require('cors');
const dotenv        = require('dotenv');
const route         = require('./routes');
const path          = require('path');
const livereload    = require("livereload");
const compression   = require("compression");

const liveReloadServer = livereload.createServer();
liveReloadServer.watch(path.join(__dirname, 'public'));


dotenv.config();
const PORT = process.env.PORT;
const app = express();

// parse requests of content-type: application/json
app.use(bodyParser.json());

// parse requests of content-type: application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));

const whitelist = ['http://localhost:3030',
                      'http://api.example.net'];

// enable CORS
const corsOptionsDelegate = (req, callback) => {
  let corsOptions;

  let isDomainAllowed = whitelist.indexOf(req.header('Origin')) !== -1;
  //let isExtensionAllowed = req.path.endsWith('.jpg');

  if (isDomainAllowed) {
      // Enable CORS for this request
      corsOptions = { origin: true }
  } else {
      // Disable CORS for this request
      corsOptions = { origin: false }
  }
  callback(null, corsOptions)
}

app.use(cors(corsOptionsDelegate));

//Compress all routes
app.use(compression());
// enable some server side assets to render when/if needed
app.use(express.static('static'));

// routes
app.use(route);


// set port, listen for requests
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}.`);
});

Mind you I intentionally changed the domain here for the sake of example. But So far I can tell you I can verify the proxy does work on the remote machine if I curl to it and test it. To see if at the least the one static html page works. This in my local environment all works perfectly fine. It wasn't until I introduced Nginx on the remote machine that this started failing for me.

My main question is, is something like Nginx needed to put Node up in a production environment if it is, how to I get it to work with things like dynamic user generated data/urls?

chris
  • 167
  • 1
  • 9
  • My best guess would be that the whitelist const needs to be `127.0.0.1`. Have you tried that? In general I would check the error log of express.js as a first step. I believe it is a good practice to put Nginx in front of express.js for TLS termination and stuff like that. – Henrik Pingel Feb 09 '21 at 12:09
  • Check the nginx error log. – Michael Hampton Feb 09 '21 at 14:41

0 Answers0