Skip to content

Deploy Proxy in HA

The deployment administrator enrolls each Proxy separately, connects private Proxy peers and publishes ready instances through a common L4 entry point. Clients and Connectors can then reach different Proxies while resource opens use local tunnels or one verified peer hop.

This procedure works with one Authority, HA Authority reached individually, or HA Authority behind an L4 LB. Select the Authority destinations first. Multiple Proxies do not require Authority bootstrap when the deployment has only one Authority.

Before you start

Input Check / value Reference
Ready Authority and administrative identity authority keys status; authority nodes list using its configuration Authority HA, administration
Public entry Example IP 203.0.113.10; raw TCP LB managed by the network administrator Certificates
Proxy nodes A 192.0.2.10, B 192.0.2.11; individual private peer 50065 Peering fields
Role inputs Same OIDC issuer and client, security profile and Authority trust; separate enrollment tokens and identity directories Enrollment
Connector route Example tunneled, IP-only registration relay 50064 Join relay
Connector capacity connector.proxy_connection_count = 2 or greater for redundant verified tunnels; enrolled nodes support peer opens with one tunnel too Connector configuration

Linux commands run in a root shell. Container deployments use the same configuration and gdsgate commands through their platform launcher; see the Authority LB topology, Compose tab and container guide. Keep each Proxy's identity directory durable and private. Do not copy another Proxy's identity, even when both roles run on the same host.

Configure each Proxy

A Proxy created by the first PostgreSQL pair already has its own peer listener and address. Keep its identity and proceed to LB configuration. Add every other Proxy with a separate role permission.

On an admitted Authority with its administrative identity:

(umask 077; gdsgate authority tokens create --role proxy > proxy.token)

Transfer the permission through the protected operator channel. On the new Proxy host in a root shell:

PUBLIC_ENTRY=203.0.113.10
NODE_IP=192.0.2.11
CA_FINGERPRINT='<approved SHA-256 fingerprint>'
gdsgate join "$PUBLIC_ENTRY" --role proxy --listen "$NODE_IP" \
  --fingerprint "$CA_FINGERPRINT" --start < proxy.token
rm proxy.token

The public entry, registration route, OIDC policy, security minimum and current Authority membership come from the verified bundle. Default local listeners are 50061–50065 on the selected individual address. Authority membership refresh is enabled; adding a member does not require editing every existing Proxy. Each Proxy has its own Registry UUID, certificate and private state.

For Authority and Proxy on this host, issue --role pair and run join --role pair. For the first Proxy beside an already configured Authority, use setup prepare --role proxy with that Authority's endpoint and trust; setup reference.

For a DNS entry with an operator-owned public certificate, provide this Proxy's certificate and key in a local template before join:

[proxy]
public_cert_file = "/etc/gdsgate/tls/fullchain.pem"
public_key_file = "/etc/gdsgate/tls/privkey.pem"

Add --local-config /etc/gdsgate/local-proxy.toml to the join command. The certificate must match the accepted public entry. IP-only deployments need no operator public certificate and receive the cluster transport trust through verified discovery. No CA file is transferred manually.

Start and check

--start installs and starts the native service after saving configuration and identity. For containers, omit it and start gdsgate proxy through the supervisor. Default configuration is the platform proxy.toml; state is the platform proxy/ directory. Explicit paths and NAT peer addresses remain overrides.

gdsgate --config /etc/gdsgate/proxy.toml doctor
curl --fail --silent http://127.0.0.1:9091/readyz

A repeated join --if-missing --start checks the saved identity, spends no new permission and starts an existing stopped service. Preserve the private state when upgrading. --start does not restart an already running service.

Configure the public L4 LB

The network administrator permits LB-to-Proxy listener connections, Proxy-to-Proxy 50065, Proxy-to-Authority control and registration, and health checks. Public clients must not reach peer or health listeners.

Public listener Backends Purpose
203.0.113.10:50061 A/B 50061 Client API
203.0.113.10:50062 A/B 50062 Connector tunnels
203.0.113.10:50063 A/B 50063 WebSocket fallback
203.0.113.10:50064 A/B 50064 IP-only registration and renewal relay

Use raw TCP passthrough, without TLS termination. Admit each backend only when its private 9091/readyz returns HTTP 200 ready; withdraw failed or draining instances. Do not pin tunnel connections by source IP: a Connector needs tunnels to distinct Proxies.

The IP templates accept no PROXY headers. If source-IP policy requires the original address, configure the public 50061 frontend to send PROXY v2 and set proxy.public_proxy_protocol_from to the actual LB addresses. Configure both ends together. Keep tunnel, WebSocket and registration relay listeners without PROXY headers. Without preservation, source-IP checks see the LB address. Exact contract: public listener behind a front.

With DNS and a public certificate, registration can use public_join on 50061; configure the same mode and advertised renewal entry on every Authority. Certificate and entry-port choices are independent of Authority HA routing.

Connect resources and verify

The deployment owner registers a Connector at the selected public entry, sets connector.proxy_connection_count = 2 before start, and declares and serves an allowed and a denied resource. IP-only registration uses https://203.0.113.10:50064 with the recorded CA fingerprint. Follow the HA Connector steps using these entry values.

Check Expected Recovery
authority nodes list Two active Proxy rows with distinct UUIDs Check separate tokens and identity directories
doctor on each Proxy No failed trust, Authority route or state checks Correct the named check before enabling the backend
Connector doctor Desired 2 and connected 2 distinct Proxies Check tunnel LB affinity, reachable advertised ports and backend readiness
Client login and allowed native operation through the LB Catalog and access succeed Check OIDC, Connector serving and private peer reachability
Stop Proxy A; open another native connection New access succeeds through B Check LB withdrawal and surviving Connector tunnels
Client and Connector reach different Proxies Resource opens through a local tunnel or one verified peer hop Check 50065, separate enrolled peer identities and Connector connection count
Public workstation tries peer 50065 or health 9091 Network refusal Correct network exposure

Restore A before repeating the failure test for B. Existing streams owned by a stopped Proxy end; they are not transferred. Complete deployment acceptance, including denied access, backend isolation and audit verification.

Drain, preserve state and recover

Withdraw one Proxy from the LB, wait for measured LB propagation, then stop or recreate it. Preserve that instance's identity directory. Re-admit it only after readiness and a new access check. A lost identity requires revoking its old node UUID and enrolling a new identity with a new token.

Use change planning and the Compose drain example. Availability of the store, Authorities and the public LB remains a separate boundary; test the selected composition.

Diagnose deployment errors

Symptom Check Fix
login uses the development issuer Public profile on every Authority/Proxy and the selected saved client config Follow profile distribution, restart changed server roles, refresh the intended client config through verified connect, then sign in again
Login succeeds, later RPC returns invalid identity token Issuer, client audience, validation and groups on every Authority; selected client config Align all instances and refresh the client configuration; successful login only proves the IdP accepted it
Authority leader discovery failed Shared DB connection, leader lease, individual Authority peers and control fallback lists Restore the store or the named route; verify policy pull and a new allowed native operation
Join relay port does not listen endpoints.proxy_join in every Proxy and Authority advertisements Enable the same relay mode on all roles, restart changed roles, then check the public LB frontend
Registration UnknownIssuer Registration endpoint, CA and transport_sni Use the cluster CA and enroll.gdsgate.internal for private registration; see trust checks
Service cannot change working directory namei -l /var/lib/gdsgate/proxy and unit WorkingDirectory Rerun service install proxy with this config; verify shared parent 0755 and preserve private role permissions

Runtime readiness

Proxy /readyz checks all configured Authority endpoints concurrently using its current transport identity. At least one must confirm write leadership with a working store and live lease. A stalled first endpoint does not hide a healthy failover. Dependency failure returns HTTP 503; recovery restores HTTP 200 without a Proxy restart. Use this endpoint for LB health checks. /healthz reports process liveness independently.