Getting 404 with NodeJS Proxy Server


#1

I’m having a difficult time getting just the login page to show up using a proxy server (node-http-proxy). My configuration is similar to other examples I have seen. However, I’m getting the “Grafana has failed to load its application files” error page.

Setup
The proxy server is currently on my local station (computer.company.com). Here’s what my Node script looks like:

app.all('/grafana(/*)?', (req, res) => {
    serverProxy.web(req, res, {
        target: 'http://[grafana-server]:3000'        
    });
});

Grafana Configuration:

[server]
# Protocol (http or https)
protocol = http

# The ip address to bind to, empty will bind to all interfaces
http_addr =

# The http port  to use
http_port = 3000

# The public facing domain name used to access grafana from a browser
domain = computer.company.com

# Redirect to correct domain if host header does not match domain
# Prevents DNS rebinding attacks
enforce_domain = false
    
# The full public facing url
root_url = %(protocol)s://%(domain)s:%(http_port)s/dashboard

The url that I’m going to is http://computer.company.com:3000/dashboard. Like I said, I’m getting the Grafana error page (“If you’re seeing this Grafana has failed to load its application files…”). However, all of the assets showing up as 404 in the Chrome DevTools Network tab.
image

Things I have tried:

  • Changing the domain to just the main domain
  • Hardcoding the root_url
  • Using localhost instead of my domain
  • Restarting both servers after every change

Any thoughts?

Also, while on the topic, can anyone tell me if it’s possible to add multiple domains in the Grafana configuration (think multiple environments)?


#2

I’m just reaching out again to see if anyone else has worked with reverse proxy and have run into this issue. My guess is that Grafana isn’t recognizing the requests from my server. Thoughts?


#3

OK. It looks like there was nothing wrong on the Grafana side. On my proxy, I needed to remove “/dashboard” from the URL for requests sent to Grafana server. For those running into the same issue, here’s the solution I came up with:

const httpProxy = require('http-proxy');
let serverProxy = httpProxy.createProxyServer();

serverProxy.on('proxyReq', function(proxyReq, req, res, options) {

    // Rewrite body to pass POST and PUT requests
    if (req.body) {
        const bodyData = JSON.stringify(req.body);
        // incase if content-type is application/x-www-form-urlencoded -> we need to change to application/json
        proxyReq.setHeader('Content-Type', 'application/json');
        proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
        // stream the content
        proxyReq.write(bodyData);
    }
});


// Send Users to Grafana Server
app.all('/dashboard(/*)?', (req, res) => {
    const urlRegex =  /^\/dashboard/gm;
    req.url = req.url.replace(urlRegex, '');
    serverProxy.web(req, res, {
        target: 'http://[grafana-server]:3000',
        prependPath: false
    });
});