Nexus GSLB is a Linux server product. The supported install is the one-line installer on a Linux VM with systemd — that is the path this guide documents, the path we test every release, and the path we run ourselves.
Container installs exist and work, but they are for evaluation. See Other install methods at the bottom for what they are and when to reach for them.
Why a plain VM
Nexus GSLB is an authoritative DNS server. It wants to own port 53 on a public IP, in each of the two-to-four locations you want to serve traffic from — small VMs in different regions, not one big cluster. Two things follow from that:
Geo-routing reads the client source address. When a resolver does not send EDNS Client Subnet — most public resolvers strip it — Nexus falls back to the address the query arrived from. Anything that NATs or proxies DNS traffic changes that address, and geo-routing quietly degrades: no error, just every client looking like it came from one place.
A cluster per region is the wrong unit. Nexus normally sits above your Kubernetes clusters, steering traffic between them. Running it inside one of them couples the thing doing the steering to the thing being steered.
Requirements
OS | Any systemd Linux (Debian 12 / Ubuntu 22.04+ / Rocky 9 tested) |
Arch | x86_64 (amd64) or arm64 |
RAM | 512 MB minimum, 1 GB comfortable |
Network | A public IP, and UDP+TCP 53 reachable |
Access | root (via |
gslbd needs no runtime dependencies — it is a static binary. The installer also places rqlited, the replicated datastore it stores configuration in.
There are no distributed macOS or Windows builds. Administer a cluster from those platforms over the REST API, or run gslbctl from any Linux host.
Directory layout
Path | Purpose |
|---|---|
| Daemon binary |
| Management CLI |
| Datastore daemon (installed for you) |
| WebUI static files, served by |
| Main configuration |
| License credentials (env overrides) |
| Datastore node/cluster settings |
| Datastore data directory (Raft log + state) |
Install
curl -fsSL https://gslb.nexus/install.sh | sudo bash
The script detects your architecture, downloads the release archive from gslb.nexus, verifies its SHA256 checksum, installs gslbd, gslbctl, rqlited and the WebUI, creates a hardened gslbd system user, and installs both systemd units.
To pin a version, pass it to the shell that actually runs the script — an environment variable in front of curl sets it for curl, not for bash:
curl -fsSL https://gslb.nexus/install.sh | sudo NEXUS_VERSION=v0.3.1 bash
Then configure and start
# 1. Configure. At minimum set dns.domain, dns.nsNames, and your endpoints.sudo nano /etc/gslb/config.yaml # 2. Optional — a paid license. The free tier runs without one.sudo nano /etc/gslb/gslbd.env # GSLB_LICENSE_KEY=<key-from-gslb.nexus> # 3. Start. rqlited comes up first; gslbd requires it.sudo systemctl start gslbdsystemctl status gslbd rqlited # 4. Confirm it answers.curl http://localhost:8080/api/v1/healthdig @127.0.0.1 -p 5353 SOA your-domain.example
gslbd.service declares Requires=/After=rqlited.service, so starting gslbd starts the datastore too.
Create the first admin user
curl -X POST http://localhost:8080/api/v1/auth/setup \ -H 'Content-Type: application/json' \ -d '{"username":"admin","password":"a-strong-password"}'
Reach the WebUI
gslbd serves the WebUI itself, from /opt/gslb/webui, on the same port and origin as the API — there is no reverse proxy, no second service, and nothing else to configure. It is at /ui/.
The shipped config binds the API to 127.0.0.1, so it is not exposed to the internet by default. Reach it over an SSH tunnel:
ssh -L 8080:localhost:8080 you@your-node# then open http://localhost:8080/ui/
That is the right answer for occasional administration and needs no further setup. For a permanent admin endpoint, set api.listenAddr to 0.0.0.0 and put it behind TLS — the API carries session cookies and API keys, so do not expose it on plain HTTP. See docs/user/EncryptedDNS.md and docs/reference/TransportSecurity.md.
Set
GSLB_API_KEYbefore you changelistenAddr.With no
GSLB_API_KEYin the environment, the API runs unauthenticated: every request is treated as a full administrator. That is deliberate — it is what lets you reach a brand-new install and create the first account — and it is safe only because the shipped config binds to127.0.0.1.Binding to
0.0.0.0without setting the key first publishes an admin API that anyone who can route to the host may use, with no credentials: read every record, repoint your traffic, delete pools.gslbdwarns about this on every startup (no GSLB_WS_SECRET or GSLB_API_KEY set), so check the logs if you are unsure which mode you are in.Set it in
/etc/gslb/gslbd.env, then restart:# generate a key and store itecho "GSLB_API_KEY=$(openssl rand -hex 32)" >> /etc/gslb/gslbd.envsystemctl restart gslbdCallers then authenticate with
Authorization: Bearer <key>. The same key also pins the WebSocket JWT secret, so live WebUI sessions survive a restart.
To run without the WebUI, comment out api.webuiPath in /etc/gslb/config.yaml.
Port 53
Handled for you. The shipped config serves DNS on 53, the systemd unit grants CAP_NET_BIND_SERVICE so an unprivileged gslbd can bind it, and — on Ubuntu and other systemd-resolved distributions, where the stub resolver already holds 127.0.0.53:53 — the installer disables that stub listener and repoints /etc/resolv.conf at resolved's upstream list. Name resolution on the host keeps working.
To keep the stub and free port 53 yourself (or run DNS on a high port), install with:
curl -fsSL https://gslb.nexus/install.sh | sudo NEXUS_KEEP_RESOLVED=1 bash
To undo the resolver change:
sudo rm /etc/systemd/resolved.conf.d/10-nexus-gslb.confsudo systemctl restart systemd-resolved
Check what owns the port at any time with sudo ss -ulpn 'sport = :53'.
Go multi-node
One node is a working install; it is not a GSLB. Add nodes in the regions you want to serve from — they form one Raft cluster over a private network and share all configuration.
Full walkthrough: docs/user/ThreeNodeCluster-BareMetal.md.
Upgrade and rollback
Re-run the installer. It backs up the previous binaries to *.bak and replaces the WebUI wholesale, so no stale assets are left behind. Your config, license and datastore are untouched.
curl -fsSL https://gslb.nexus/install.sh | sudo bashsudo systemctl restart gslbd
Rollback:
sudo cp /usr/local/bin/gslbd.bak /usr/local/bin/gslbdsudo cp /usr/local/bin/gslbctl.bak /usr/local/bin/gslbctlsudo systemctl restart gslbd
In a cluster, upgrade one node at a time and confirm it rejoins (gslbctl cluster status) before moving to the next.
Other install methods
Available, not the documented path. Use them to evaluate; use a VM to deploy.
Docker Compose
Single-node evaluation. gslbd, the WebUI and Caddy (automatic HTTPS) as one stack:
VERSION=0.3.1curl -fsSLO "https://gslb.nexus/dl/v${VERSION}/nexus-gslb-compose.tar.gz"tar -xzf nexus-gslb-compose.tar.gz && cd nexus-gslb-compose nano deploy/config.yaml # dns.domain, dns.nsNames, endpointsnano deploy/Caddyfile # replace example.com with your domain export GSLB_API_KEY="$(openssl rand -hex 32)"docker compose -f docker-compose.release.yml up -d
The bundle carries the compose file plus the two files it bind-mounts (deploy/config.yaml, deploy/Caddyfile) in the layout it expects. GSLB_API_KEY is required — without it the stack refuses to start rather than silently running the API unauthenticated.
Before using this in production, check your source addresses. DNS arrives through a published container port, and depending on your Docker daemon's
userland-proxysetting the client addressgslbdsees may be rewritten to the bridge gateway — which silently flattens geo-routing. Verify withgslbctl trace <service-id> --client-ip <a-real-client>and by inspecting query logs for varied source addresses.network_mode: hostavoids the problem.
Kubernetes
For running Nexus inside a cluster you already operate. The manifests (deploy/kubernetes/) cover a 3-replica Raft StatefulSet, the WebUI Deployment, and DNS via a LoadBalancer service. See docs/user/Kubernetes.md.
Note the same source-address caveat: preserve the client IP (externalTrafficPolicy: Local, already set on gslbd-dns) or geo-routing degrades.
DEB and RPM packages
The same contents as the installer, if your fleet management wants a package. There is no apt or yum repository — download and install the file directly:
VERSION=0.3.1 # Debian / Ubuntucurl -fsSLO "https://gslb.nexus/dl/v${VERSION}/nexus-gslb_${VERSION}_linux_amd64.deb"sudo apt install "./nexus-gslb_${VERSION}_linux_amd64.deb" # RHEL / Fedora / Rocky (note: x86_64, not amd64)curl -fsSLO "https://gslb.nexus/dl/v${VERSION}/nexus-gslb-${VERSION}-1.x86_64.rpm"sudo rpm -i "nexus-gslb-${VERSION}-1.x86_64.rpm"
Both bundle rqlited and the WebUI. Upgrades are the same command against a newer file; there is no automatic update.
Manual tarball
If you want to place files yourself. The download path is /dl/v<VERSION>/, but the filenames carry the bare version with no v prefix:
VERSION=0.3.1ARCHIVE="nexus-gslb-${VERSION}-linux-amd64.tar.gz" curl -fsSLO "https://gslb.nexus/dl/v${VERSION}/${ARCHIVE}"curl -fsSLO "https://gslb.nexus/dl/v${VERSION}/nexus-gslb-checksums.txt"grep "$ARCHIVE" nexus-gslb-checksums.txt | sha256sum -c - tar -xzf "$ARCHIVE" && cd "nexus-gslb-${VERSION}-linux-amd64" sudo install -m 755 gslbd gslbctl /usr/local/bin/sudo mkdir -p /opt/gslb/webui /etc/gslbsudo cp -R webui/. /opt/gslb/webui/sudo install -m 640 deploy/config.yaml.example /etc/gslb/config.yamlsudo install -m 644 deploy/gslbd.service deploy/rqlited.service /etc/systemd/system/sudo systemctl daemon-reload
The archive contains gslbd, gslbctl, gslb-probe, the webui/ export, and deploy/ with the systemd units and example config.
rqlited is not in the archive — the installer fetches it from the rqlite project. A hand install must place it too; see docs/reference/Datastore.md. Note that deploy/install.sh inside the archive always downloads a fresh release rather than installing the files next to it, so there is no point running it from here.
Management CLI (gslbctl)
gslbctl manages all resources over the REST API. Configure it with environment variables:
export GSLB_SERVER_URL=https://your.domainexport GSLB_API_KEY=your-api-key gslbctl pools listgslbctl services listgslbctl cluster status
Generate an API key in the WebUI under Settings → API Tokens, or via:
gslbctl users apikey create --name automation
Run gslbctl help for the full command list.
Uninstall
sudo systemctl disable --now gslbd rqlited || truesudo rm -f /etc/systemd/system/gslbd.service /etc/systemd/system/rqlited.servicesudo systemctl daemon-reloadsudo rm -f /usr/local/bin/{gslbd,gslbctl,rqlited,rqlite}sudo rm -rf /opt/gslb /etc/gslb /var/lib/gslbdsudo userdel gslbd || true
/var/lib/gslbd holds all of your configuration — pools, services, members, users. Take a backup first if you may want it back (docs/ops/Runbook.md).
Optional: Apply a license key
Free tier installs are rate-limited. To unlock paid features, obtain a license from gslb.nexus and apply it:
# Preferred: set as environment variable (never stored in config file)echo "GSLB_LICENSE_KEY=your-key" | sudo tee -a /etc/gslb/gslbd.envsudo systemctl restart gslbd
Or apply at runtime via the WebUI: Admin → License → Apply Key.
Optional: Enable DNSSEC (paid)
# /etc/gslb/config.yamldnssec: enabled: true zone: "gslb.example.com." ksk: pemFile: "/etc/gslb/ksk.pem" zsk: pemFile: "/etc/gslb/zsk.pem" signatureValidityDays: 7
See docs/reference/DNSSEC.md for key generation and DS record submission.
Optional: Enable NATS clustering (paid)
# /etc/gslb/config.yamlcluster: id: "prod-cluster"state: nats: servers: - "nats://nats-1.internal:4222" - "nats://nats-2.internal:4222" - "nats://nats-3.internal:4222"
See docs/user/ThreeNodeCluster-BareMetal.md for a full three-node setup walkthrough.