Single-tenant multi-domain Saas with Node

Hi Everyone!

1. The problem I’m having:

Ok, so my issue may be more on the nodejs side than caddy but if someone has any experience with something like this, it would be a huge help.

I’m building a SAAS project where customers can set up their own domain.
It’s a single-tenant project, which means each customer has its own database and codebase.
Each customer has access to a frontend and a backend, which are 2 different node projects.

Everything is dynamic, so I have no idea how to use the reverse_proxy with node.
I mean if I add something manually, it’s easy to use 2 ports per customers (one for frontend and one for backend) and to go like that.
But with a dynamic configuration, I don’t know how to handle node and its ports.

For now, I just use file_server to server an index.html but I need to start using my node project

2. Error messages and/or full log output:

No error as I don’t even know how to start

3. Caddy version:

v2.6.4 h1:2hwYqiRwk1tf3VruhMpLcYTg+11fCdr8S3jhNAdnPy8=

4. How I installed and ran Caddy:

Debian installation

a. System environment:

Debian with systemd

b. Command:

sudo caddy start–config /etc/caddy/Caddyfile

d. My complete Caddy config:

{
  on_demand_tls {
    ask http://localhost:8081
  }
}

http://localhost:8081 {
  root * /home/codi/clients/
  @deny not file /{query.domain}/
  respond @deny 404
}

:443 {
  tls {
    on_demand
  }

  redir /admin /admin/ 308
  route /admin/* {
    uri strip_prefix /admin/
    file_server {
      root /home/codi/clients/{host}/backend
    }
  }
  file_server * {
    root /home/codi/clients/{host}/storefront
  }
  #root /admin/* /home/codi/clients/{host}/backend
  #root * /home/codi/clients/{host}/storefront
  #file_server
}

Thx in advance!

I’m not sure exactly what you’re asking… I think the most specific of a question I can find is:

I don’t know how to handle node and its ports.

I need to start using my node project

Do you mean you need to proxy to your Node app?

reverse_proxy 127.0.0.1:9000

(or whatever address your Node app is listening on)

Hi!

Sorry, English is not my first language and I’m having problems explaining my issue.

Yes, but each customer has their own node app (2 apps per customer to be even more precise).
I don’t think I can use multiple node apps on the same port, so I must also use multiple ports. But everything is dynamic, so I’m unsure how to map my caddy file with a port I don’t know in advance.

Or maybe there is a way to do that differently but I have no idea.

If I had to to it manually it would be something like that

customer1.com {
  reverse_proxy 127.0.0.1:9000
}

customer2.com {
  reverse_proxy 127.0.0.1:9001
}

But it’s dynamic, I don’t know the domains in advance, so I don’t know how to assign a node port for each domain on the node side, and then map it in the caddy file.

Sorry if it’s still unclear

1 Like

You can use a dynamic upstreams module:

This tells the proxy how to get the upstream dynamically at each request.

Currently there’s built-in support for reading upstreams from DNS records (A/AAA and SRV). You’d probably want SRV in your case. If you do that, then this should be a 1-liner for you.

If you want to give that information to Caddy another way (like checking a DB), you’ll have to write your own dynamic upstreams module. (It’s not hard, but you have to use Go.)


Another option (that I like less) is you could have your infrastructure update your Caddy config each time you spin up or down a node backend for a customer.

I will take a look!
Thank you for directing me to this documentation, I hadn’t found it.

By the way, I’m new to Caddy but I think it’s awesome. In just a few lines of config, I have something with dynamic domains and automatic SSL.
It’s impressive so thx you for this project :slight_smile:

1 Like

Hi again,

I was thinking, instead of using dynamic upstream (it’s a little complicated as I don’t have control of the domain names ; and it could be difficult to ask too many DNS changes to the customer).

Could I simply put the port in a txt file in my root and read it?

Something like this:

reverse_proxy http://localhost:{file(“/home/codi/clients/{http.request.host}/port.txt”)}

?
I know I’m asking for weird stuff :slight_smile:

Thx again!

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