WebUI Documentation
The GSLB WebUI is a modern Next.js-based dashboard for managing the GSLB system. It provides real-time monitoring and configuration capabilities through an intuitive interface.
Features
Real-time Dashboard: Live overview of all pools and their health status
WebSocket Updates: Instant notifications when members go online/offline
Pool Management: Create, view, and manage pools and their members
Service Configuration: Manage DNS services and their mappings
Health Monitoring: Visual health status with health scores and history
Activity Feed: Live feed of health changes and configuration updates
Architecture
┌─────────────────────────────────────────────────────────────────┐│ WebUI (Next.js) ││ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ ││ │ Dashboard │ │ Pool Mgmt │ │ Member Health View │ ││ │ (Real-time)│ │ (CRUD) │ │ (WebSocket) │ ││ └──────────────┘ └──────────────┘ └──────────────────────┘ │└─────────────────────────────────────────────────────────────────┘ │ │ REST API + WebSocket ▼┌─────────────────────────────────────────────────────────────────┐│ gslbd (Go Backend) ││ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ ││ │ REST API │ │ WebSocket │ │ NATS/JetStream │ ││ │ (18+ ep) │ │ Server │ │ (Real-time bridge) │ ││ └──────────────┘ └──────────────┘ └──────────────────────┘ │└─────────────────────────────────────────────────────────────────┘
InstallationPrerequisites
Go 1.25+
Node.js 18+ and npm
NATS server (optional, for multi-node deployments)
Building the WebUI
cd webuinpm installnpm run build
The build output is placed in webui/out/ (static HTML export). This is the directory to deploy.
Deploying the WebUI
Copy the static export to your desired location:
cp -r webui/out /opt/gslb/webui
Configure gslbd to serve the WebUI:
api: enabled: true listenAddr: "0.0.0.0" port: 8080 webuiPath: "/opt/gslb/webui"
Accessing the WebUI
Once deployed, access the WebUI at:
http://<host>:8080/ui/- WebUI dashboard (redirected from/)http://<host>:8080/api/v1/- REST APIws://<host>:8080/api/v1/ws- WebSocket for real-time updates
ConfigurationEnvironment Variables
The WebUI can be configured via environment variables or defaults to relative URLs:
Variable | Description | Default |
|---|---|---|
| REST API base URL | Same origin |
| WebSocket URL | Same origin with ws:// protocol |
Backend Environment Variables
Variable | Description | Default |
|---|---|---|
| REST API authentication key | Unauthenticated |
| WebSocket JWT signing secret | Value of |
| Cluster identifier for NATS |
|
WebSocket Protocol
The WebSocket connection provides real-time updates. Connect with a JWT token obtained from /api/v1/ws/token.
Connection Example
const response = await fetch('/api/v1/ws/token');const { token } = await response.json();const ws = new WebSocket(`ws://localhost:8080/api/v1/ws?token=${token}`);
Message Types
Type | Description | Payload |
|---|---|---|
| Health status change |
|
| Pool CRUD event |
|
| Member CRUD event |
|
| Full member data |
|
| Service CRUD event |
|
Example Messages
Health Update (member goes offline):
{ "type": "health_update", "payload": { "poolId": "pool-123", "ipAddress": "192.168.1.1", "healthy": false, "score": 0.0, "timestamp": 1234567890000, "rttMs": 0, "node": "node-1" }}
Pool Created:
{ "type": "pool_update", "payload": { "action": "created", "pool": { "id": "pool-456", "name": "web-servers", "createdAt": 1234567890000, "updatedAt": 1234567890000 } }}
Dashboard
The main dashboard provides:
Stats Cards
Total Pools
Total Members
Healthy Percentage
Server Uptime
Pool Health Grid
Each pool shows:
Pool name and ID
Members listed as
label: ip_address(or bare IP if no label is set), sorted by priority ascending then weight descending — the member most likely to receive traffic appears firstGreen/red health indicators per member
Health scores when configured
Real-time status updates via WebSocket
Activity Feed
Shows recent events:
Health status changes
Member additions/removals
Pool modifications
State Management
The WebUI uses Zustand for client-side state management:
// lib/store.tsinterface GSLBState { pools: Pool[]; members: Record<string, Member[]>; services: Service[]; healthStatus: Record<string, Record<string, MemberHealth>>; dashboardStats: DashboardStats | null; // ... actions}
API Integration
REST API calls are handled through a centralized client:
// lib/api.tsexport async function listPools(): Promise<Pool[]>export async function createPool(name: string): Promise<Pool>export async function getPoolStatus(poolId: string): Promise<PoolStatus>export async function getSnapshot(): Promise<SnapshotResponse>export async function getDashboardStats(): Promise<DashboardStats>
DevelopmentRunning the WebUI in Development
cd webuinpm installnpm run dev
The WebUI will be available at http://localhost:3000/ui/ (note the /ui/ path, required by basePath). Configure the API URL:
NEXT_PUBLIC_API_URL=http://localhost:8080 npm run dev
Tech Stack
Framework: Next.js 14+ (App Router)
UI: React 18+, Tailwind CSS
State: Zustand
Data Fetching: TanStack Query (React Query)
Charts: Recharts (optional)
Icons: Lucide React
Project Structure
webui/├── src/│ ├── app/ # Next.js app router pages│ │ ├── layout.tsx # Root layout with sidebar│ │ ├── page.tsx # Dashboard│ │ ├── pools/ # Pool management pages│ │ └── providers.tsx # React Query provider│ ├── components/│ │ ├── dashboard/ # Dashboard components│ │ │ ├── StatsCards.tsx│ │ │ ├── PoolHealthGrid.tsx│ │ │ └── RecentActivity.tsx│ │ ├── layout/│ │ │ └── Sidebar.tsx # Navigation sidebar│ │ └── ui/ # Reusable UI components│ │ ├── LoadingSpinner.tsx│ │ └── ErrorDisplay.tsx│ └── lib/│ ├── api.ts # REST API client│ ├── types.ts # TypeScript definitions│ ├── websocket.ts # WebSocket hook│ └── store.ts # Zustand store├── .env.production # Production environment├── next.config.js├── package.json└── tailwind.config.ts
TroubleshootingWebSocket Connection Issues
Ensure the server is running with WebSocket support
The WebSocket endpoint (
/api/v1/ws) is auth-exempt in the HTTP middleware; authentication is handled by the JWT token in the query string (?token=<jwt>). If you see 401s on the WS endpoint, confirm you are running a patched build.Check that the JWT token from
/api/v1/ws/tokenis valid and not expired (default TTL: 24 hours)Verify network connectivity between client and server
Check browser console for specific error messages
Authentication Issues
The REST API uses
Authorization: Bearer <token>(HTTP header). The WebSocket endpoint uses?token=<jwt>(query string) — these are different mechanisms; do not mix them.Verify
GSLB_API_KEYand/orGSLB_WS_SECRETare set on the server. IfGSLB_WS_SECRETis unset, it falls back toGSLB_API_KEY. SetGSLB_WS_SECRETexplicitly for production.Ensure the token hasn't expired (default: 24 hours)
Check that the Authorization header is correctly formatted for REST calls
Real-time Updates Not Working
Confirm WebSocket connection is established (check connection indicator in the top-right of the sidebar)
Single-node deployments (no NATS) broadcast health changes directly from the health checker sink — no NATS configuration is required
Multi-node deployments require NATS: verify
state.nats.serversis set and the NATS connection is establishedCheck server logs for WebSocket or health bridge errors
Security Considerations
Always use HTTPS in production
Set a strong
GSLB_API_KEYandGSLB_WS_SECRETConsider firewall rules to restrict API access
JWT tokens expire after 24 hours by default
Audit log all API mutations via
GSLB_AUDIT_LOG