Skip to main content

Configuration

This guide covers all configuration options for Nekzus. Configuration can be provided via YAML files, environment variables, or a combination of both.

Configuration File

Nekzus uses YAML configuration files. The default location is configs/config.yaml, but you can specify a custom path using the -config flag:

./nekzus -config /path/to/config.yaml

File Format

Both YAML and JSON formats are supported. The parser automatically detects the format based on file extension:

ExtensionFormat
.yaml, .ymlYAML
.jsonJSON
YAML is Recommended

YAML is the preferred format for its readability and support for comments. All examples in this documentation use YAML.


Configuration Sections

Server

Configure the HTTP server, listening address, and TLS certificates.

config.yaml
server:
# Listen address (host:port or :port)
addr: ":8080"

# Base URL for QR code pairing and external access
# Leave empty for auto-detection of local network IP
base_url: ""

# TLS certificate paths
# Leave empty to run behind a reverse proxy or use -insecure-http flag
tls_cert: ""
tls_key: ""

TLS Options

Leave TLS settings empty when running behind Caddy, nginx, or Traefik:

server:
addr: ":8080"
tls_cert: ""
tls_key: ""
OptionTypeDefaultDescription
addrstring:8443Server listen address
base_urlstringauto-detectBase URL for external access
tls_certstring""Path to TLS certificate
tls_keystring""Path to TLS private key
http_redirect_addrstring""Address for HTTP to HTTPS redirect

Authentication

Configure JWT authentication and token settings.

config.yaml
auth:
# JWT issuer claim
issuer: "nekzus"

# JWT audience claim
audience: "nekzus-mobile"

# JWT signing secret (32+ characters required)
# STRONGLY RECOMMENDED: Use NEKZUS_JWT_SECRET environment variable instead
hs256_secret: ""

# Default scopes applied to routes without explicit scopes
default_scopes: []
JWT Secret Security
  • Must be at least 32 characters
  • Avoid weak patterns like "dev", "test", "example" in production
  • Use environment variable NEKZUS_JWT_SECRET for sensitive deployments
  • If not provided, a secure secret is auto-generated on startup
OptionTypeDefaultDescription
issuerstringnekzusJWT issuer claim
audiencestringnekzus-mobileJWT audience claim
hs256_secretstringauto-generateJWT signing secret (32+ chars)
default_scopes[]string[]Default scopes for routes

Bootstrap Tokens

Configure initial authentication tokens for device pairing.

config.yaml
bootstrap:
# List of valid bootstrap tokens
tokens:
- "your-secure-bootstrap-token"
Bootstrap Token Behavior
  • Tokens are optional; if not provided, devices can pair using the QR code flow
  • Tokens can be added via the NEKZUS_BOOTSTRAP_TOKEN environment variable
  • Multiple tokens are supported for different devices or purposes
OptionTypeDefaultDescription
tokens[]string[]Valid bootstrap tokens

Storage

Configure the SQLite database location.

config.yaml
storage:
# Path to SQLite database file
database_path: "./data/nexus.db"
OptionTypeDefaultDescription
database_pathstring./data/nexus.dbSQLite database file path

Discovery

Configure automatic service discovery from Docker, mDNS, and Kubernetes.

config.yaml
discovery:
enabled: true

# Docker container discovery
docker:
enabled: true
socket_path: "unix:///var/run/docker.sock"
poll_interval: "30s"
network_mode: "all" # all, first, or preferred
networks: [] # Specific networks (for preferred mode)
exclude_networks: [] # Networks to ignore

# mDNS/Bonjour discovery
mdns:
enabled: true
scan_interval: "60s"
services:
- "_http._tcp"
- "_https._tcp"
- "_homeassistant._tcp"

# Kubernetes service discovery
kubernetes:
enabled: false
kubeconfig: "" # Path to kubeconfig (empty for in-cluster)
namespaces: # Namespaces to watch (empty for all)
- "default"
- "apps"
poll_interval: "30s"

Docker Discovery

OptionTypeDefaultDescription
enabledboolfalseEnable Docker discovery
socket_pathstringunix:///var/run/docker.sockDocker socket path
poll_intervalduration30sPoll interval
network_modestringallNetwork selection mode
networks[]string[]Networks to scan (for preferred mode)
exclude_networks[]string[]Networks to exclude

Network Modes:

ModeDescription
allDiscover services on all container networks
firstUse only the first network found
preferredUse networks from the networks list, fallback to first

mDNS Discovery

OptionTypeDefaultDescription
enabledboolfalseEnable mDNS discovery
scan_intervalduration60sScan interval
services[]string["_http._tcp", "_https._tcp"]Service types to discover

Kubernetes Discovery

OptionTypeDefaultDescription
enabledboolfalseEnable Kubernetes discovery
kubeconfigstring""Path to kubeconfig (empty for in-cluster)
namespaces[]string[]Namespaces to watch (empty for all)
poll_intervalduration30sPoll interval
Kubernetes Auto-Discovery

Nekzus uses smart label inference to auto-discover services:

  • Explicit labels: Services with nekzus.enable=true (confidence: 0.95)
  • Ingress-exposed: Services via Kubernetes Ingress (confidence: 1.00)
  • LoadBalancer/NodePort: Services with standard K8s labels (confidence: 0.70)
  • Helm charts: Services with Helm labels (confidence: 0.60)

Toolbox

Configure the one-click service deployment system.

config.yaml
toolbox:
enabled: true

# Directory containing Compose-based service templates
catalog_dir: "./toolbox"

# Directory for persistent service data
data_dir: "./data/toolbox"

# Host path for Docker-in-Docker scenarios
host_data_dir: ""

# Automatically create routes for deployed services
auto_route: true

# Automatically start containers after deployment
auto_start: true
OptionTypeDefaultDescription
enabledbooltrueEnable toolbox feature
catalog_dirstring./toolboxCompose templates directory
data_dirstring./data/toolboxService data directory
host_data_dirstring""Host path for DinD bind mounts
auto_routebooltrueAuto-create routes
auto_startbooltrueAuto-start containers
Deprecated Option

catalog_path (YAML-based catalog) is deprecated. Use catalog_dir for Compose-based templates.


Federation

Configure peer-to-peer federation for multi-instance deployments.

config.yaml
federation:
enabled: false

# Shared secret for peer authentication (32+ characters)
# Generate with: openssl rand -base64 32
cluster_secret: ""

# Gossip protocol port (TCP/UDP)
gossip_port: 7946

# Enable mDNS peer discovery
mdns_enabled: true

# Bootstrap peers for initial cluster formation
bootstrap_peers: []
# - "192.168.1.101:7946"
# - "homelab-server-2:7946"

# Synchronization settings
sync:
full_sync_interval: "300s" # 5 minutes
anti_entropy_period: "60s" # 1 minute

# DANGER: Allow proxying to remote peer services
allow_remote_routes: false
OptionTypeDefaultDescription
enabledboolfalseEnable federation
cluster_secretstring""Shared peer authentication secret
gossip_portint7946Gossip protocol port
mdns_enabledbooltrueEnable mDNS peer discovery
bootstrap_peers[]string[]Initial peer addresses
sync.full_sync_intervalduration300sFull catalog sync interval
sync.anti_entropy_periodduration60sAnti-entropy repair interval
allow_remote_routesboolfalseAllow remote route proxying
Security Warning

Setting allow_remote_routes: true allows proxying to any service discovered by federated peers. Only enable this in trusted network environments.


Runtimes

Configure container runtime settings for management operations.

config.yaml
runtimes:
# Primary runtime: docker or kubernetes
primary: "docker"

# Docker runtime settings
docker:
enabled: true
socket_path: "" # Empty for default

# Kubernetes runtime settings
kubernetes:
enabled: false
kubeconfig: "" # Path to kubeconfig
context: "" # Kubernetes context
namespaces: [] # Namespaces to manage
metrics_server: true # Use Metrics Server for stats
metrics_cache_ttl: "30s" # Cache TTL for metrics
OptionTypeDefaultDescription
primarystringdockerPrimary runtime (docker or kubernetes)
docker.enabledbooltrueEnable Docker runtime
docker.socket_pathstringunix:///var/run/docker.sockDocker socket path
kubernetes.enabledboolfalseEnable Kubernetes runtime
kubernetes.kubeconfigstring""Kubeconfig path
kubernetes.contextstring""Kubernetes context
kubernetes.namespaces[]string[]Namespaces to manage
kubernetes.metrics_serverbooltrueUse Metrics Server
kubernetes.metrics_cache_ttlduration30sMetrics cache TTL

Metrics

Configure Prometheus metrics endpoint.

config.yaml
metrics:
enabled: true
path: "/metrics"
OptionTypeDefaultDescription
enabledbooltrueEnable metrics endpoint
pathstring/metricsMetrics endpoint path
Metrics Collection
  • Metrics are always collected internally for observability
  • This setting only controls the HTTP endpoint exposure
  • The enabled flag can be hot-reloaded without restart
  • The path cannot be changed without restart

Health Checks

Configure service health monitoring.

config.yaml
health_checks:
enabled: true
interval: "30s" # Check frequency
timeout: "5s" # Request timeout
unhealthy_threshold: 3 # Failures before unhealthy
path: "/" # Default health check path

# Per-service overrides
per_service:
grafana:
path: "/api/health"
interval: "30s"
timeout: "5s"
homeassistant:
path: "/api/"
interval: "60s"
OptionTypeDefaultDescription
enabledbooltrueEnable health checks
intervalduration10sDefault check interval
timeoutduration5sDefault request timeout
unhealthy_thresholdint2Consecutive failures threshold
pathstring/Default health check path
per_servicemap{}Per-service configuration overrides

Notifications

Configure WebSocket notification system for mobile devices.

config.yaml
notifications:
enabled: false

# Notification queue settings
queue:
worker_count: 4
buffer_size: 1000
retry_interval: "30s"
max_retries: 3

# Offline device detection
offline_detection:
enabled: false
check_interval: "1m"
offline_threshold: "5m"
OptionTypeDefaultDescription
enabledboolfalseEnable notifications
queue.worker_countint4Worker goroutines
queue.buffer_sizeint1000Channel buffer size
queue.retry_intervalduration30sRetry interval
queue.max_retriesint3Maximum retries
offline_detection.enabledboolfalseEnable offline detection
offline_detection.check_intervalduration1mCheck frequency
offline_detection.offline_thresholdduration5mOffline threshold

Backup

Configure automatic database backups.

config.yaml
backup:
enabled: true
directory: "./data/backups"
schedule: "24h" # Backup interval
retention: 7 # Backups to keep
OptionTypeDefaultDescription
enabledbooltrueEnable automatic backups
directorystring./data/backupsBackup directory
scheduleduration24hBackup interval
retentionint7Number of backups to retain

Scripts

Configure user script execution.

config.yaml
scripts:
enabled: false
directory: "./scripts"
default_timeout: 300 # seconds
max_output_bytes: 10485760 # 10MB
OptionTypeDefaultDescription
enabledboolfalseEnable script execution
directorystring./scriptsScripts directory
default_timeoutint300Default timeout (seconds)
max_output_bytesint10485760Max output size (bytes)

System

Configure system-level settings for host metrics collection.

config.yaml
system:
host_root_path: "/mnt/host" # Mount point for host filesystem
OptionTypeDefaultDescription
host_root_pathstring""Path to mounted host root filesystem for host metrics
Container Deployments

When running in a container, set host_root_path to the mount point of the host filesystem (e.g., /mnt/host) to report accurate host system metrics (CPU, RAM, disk) instead of container metrics.


Routes and Apps

Define static routes and applications.

config.yaml
routes:
- id: "route:grafana"
app_id: "grafana"
path_base: "/apps/grafana/"
to: "http://127.0.0.1:3000"
scopes: ["access:grafana"]
websockets: true
strip_prefix: true

apps:
- id: "grafana"
name: "Grafana"
icon: "chart"
tags: ["monitoring", "dashboards"]
endpoints:
lan: "http://127.0.0.1:3000"

Route Options

OptionTypeDefaultDescription
idstringrequiredUnique route identifier
app_idstringrequiredAssociated app ID
path_basestringrequiredURL path prefix (must start with /)
tostringrequiredUpstream service URL
scopes[]string[]Required authorization scopes
public_accessboolfalseBypass authentication
websocketsboolfalseEnable WebSocket proxying
strip_prefixboolfalseStrip path prefix before proxying
strip_response_cookiesboolfalseRemove Set-Cookie headers
rewrite_cookie_pathsboolfalseRewrite cookie paths
rewrite_htmlboolfalseRewrite HTML for SPA assets
persist_cookiesboolfalsePersist cookies for mobile
health_check_pathstring""Custom health check path
health_check_timeoutduration""Custom health check timeout
health_check_intervalduration""Custom health check interval
expected_status_codes[]int[200-299]Valid health status codes

App Options

OptionTypeDefaultDescription
idstringrequiredUnique app identifier
namestringrequiredDisplay name
iconstring""Icon identifier
tags[]string[]Searchable tags
endpointsmap{}Network-specific endpoints

Environment Variables

Environment variables override configuration file values. Use these for sensitive data and deployment flexibility.

VariableConfig PathDescription
NEKZUS_ADDRserver.addrServer listen address
NEKZUS_BASE_URLserver.base_urlBase URL for external access
NEKZUS_TLS_CERTserver.tls_certTLS certificate path
NEKZUS_TLS_KEYserver.tls_keyTLS private key path
NEKZUS_JWT_SECRETauth.hs256_secretJWT signing secret
NEKZUS_BOOTSTRAP_TOKENbootstrap.tokensBootstrap token (appended to list)
NEKZUS_DATABASE_PATHstorage.database_pathSQLite database path
NEKZUS_TOOLBOX_HOST_DATA_DIRtoolbox.host_data_dirHost data directory for DinD
NEKZUS_HOST_ROOT_PATHsystem.host_root_pathHost root path for metrics
NEKZUS_DISCOVERY_ENABLEDdiscovery.enabledEnable discovery (true/1)
NEKZUS_DISCOVERY_DOCKER_ENABLEDdiscovery.docker.enabledEnable Docker discovery
NEKZUS_TOOLBOX_ENABLEDtoolbox.enabledEnable toolbox
NEKZUS_METRICS_ENABLEDmetrics.enabledEnable metrics endpoint
ENVIRONMENT-Set to production for strict validation

Debug Variables

VariableDescription
NEKZUS_DEBUGEnable debug logging (true/1)
NEKZUS_DEBUG_TOKENSEnable debug token platform (1)
NEKZUS_BOOTSTRAP_ALLOW_ANYAllow any bootstrap token in development (1)
NEKZUS_BOOTSTRAP_ALLOW_ANY

The NEKZUS_BOOTSTRAP_ALLOW_ANY=1 setting only works when ENVIRONMENT=development is explicitly set. Attempting to use it in production results in an error.

Certificate Injection

For Kubernetes and other orchestrated environments:

VariableDefaultDescription
NEKZUS_CA_CERT/certs/ca.crtPath to CA certificate
NEKZUS_CERT/certs/cert.crtPath to service certificate
NEKZUS_KEY/certs/cert.keyPath to service private key
NEKZUS_CERT_DIR/certsCertificate directory
Production Environment Variables
export NEKZUS_JWT_SECRET=$(openssl rand -base64 32)
export NEKZUS_BOOTSTRAP_TOKEN=$(openssl rand -base64 24)
export ENVIRONMENT=production

Hot Reload

Nekzus supports hot reloading for certain configuration changes without restart:

Hot Reloadable:

  • metrics.enabled - Enable/disable metrics endpoint
  • discovery.* - Discovery settings
  • health_checks.* - Health check settings
  • routes and apps - Route and app definitions

Requires Restart:

  • server.addr - Listen address
  • server.tls_* - TLS certificates
  • metrics.path - Metrics endpoint path
  • auth.* - Authentication settings
  • storage.* - Database settings
  • federation.* - Federation settings

To trigger a reload, send a SIGHUP signal:

kill -HUP $(pidof nekzus)

Example Configurations

Minimal Development Setup

config.yaml
server:
addr: ":8080"

discovery:
enabled: true
docker:
enabled: true

Run with:

./nekzus -config config.yaml -insecure-http

Production with TLS

config.yaml
server:
addr: ":8443"
base_url: "https://nekzus.example.com:8443"
tls_cert: "./certs/server-cert.pem"
tls_key: "./certs/server-key.pem"

auth:
issuer: "nekzus"
audience: "nekzus-mobile"
# Use NEKZUS_JWT_SECRET environment variable

storage:
database_path: "./data/nexus.db"

backup:
enabled: true
directory: "./data/backups"
schedule: "12h"
retention: 14

discovery:
enabled: true
docker:
enabled: true
poll_interval: "30s"

metrics:
enabled: true
path: "/metrics"

health_checks:
enabled: true
interval: "30s"
timeout: "5s"
unhealthy_threshold: 3

Docker Compose Deployment

config.yaml
server:
addr: ":8080"

discovery:
enabled: true
docker:
enabled: true
socket_path: "unix:///var/run/docker.sock"

toolbox:
enabled: true
catalog_dir: "./toolbox"
data_dir: "./data/toolbox"
host_data_dir: "/opt/nekzus/data/toolbox" # Host path for volumes
auto_route: true
auto_start: true

Kubernetes Cluster

config.yaml
server:
addr: ":8080"

discovery:
enabled: true
kubernetes:
enabled: true
kubeconfig: "" # Uses in-cluster config
namespaces:
- "default"
- "production"
- "staging"
poll_interval: "30s"

runtimes:
primary: "kubernetes"
kubernetes:
enabled: true
namespaces:
- "default"
- "production"
metrics_server: true

Multi-Instance Federation

config.yaml (Server 1 - Main)
server:
addr: ":8080"

federation:
enabled: true
cluster_secret: "your-32-character-or-longer-secret"
gossip_port: 7946
mdns_enabled: true
bootstrap_peers: [] # Main server, no bootstrap needed
sync:
full_sync_interval: "300s"
anti_entropy_period: "60s"
config.yaml (Server 2 - Secondary)
server:
addr: ":8080"

federation:
enabled: true
cluster_secret: "your-32-character-or-longer-secret"
gossip_port: 7946
mdns_enabled: true
bootstrap_peers:
- "192.168.1.100:7946" # Main server address

Validation

Configuration is validated on load with the following checks:

  • Server address: Valid host:port or :port format
  • JWT secret: Minimum 32 characters, no weak patterns in production
  • TLS: Both tls_cert and tls_key required if either is set
  • Durations: Valid Go duration format (e.g., 30s, 5m, 1h)
  • Routes: Required fields (id, path_base, to), paths start with /
  • Apps: Required fields (id, name)
  • Metrics path: Must start with /, cannot conflict with /api/*

Validation errors are reported at startup with clear messages indicating the problematic configuration.