# Custom domains for dashboard endpoint

**URL:** https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988
**Category:** General
**Created:** [6 June 2023 10:36 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988 "2023-06-06T10:36:46Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)
#### Post date: [6 June 2023 10:36 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988/1 "2023-06-06T10:36:46Z")

</div>

Hi There!

A thought occurred to me and I was wondering whether its possible - can I configure Node-RED to server the dashboard on a custom domain?

For example [https://demo.openmindmap.org/ui](https://demo.openmindmap.org/ui) becomes [https://website.openmindmap.org](https://website.openmindmap.org) without having an apache or nginx doing the redirects/rewrites. In my case, the domain [demo.openmindmap.org](http://demo.openmindmap.org) is hosted on Heroku where I can only specify the custom domains that go directly to Node-RED. But I can setup multiple domains on Heroku so that Node-RED would need to know that `website.` goes to `/ui`, i.e. it would need to do the routing.

The use-case here would be create blogs or demo-pages for designers or whatever in Node-RED and then have an endpoint that would exclusively show the dashboard.

I hope that this isn't a repetition of someone elses question!

Cheers!

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [6 June 2023 13:21 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988/2 "2023-06-06T13:21:30Z")

</div>

> [@gregorius](#):
>
> can I configure Node-RED to server the dashboard on a custom domain?

Certainly. Lots of people are doing that.

> [@gregorius](#):
>
> without having an apache or nginx doing the redirects/rewrites

The external domain name maps to an external IP address using DNS. This has nothing to do directly with the use of a web proxy service or not.

There are, however, lots of benefits for adding a proxy to the stack. Including performance, security and flexibility as well as giving a better user experience.

> [@gregorius](#):
>
> The use-case here would be create blogs or demo-pages for designers or whatever in Node-RED and then have an endpoint that would exclusively show the dashboard.

Well, Node-RED has a number of ways of delivering web pages of course. Not only UI but also http-in/-out pairings and uibuilder to mention a few. Speaking of uibuilder, I've previously done some proof of concept work around using it to create a content management system. There are lots of ways to achieve these outcomes just with Node-RED.

---

<div class="post-metadata">

### Author: ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)
#### Post date: [6 June 2023 13:53 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988/3 "2023-06-06T13:53:29Z")

</div>

> [@TotallyInformation](#):
>
> Certainly. Lots of people are doing that.

Me too!

But perhaps I should clarify what I mean. I've got an installation on Heroku which means I do a git push and Node-RED is deployed. At Heroku I can't configure a proxy, all I can do is setup an domain CNAME that points to the Heroku proxy. Sure if I had a bare metal server or AWS stack, then I could setup a proxy but that's not what I want to do.

Heroku is very limited in what one can do - by design so. What I specifically looking is mapping URL paths to domains:

[nodered.example.com](http://nodered.example.com) --\> node-red flow editor  
[dashboard.example.com](http://dashboard.example.com) --\> node-red dashboard, i.e. the equivalent to [nodered.example.com/ui](http://nodered.example.com/ui)

It's the `/ui` that can't be mapped to the [dashboard.example.com](http://dashboard.example.com) (via Heroku nor my DNS provider). The path part has to be proxied somehow. If the stack is just Node-RED running on an Heroku instance, then there is no room for a proxy (unless I setup an nginx/apache to run on Heroku and then do magic redirects).

Sure I could use a HTTP-in node to simulate that however then I can't use the dashboard components that _assume_ they are reachable via `/ui` (or whatever is set in the settings.js). Alternatively is there a way to hook up the dashboard components to point to an http-out node to send back their content?

Turning the question around: is there a way to specify a domain for the dashboard within Node-RED? I.e. does the NR webserver do domain mapping to routes? It does some mapping, mapping `/ui` to the dashboard component. In the `settings.js` I can change the dashboard path but can I set it to a domain without a path?

I.e.:

```auto
  settings.ui = {
        path: "/",
        host: "dashboard.example.com"
  };

```

is what I'm looking for ... I'ven't tried it but it probably works 🙂

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [6 June 2023 15:09 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988/4 "2023-06-06T15:09:35Z")

</div>

> [@gregorius](#):
>
> What I specifically looking is mapping URL paths to domains:

As far as I know, you can only do that at the web server level. DNS takes care of only the domain name to IP address mapping.

> "A CNAME record is used in lieu of an [A record](https://www.cloudflare.com/learning/dns/dns-records/dns-a-record/), when a [domain](https://www.cloudflare.com/learning/dns/glossary/what-is-a-domain-name/) or subdomain is an alias of another domain."

So You can use CNAMEs to map to different Heroku instances or to map different sub-domains to the same instance. But you cannot use them to map to a URI.

However, you could use Node-RED http-in/-out pairs to map from 1 URI to another using a redired (e.g. 301) response. Not very efficient though since you are forcing the browser to load twice and Node-RED to deliver twice.

> [@gregorius](#):
>
> is there a way to specify a domain for the dashboard within Node-RED?

No, for the reverse of the same reason. Domains and URI paths are not actually related. DNS services the former and the web server the latter. (\*)

> [@gregorius](#):
>
> NR webserver do domain mapping to routes?

No, because there are two services required for that outcome.

* * *

(\*) Actually, I suppose I should clarify that a web server that has proxy capabilities CAN re-route based on the source domain that a browser uses to do a request. But Node-RED's ExpressJS web server is not proxy capable itself (as far as I know).

* * *

I also note that it is possible to deploy a proxy to Heroku since there is at least 1 node.js based proxy library. So you could either achieve what you want using 2 Heroku instances or by embedding Node-RED into a custom node.js service that includes the proxy (theoretically - never tried of course).

---

<div class="post-metadata">

### Author: ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)
#### Post date: [6 June 2023 15:52 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988/5 "2023-06-06T15:52:27Z")

</div>

> [@TotallyInformation](#):
>
> (\*) Actually, I suppose I should clarify that a web server that has proxy capabilities CAN re-route based on the source domain that a browser uses to do a request. But Node-RED's ExpressJS web server is not proxy capable itself (as far as I know).

Thats what I wanted to know, so it's not possible with just simply red, node-red of course.

I did some quick ddg'ing and found this:

- [GitHub - expressjs/vhost: virtual domain hosting](https://github.com/expressjs/vhost), which came from
- [javascript - Subdomain (host) based routing in Express - Stack Overflow](https://stackoverflow.com/questions/54791634/subdomain-host-based-routing-in-express)
- Or this [node.js - nodejs domain based routing - Stack Overflow](https://stackoverflow.com/questions/6999073/nodejs-domain-based-routing) which leads to
- [Connect - High quality middleware for node.js](http://www.senchalabs.org/connect/vhost.html)

So there does seem to be a some middleware for doing this. I'm no NodeJS expert but it does seem there are possibilities out there.

The Rails router has this built in using [`constraints`](https://devtut.github.io/rubyonrails/routing.html#constraints) #justsaying 🙂

> [@TotallyInformation](#):
>
> However, you could use Node-RED http-in/-out pairs to map from 1 URI to another using a redired (e.g. 301) response. Not very efficient though since you are forcing the browser to load twice and Node-RED to deliver twice.

Redirects can get messy if the underlying server does not know the domain changes, i.e., checking if domain is X then redirect to /ui but with the same or different domain? Plus I would have to hijack the `/ui` path in Node-RED - which does seem doable AFAIR.

> [@TotallyInformation](#):
>
> I also note that it is possible to deploy a proxy to Heroku since there is at least 1 node.js based proxy library. So you could either achieve what you want using 2 Heroku instances or by embedding Node-RED into a custom node.js service that includes the proxy (theoretically - never tried of course).

Indeed, indeed! Why complicated when simple is simpler! I would tryout some middleware solution (if possible) before wrapping Node-RED in NodeJS proxy blanket.

Thanks for the detailed background info 👍

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [6 June 2023 20:07 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988/6 "2023-06-06T20:07:40Z")

</div>

> [@gregorius](#):
>
> So there does seem to be a some middleware for doing this. I'm no NodeJS expert but it does seem there are possibilities out there.

Well, if you ever decide to try that, maybe it would be an interesting extension to uibuilder 😁

> [@gregorius](#):
>
> Redirects can get messy

Yes, it wasn't really a serious solution.

> [@gregorius](#):
>
> I would tryout some middleware solution (if possible) before wrapping Node-RED in NodeJS proxy blanket.

Seems more sensible, yes.

Good luck and let us know how you get on 🙂

---

<div class="post-metadata">

### Author: ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)
#### Post date: [6 June 2023 20:37 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988/7 "2023-06-06T20:37:42Z")

</div>

I think I might have a solution.

If I set the adminRoot to something like /fubar and the ui path to / (slash) and add a middleware (to the ui setting) that rejects anything that comes from the wrong domain, that should do the trick.

I'll give try and see what happens...

---

<div class="post-metadata">

### Author: ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)
#### Post date: [7 June 2023 08:14 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988/8 "2023-06-07T08:14:27Z")

</div>

Ok that seems to work, I just tested this on my localhost installation, in `settings.js` I did this:

```js
  httpAdminRoot: '/cfg',
  httpAdminMiddleware: [
    (req,res,next) => {
        if ( req.host == "127.0.0.1" ) {
          next();
        } else {
          res.status(404).send("Not Found - " + req.host );
        }
    }
  ],

  / ***somewhere further down*** /

  ui: {
    path: "/",
    middleware: [
      (req, res, next) => {
        if ( req.hostname == "localhost" ) {
          next();
        } else {
          res.status(404).send("Not Found - " + req.hostname );
        }
      }
    ],
    ioMiddleware: [
      /* need to do the same for the socket */
    ]
  },

```

This meant that I had the following:

[http://localhost/cfg](http://localhost/cfg) --\> flow editor  
[http://127.0.0.1/cfg](http://127.0.0.1/cfg) --\> 404 Not Found

[http://localhost/](http://localhost/) --\> 404 Not Found  
[http://127.0.0.1/](http://127.0.0.1/) --\> Dashboard

The next step would be to try this out at Heroku and check whether the domain (and which header with domain) is passed through to the Node-RED endpoint.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [7 June 2023 14:45 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988/9 "2023-06-07T14:45:06Z")

</div>

Looks good.

Just to let you know that you should be able to use the same technique with uibuilder endpoints since it has its own middleware capabilities both for all uibuilder endpoints in settings.js. The next release of uibuilder will also be adding middleware for individual uibuilder node instances as well as a global setting. Also worth noting that uibuilder also has middleware for [Socket.IO](http://Socket.IO) connections as well as ExpressJS.

---

<div class="post-metadata">

### Author: ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)
#### Post date: [8 June 2023 13:34 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988/10 "2023-06-08T13:34:35Z")

</div>

I've tried on heroku and it does work. I have also updated my [heroku node-red base repo](https://github.com/gorenje/node-red-heroku) so that it becomes a matter of just setting an env variable.

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [22 June 2023 13:35 UTC](https://discourse.nodered.org/t/custom-domains-for-dashboard-endpoint/78988/11 "2023-06-22T13:35:11Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
