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.