[GH-ISSUE #5848] Feature Request: Allow multiple proxy clusters to serve services under a single shared custom domain #11185

Open
opened 2026-08-05 01:28:49 -04:00 by saavagebueno · 7 comments
Owner

Originally created by @GEAR-IT-UP on GitHub (Apr 10, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5848

Is your feature request related to a problem? Please describe.

When running NetBird proxy instances across multiple physical locations, a custom domain can only be assigned to a single proxy cluster. Attempting to register the same domain against a second cluster returns a 500 error. This means services on different location clusters are forced onto two-level subdomains (e.g. portainer.remote-proxy.domain.com) rather than a clean single-level subdomain (portainer.domain.com). More critically, all traffic for that domain routes through whichever location owns it — meaning services hosted at a remote location are forwarded via WireGuard mesh back through the primary location, negating the purpose of running distributed proxy instances.

Describe the solution you'd like

Allow a custom domain to be associated with multiple proxy clusters, with service creation offering a cluster selector per service. Traffic for a given service should exit directly from the selected cluster's physical location, with the service resolvable at a single-level subdomain regardless of which cluster handles it.

Describe alternatives you've considered

  • Per-service CNAMEs pointing directly to a specific cluster domain — DNS routes correctly to the right location, but the browser sends SNI portainer.domain.com while the proxy has the service registered as portainer.remote-proxy.domain.com. These don't match, resulting in a 404.

  • Shared NB_PROXY_DOMAIN across all locations — forms a single cluster but loses per-service location control and still results in a two-level subdomain.

  • Replacing NetBird proxy with standalone reverse proxies per location — defeats the purpose of a single management interface.

Additional context

Management: v0.68.1 / Dashboard: v2.36.0

Self-hosted, Docker Compose with built-in Traefik

Multiple proxy instances across geographically separate locations, all peered via NetBird WireGuard mesh

Portainer used as an example service — the limitation applies to any service on a non-primary cluster

Has anyone else came across this at all?

Originally created by @GEAR-IT-UP on GitHub (Apr 10, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5848 **Is your feature request related to a problem? Please describe.** When running NetBird proxy instances across multiple physical locations, a custom domain can only be assigned to a single proxy cluster. Attempting to register the same domain against a second cluster returns a 500 error. This means services on different location clusters are forced onto two-level subdomains (e.g. portainer.remote-proxy.domain.com) rather than a clean single-level subdomain (portainer.domain.com). More critically, all traffic for that domain routes through whichever location owns it — meaning services hosted at a remote location are forwarded via WireGuard mesh back through the primary location, negating the purpose of running distributed proxy instances. **Describe the solution you'd like** Allow a custom domain to be associated with multiple proxy clusters, with service creation offering a cluster selector per service. Traffic for a given service should exit directly from the selected cluster's physical location, with the service resolvable at a single-level subdomain regardless of which cluster handles it. **Describe alternatives you've considered** - Per-service CNAMEs pointing directly to a specific cluster domain — DNS routes correctly to the right location, but the browser sends SNI portainer.domain.com while the proxy has the service registered as portainer.remote-proxy.domain.com. These don't match, resulting in a 404. - Shared NB_PROXY_DOMAIN across all locations — forms a single cluster but loses per-service location control and still results in a two-level subdomain. - Replacing NetBird proxy with standalone reverse proxies per location — defeats the purpose of a single management interface. **Additional context** Management: v0.68.1 / Dashboard: v2.36.0 Self-hosted, Docker Compose with built-in Traefik Multiple proxy instances across geographically separate locations, all peered via NetBird WireGuard mesh Portainer used as an example service — the limitation applies to any service on a non-primary cluster Has anyone else came across this at all?
saavagebueno added the feature-request label 2026-08-05 01:28:49 -04:00
Author
Owner

@SuperKali commented on GitHub (May 12, 2026):

+1, same need on a self-hosted multi-cluster deployment.

Concrete setup: 3 connected reverse-proxy clusters on different providers (Netcup x86 / Netcup ARM64 / Oracle Cloud) under shared parent custom domains. The pain is that the dashboard binds every service under a parent to the parent's target_cluster, so we cannot split services between clusters from the UI even when the cost / bandwidth profile of one cluster (e.g. Oracle Free egress cap) is fundamentally different from the others.

What makes this surprising: the data model already supports it. In the management SQLite store, services.proxy_cluster and domains.target_cluster are independent columns with no FK / CHECK constraint. We verified empirically that setting services.proxy_cluster to a value different from the parent's target_cluster is persisted across management restarts and that traffic flows correctly — each cluster serves its assigned services from its own egress, no central hop.

Workaround currently in use: direct UPDATE services SET proxy_cluster = '<cluster>' WHERE id = '...' against the SQLite store, then docker compose restart netbird-server. Reliable but requires shell + SQL access on the management host, so not viable for users who manage NetBird through the dashboard alone.

Minimal UI change that would unblock this: a "Proxy cluster" dropdown on the service create/edit form, prefilled with the parent's target_cluster but overridable per service, populated from the proxies table (clusters with at least one currently-connected proxy). The reverse-proxy binary already supports running independently of the parent zone — on all our clusters require_subdomain=0 is the default — so no backend / data-model changes seem required, only the UI gate.

<!-- gh-comment-id:4429727928 --> @SuperKali commented on GitHub (May 12, 2026): +1, same need on a self-hosted multi-cluster deployment. Concrete setup: 3 connected reverse-proxy clusters on different providers (Netcup x86 / Netcup ARM64 / Oracle Cloud) under shared parent custom domains. The pain is that the dashboard binds every service under a parent to the parent's `target_cluster`, so we cannot split services between clusters from the UI even when the cost / bandwidth profile of one cluster (e.g. Oracle Free egress cap) is fundamentally different from the others. What makes this surprising: the data model already supports it. In the management SQLite store, `services.proxy_cluster` and `domains.target_cluster` are independent columns with no FK / CHECK constraint. We verified empirically that setting `services.proxy_cluster` to a value different from the parent's `target_cluster` is persisted across management restarts and that traffic flows correctly — each cluster serves its assigned services from its own egress, no central hop. Workaround currently in use: direct `UPDATE services SET proxy_cluster = '<cluster>' WHERE id = '...'` against the SQLite store, then `docker compose restart netbird-server`. Reliable but requires shell + SQL access on the management host, so not viable for users who manage NetBird through the dashboard alone. Minimal UI change that would unblock this: a "Proxy cluster" dropdown on the service create/edit form, prefilled with the parent's `target_cluster` but overridable per service, populated from the `proxies` table (clusters with at least one currently-connected proxy). The reverse-proxy binary already supports running independently of the parent zone — on all our clusters `require_subdomain=0` is the default — so no backend / data-model changes seem required, only the UI gate.
Author
Owner

@GEAR-IT-UP commented on GitHub (May 12, 2026):

That is pretty good to hear thanks!

So what is needed, is a UI based pull request that allows updates of these entries, makes sense. Hopefully someone from.the netbird team, can have a good at adding this!

<!-- gh-comment-id:4429889759 --> @GEAR-IT-UP commented on GitHub (May 12, 2026): That is pretty good to hear thanks! So what is needed, is a UI based pull request that allows updates of these entries, makes sense. Hopefully someone from.the netbird team, can have a good at adding this!
Author
Owner

@GEAR-IT-UP commented on GitHub (May 14, 2026):

+1, same need on a self-hosted multi-cluster deployment.

Concrete setup: 3 connected reverse-proxy clusters on different providers (Netcup x86 / Netcup ARM64 / Oracle Cloud) under shared parent custom domains. The pain is that the dashboard binds every service under a parent to the parent's target_cluster, so we cannot split services between clusters from the UI even when the cost / bandwidth profile of one cluster (e.g. Oracle Free egress cap) is fundamentally different from the others.

What makes this surprising: the data model already supports it. In the management SQLite store, services.proxy_cluster and domains.target_cluster are independent columns with no FK / CHECK constraint. We verified empirically that setting services.proxy_cluster to a value different from the parent's target_cluster is persisted across management restarts and that traffic flows correctly — each cluster serves its assigned services from its own egress, no central hop.

Workaround currently in use: direct UPDATE services SET proxy_cluster = '<cluster>' WHERE id = '...' against the SQLite store, then docker compose restart netbird-server. Reliable but requires shell + SQL access on the management host, so not viable for users who manage NetBird through the dashboard alone.

Minimal UI change that would unblock this: a "Proxy cluster" dropdown on the service create/edit form, prefilled with the parent's target_cluster but overridable per service, populated from the proxies table (clusters with at least one currently-connected proxy). The reverse-proxy binary already supports running independently of the parent zone — on all our clusters require_subdomain=0 is the default — so no backend / data-model changes seem required, only the UI gate.

I see from the latest release, bring your own proxy, I guess fixes this as we would just run nginx etc on each site, then "add it" to netbird and it would control it. That way it gets around DNS-01 issues (as they support it unlike netbird directly) and it would also allow basic A records to be used instead of the CNAME stuff that netbird normally uses. what do you think>

<!-- gh-comment-id:4455685213 --> @GEAR-IT-UP commented on GitHub (May 14, 2026): > +1, same need on a self-hosted multi-cluster deployment. > > Concrete setup: 3 connected reverse-proxy clusters on different providers (Netcup x86 / Netcup ARM64 / Oracle Cloud) under shared parent custom domains. The pain is that the dashboard binds every service under a parent to the parent's `target_cluster`, so we cannot split services between clusters from the UI even when the cost / bandwidth profile of one cluster (e.g. Oracle Free egress cap) is fundamentally different from the others. > > What makes this surprising: the data model already supports it. In the management SQLite store, `services.proxy_cluster` and `domains.target_cluster` are independent columns with no FK / CHECK constraint. We verified empirically that setting `services.proxy_cluster` to a value different from the parent's `target_cluster` is persisted across management restarts and that traffic flows correctly — each cluster serves its assigned services from its own egress, no central hop. > > Workaround currently in use: direct `UPDATE services SET proxy_cluster = '<cluster>' WHERE id = '...'` against the SQLite store, then `docker compose restart netbird-server`. Reliable but requires shell + SQL access on the management host, so not viable for users who manage NetBird through the dashboard alone. > > Minimal UI change that would unblock this: a "Proxy cluster" dropdown on the service create/edit form, prefilled with the parent's `target_cluster` but overridable per service, populated from the `proxies` table (clusters with at least one currently-connected proxy). The reverse-proxy binary already supports running independently of the parent zone — on all our clusters `require_subdomain=0` is the default — so no backend / data-model changes seem required, only the UI gate. I see from the latest release, bring your own proxy, I guess fixes this as we would just run nginx etc on each site, then "add it" to netbird and it would control it. That way it gets around DNS-01 issues (as they support it unlike netbird directly) and it would also allow basic A records to be used instead of the CNAME stuff that netbird normally uses. what do you think>
Author
Owner

@Veeau commented on GitHub (May 27, 2026):

+1 for me also. I have self hosted items in 2 different countries.

<!-- gh-comment-id:4555260573 --> @Veeau commented on GitHub (May 27, 2026): +1 for me also. I have self hosted items in 2 different countries.
Author
Owner

@GEAR-IT-UP commented on GitHub (May 27, 2026):

+1 for me also. I have self hosted items in 2 different countries.

The new in the works feature (bring your own proxy) in the latest release notes, should fix this i think. Here is hoping 🙏

<!-- gh-comment-id:4557437570 --> @GEAR-IT-UP commented on GitHub (May 27, 2026): > +1 for me also. I have self hosted items in 2 different countries. The new in the works feature (bring your own proxy) in the latest release notes, should fix this i think. Here is hoping 🙏
Author
Owner

@Technerd-SG commented on GitHub (Jun 8, 2026):

I also had an Idea:
If the cluster came bundled with a DNS server then this would be much easier to solve (I think).
If you have three locations you host 3 x "the cluster".
In your domain settings you change the default name servers to a selection of your clusters (we have 3 so we add all 3 ip's as first, second and third nameserver).
This also solves the availability problems if one cluster is offline that the other one can still resolve DNS requests.
Certificate requests would also be much easier because there is only one DNS service and we control it.
So the DNS challenge should be no problem.
And of course then selecting which cluster should be used is a breeze because the NetBird can manage that for us.

<!-- gh-comment-id:4652966742 --> @Technerd-SG commented on GitHub (Jun 8, 2026): I also had an Idea: If the cluster came bundled with a DNS server then this would be much easier to solve (I think). If you have three locations you host 3 x "the cluster". In your domain settings you change the default name servers to a selection of your clusters (we have 3 so we add all 3 ip's as first, second and third nameserver). This also solves the availability problems if one cluster is offline that the other one can still resolve DNS requests. Certificate requests would also be much easier because there is only one DNS service and we control it. So the DNS challenge should be no problem. And of course then selecting which cluster should be used is a breeze because the NetBird can manage that for us.
Author
Owner

@GEAR-IT-UP commented on GitHub (Jun 8, 2026):

I also had an Idea:
If the cluster came bundled with a DNS server then this would be much easier to solve (I think).
If you have three locations you host 3 x "the cluster".
In your domain settings you change the default name servers to a selection of your clusters (we have 3 so we add all 3 ip's as first, second and third nameserver).
This also solves the availability problems if one cluster is offline that the other one can still resolve DNS requests.
Certificate requests would also be much easier because there is only one DNS service and we control it.
So the DNS challenge should be no problem.
And of course then selecting which cluster should be used is a breeze because the NetBird can manage that for us.

Yeah that would be a good idea. Otherwise roundrobin/cloudflare load balancer would be whats needed to do that process which would be worse... maybe a dev can see this and see if its viable

<!-- gh-comment-id:4653090107 --> @GEAR-IT-UP commented on GitHub (Jun 8, 2026): > I also had an Idea: > If the cluster came bundled with a DNS server then this would be much easier to solve (I think). > If you have three locations you host 3 x "the cluster". > In your domain settings you change the default name servers to a selection of your clusters (we have 3 so we add all 3 ip's as first, second and third nameserver). > This also solves the availability problems if one cluster is offline that the other one can still resolve DNS requests. > Certificate requests would also be much easier because there is only one DNS service and we control it. > So the DNS challenge should be no problem. > And of course then selecting which cluster should be used is a breeze because the NetBird can manage that for us. Yeah that would be a good idea. Otherwise roundrobin/cloudflare load balancer would be whats needed to do that process which would be worse... maybe a dev can see this and see if its viable
Sign in to join this conversation.
No Label feature-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11185