Installation

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 sudo)

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

/usr/local/bin/gslbd

Daemon binary

/usr/local/bin/gslbctl

Management CLI

/usr/local/bin/rqlited

Datastore daemon (installed for you)

/opt/gslb/webui

WebUI static files, served by gslbd

/etc/gslb/config.yaml

Main configuration

/etc/gslb/gslbd.env

License credentials (env overrides)

/etc/gslb/rqlited.env

Datastore node/cluster settings

/var/lib/gslbd/rqlite/

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 gslbd
systemctl status gslbd rqlited
 
# 4. Confirm it answers.
curl http://localhost:8080/api/v1/health
dig @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_KEY before you change listenAddr.

With no GSLB_API_KEY in 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 to 127.0.0.1.

Binding to 0.0.0.0 without 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. gslbd warns 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 it
echo "GSLB_API_KEY=$(openssl rand -hex 32)" >> /etc/gslb/gslbd.env
systemctl restart gslbd

Callers 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.conf
sudo 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 bash
sudo systemctl restart gslbd

Rollback:

sudo cp /usr/local/bin/gslbd.bak /usr/local/bin/gslbd
sudo cp /usr/local/bin/gslbctl.bak /usr/local/bin/gslbctl
sudo 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.1
curl -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, endpoints
nano 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-proxy setting the client address gslbd sees may be rewritten to the bridge gateway — which silently flattens geo-routing. Verify with gslbctl trace <service-id> --client-ip <a-real-client> and by inspecting query logs for varied source addresses. network_mode: host avoids 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 / Ubuntu
curl -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.1
ARCHIVE="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/gslb
sudo cp -R webui/. /opt/gslb/webui/
sudo install -m 640 deploy/config.yaml.example /etc/gslb/config.yaml
sudo 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.domain
export GSLB_API_KEY=your-api-key
 
gslbctl pools list
gslbctl services list
gslbctl 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 || true
sudo rm -f /etc/systemd/system/gslbd.service /etc/systemd/system/rqlited.service
sudo systemctl daemon-reload
sudo rm -f /usr/local/bin/{gslbd,gslbctl,rqlited,rqlite}
sudo rm -rf /opt/gslb /etc/gslb /var/lib/gslbd
sudo 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.env
sudo systemctl restart gslbd

Or apply at runtime via the WebUI: Admin → License → Apply Key.


Optional: Enable DNSSEC (paid)

# /etc/gslb/config.yaml
dnssec:
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.yaml
cluster:
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.


Was this article helpful?