Skip to content

NetBird

Deploy NetBird on Kubernetes as a self-hosted WireGuard overlay control plane for device management, identity-aware access, and peer coordination.

Overview

The HelmForge NetBird chart follows the current upstream combined self-hosted architecture:

  • netbirdio/netbird-server:0.75.0 for the management API, gRPC endpoint, signal, relay, metrics, health, and UDP STUN service
  • netbirdio/dashboard:v2.90.3 for the web dashboard
  • Secret-backed config.yaml, either generated from values or supplied through server.config.existingSecret
  • HelmForge PostgreSQL subchart as the default production store
  • persistent server data under /var/lib/netbird
  • separate server and dashboard Services
  • Ingress and Gateway API HTTPRoute support
  • UDP 3478 Service exposure for STUN
  • External Secrets Operator, NetworkPolicy, PDB, dual-stack service fields, and Helm tests

Configuration Reference

Server:

  • server.image.repository, server.image.tag, server.image.pullPolicy: official pinned NetBird server image.
  • server.replicaCount: server pod count. Keep 1 with the default sqlite store.
  • server.publicUrl: externally reachable URL for dashboard, API, gRPC, signal, and relay traffic.
  • server.authSecret: shared server auth secret. Replace the default before production use.
  • server.disableAnonymousMetrics, server.disableGeoliteUpdate: upstream telemetry and GeoLite controls.
  • server.config.existingSecret, server.config.existingSecretKey, server.config.extraYaml: generated or externally supplied config.yaml.
  • server.auth.issuer, server.auth.localAuthDisabled, server.auth.signKeyRefreshEnabled: embedded or external OIDC settings.
  • server.auth.owner.email, server.auth.owner.password: optional local owner bootstrap.
  • server.store.engine, server.store.dsn, server.store.encryptionKey: legacy direct sqlite, postgres, or mysql store settings.
  • server.service.type, server.service.httpPort, server.service.stunPort, server.service.metricsPort, server.service.healthPort.
  • server.probes.enabled: opt-in health probes for environments where first boot completes within the configured timeout.

Database:

  • database.mode: auto, sqlite, postgresql, or external.
  • database.external.engine: external postgres or mysql.
  • database.external.host, database.external.port, database.external.name, database.external.username.
  • database.external.password, database.external.existingSecret, database.external.existingSecretPasswordKey, database.external.dsn.
  • postgresql.enabled, postgresql.auth, postgresql.standalone.persistence: bundled HelmForge PostgreSQL store.

Dashboard:

  • dashboard.enabled: deploy the dashboard UI.
  • dashboard.image.repository, dashboard.image.tag, dashboard.image.pullPolicy: official pinned dashboard image.
  • dashboard.replicaCount: dashboard pod count.
  • dashboard.auth.clientId, dashboard.auth.audience, dashboard.auth.supportedScopes: dashboard OIDC identity and scopes.
  • dashboard.auth.redirectUri, dashboard.auth.silentRedirectUri: interactive and silent dashboard callbacks.
  • dashboard.auth.tokenSource, dashboard.auth.useAuth0: dashboard token and provider mode.
  • dashboard.securityContext: dashboard-specific runtime security context for upstream supervisord and nginx.
  • dashboard.service.type, dashboard.service.port, dashboard.service.annotations, dashboard.service.ipFamilyPolicy, dashboard.service.ipFamilies.

Shared operations:

  • imagePullSecrets, commonLabels, nameOverride, fullnameOverride.
  • persistence.enabled, persistence.size, persistence.storageClass, persistence.accessModes, persistence.existingClaim, persistence.mountPath.
  • serviceAccount.create, serviceAccount.name, serviceAccount.annotations, serviceAccount.automountServiceAccountToken.
  • ingress.enabled, ingress.ingressClassName, ingress.annotations, ingress.hosts, ingress.tls.
  • gatewayAPI.enabled, gatewayAPI.httpRoutes.
  • externalSecrets.enabled, externalSecrets.items.
  • pdb.enabled, pdb.minAvailable.
  • networkPolicy.enabled, networkPolicy.ingressFrom, networkPolicy.extraEgress.
  • resources, podSecurityContext, securityContext, nodeSelector, tolerations, affinity.
  • topologySpreadConstraints, priorityClassName, terminationGracePeriodSeconds.
  • podLabels, podAnnotations, extraVolumes, extraVolumeMounts, extraManifests.

Installation

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install netbird helmforge/netbird --namespace netbird --create-namespace

OCI install:

helm install netbird oci://ghcr.io/helmforgedev/helm/netbird --namespace netbird --create-namespace

Production Example

The embedded identity provider expects dashboard and server callbacks on the same public hostname. The defaults use the netbird-dashboard client and the /nb-auth and /nb-silent-auth callback paths:

server:
  publicUrl: https://netbird.example.com
  authSecret: replace-with-a-strong-random-secret
  auth:
    issuer: https://netbird.example.com/oauth2
  store:
    encryptionKey: replace-with-a-persistent-encryption-key

dashboard:
  auth:
    clientId: netbird-dashboard
    audience: netbird-dashboard
    supportedScopes: openid profile email groups
    redirectUri: /nb-auth
    silentRedirectUri: /nb-silent-auth

database:
  mode: postgresql
postgresql:
  enabled: true
  auth:
    database: netbird
    username: netbird

persistence:
  enabled: true
  size: 20Gi

ingress:
  enabled: true
  ingressClassName: nginx
  hosts:
    - host: netbird.example.com
      paths:
        - path: /
          pathType: Prefix
          service: dashboard
        - path: /api
          pathType: Prefix
          service: server
  tls:
    - secretName: netbird-tls
      hosts:
        - netbird.example.com

Expose UDP 3478 for STUN with a LoadBalancer Service, Gateway implementation, or infrastructure-specific UDP listener. Kubernetes Ingress does not handle UDP.

Prefer separate hosts for production ingress: route the NetBird backend host to the server service and the dashboard host to the dashboard service. If you use one host with path-based routing, send /api, /oauth2, /relay, /ws-proxy/management, /ws-proxy/signal, /signalexchange.SignalExchange/, /management.ManagementService/, and /management.ProxyService/ to the server service before any dashboard route. Configure the ingress controller or gateway to preserve HTTP/2 or h2c behavior for gRPC routes.

External Secrets

Use External Secrets for a full upstream config.yaml or sensitive bootstrap data:

server:
  config:
    existingSecret: netbird-config

externalSecrets:
  enabled: true
  items:
    - name: config
      spec:
        secretStoreRef:
          kind: ClusterSecretStore
          name: production
        target:
          name: netbird-config
          creationPolicy: Owner
        data:
          - secretKey: config.yaml
            remoteRef:
              key: apps/netbird/config.yaml

Scaling

The v1 chart defaults to PostgreSQL through the HelmForge PostgreSQL subchart. Use database.mode=external for a managed PostgreSQL or MySQL database. Use database.mode=sqlite with postgresql.enabled=false only for lab or small single-replica installs.

Even with PostgreSQL or MySQL, scaling server.replicaCount above 1 requires a complete HA topology for the combined server components. Plan signal, relay, and STUN exposure with load-balancer affinity and protocol-aware routing before enabling multiple server replicas. If that topology is not in place, keep server.replicaCount: 1.

Upgrade Notes

NetBird 0.75.0 improves the combined server’s management, relay, and self-hosting paths. It adds account settings for dashboard and agent-network features, source and destination traffic filters, trusted-proxy handling for relay client addresses, and a unified admin CLI. The redesigned desktop client announced in this upstream release is distributed separately and is not part of this server chart.

No chart value migration is required when upgrading from 0.74.7. Back up the configured database and /var/lib/netbird, then apply the new chart defaults while preserving your explicit overrides:

helm repo update helmforge
helm upgrade netbird helmforge/netbird \
  --version 1.0.3 \
  --namespace netbird \
  --reset-then-reuse-values

Using --reuse-values alone retains the previous image tag and does not deploy NetBird 0.75.0.

This v1 hardening release changes the default store from sqlite to PostgreSQL subchart mode. Existing sqlite installs that want to keep sqlite should set:

database:
  mode: sqlite
postgresql:
  enabled: false

To migrate production data from sqlite to PostgreSQL, follow the upstream NetBird PostgreSQL migration guidance and back up /var/lib/netbird before switching modes.

Dashboard replicas can scale independently when the backing server and ingress layer are ready for the traffic.

Additional Resources