From 8c515797edfe9d737f68dec8a41f75740c685ed2 Mon Sep 17 00:00:00 2001 From: Alexandre <44178713+alexbelgium@users.noreply.github.com> Date: Fri, 6 Feb 2026 12:26:42 +0100 Subject: [PATCH 1/2] Add NetBird server add-on --- netbird-server/DOCS.md | 58 +++++ netbird-server/Dockerfile | 130 +++++++++++ netbird-server/build.yaml | 4 + netbird-server/config.yaml | 93 ++++++++ .../rootfs/etc/cont-init.d/00-config.sh | 214 ++++++++++++++++++ netbird-server/rootfs/etc/nginx/nginx.conf | 18 ++ .../rootfs/etc/services.d/coturn/run | 19 ++ .../rootfs/etc/services.d/dashboard/run | 43 ++++ .../rootfs/etc/services.d/management/run | 23 ++ .../rootfs/etc/services.d/relay/run | 20 ++ .../rootfs/etc/services.d/signal/run | 18 ++ .../share/netbird-dashboard/default.conf.tmpl | 27 +++ 12 files changed, 667 insertions(+) create mode 100644 netbird-server/DOCS.md create mode 100644 netbird-server/Dockerfile create mode 100644 netbird-server/build.yaml create mode 100644 netbird-server/config.yaml create mode 100644 netbird-server/rootfs/etc/cont-init.d/00-config.sh create mode 100644 netbird-server/rootfs/etc/nginx/nginx.conf create mode 100644 netbird-server/rootfs/etc/services.d/coturn/run create mode 100644 netbird-server/rootfs/etc/services.d/dashboard/run create mode 100644 netbird-server/rootfs/etc/services.d/management/run create mode 100644 netbird-server/rootfs/etc/services.d/relay/run create mode 100644 netbird-server/rootfs/etc/services.d/signal/run create mode 100644 netbird-server/rootfs/usr/local/share/netbird-dashboard/default.conf.tmpl diff --git a/netbird-server/DOCS.md b/netbird-server/DOCS.md new file mode 100644 index 000000000..704ebcf24 --- /dev/null +++ b/netbird-server/DOCS.md @@ -0,0 +1,58 @@ +# NetBird Server (monolithic) + +This add-on runs the NetBird self-hosted server stack in a single container (Management + Signal + Dashboard + Coturn; Relay optional). It does **not** use Home Assistant ingress. Access the Dashboard directly via the configured port. + +NetBird relies on gRPC. If you place the Management/Signal endpoints behind a reverse proxy, it **must** support HTTP/2 + gRPC proxying. See the NetBird reverse-proxy guide for supported configurations: . + +The NetBird self-hosted guide includes up-to-date port requirements and legacy port notes: . + +The Dashboard container requires the `NETBIRD_MGMT_API_ENDPOINT` environment variable (the add-on injects this automatically) as described in the NetBird dashboard README: . + +## Quick start + +1. Install the add-on. +2. Configure your Identity Provider (IdP) and set the required `auth_*` options (or edit the generated `management.json`). +3. Start the add-on and verify all services are running in the log output. +4. Access the dashboard at `http://:`. + +> **Tip:** If you are using your own reverse proxy, set `external_base_url` to the public URL and keep TLS termination in your proxy. + +## Configuration + +### Required options +- `data_dir`: Where NetBird stores persistent data. Default: `/config/netbird`. +- `auth_authority`, `auth_client_id`, `auth_audience`, `auth_jwt_certs`, `auth_oidc_configuration_endpoint`: OIDC values used by the Management service and Dashboard. + +### Optional options +- `disable_dashboard`: Disable the dashboard service entirely. +- `enable_relay`: Enable the NetBird relay service (requires `relay_exposed_address` and `relay_auth_secret`). +- `turn_external_ip`: Public IP to advertise when Coturn is behind NAT. +- `allow_legacy_ports`: Keep legacy port exposure for pre-v0.29 agents (see NetBird docs). + +### Generated configuration +On first start, the add-on creates: +- `management.json` in `$data_dir/management/` +- `turnserver.conf` in `$data_dir/turn/` + +If you need advanced settings, stop the add-on and edit these files. The add-on will keep your edits on restart. + +## Ports + +Default ports exposed by this add-on: + +- `33073/tcp`: Management API (HTTP/gRPC) +- `10000/tcp`: Signal gRPC +- `8080/tcp`: Dashboard +- `3478/udp`: Coturn STUN/TURN +- `33080/tcp`: Relay (optional) + +If you have legacy (< v0.29) clients, review the legacy port notes in the NetBird self-hosted guide and ensure your firewall/forwarding rules are compatible. + +## Logs + +Use `log_level: debug` for more verbose logging. + +## Notes + +- This add-on does **not** handle TLS certificates. Place it behind your existing reverse proxy if you need HTTPS. +- Coturn requires a UDP relay port range (defaults to `49152-65535`). Ensure this range is allowed in your firewall when using TURN relaying. diff --git a/netbird-server/Dockerfile b/netbird-server/Dockerfile new file mode 100644 index 000000000..c6eba8d96 --- /dev/null +++ b/netbird-server/Dockerfile @@ -0,0 +1,130 @@ +#============================# +# ALEXBELGIUM'S DOCKERFILE # +#============================# +# _.------. +# _.-` ('>.-`"""-. +# '.--'` _'` _ .--.) +# -' '-.-';` ` +# ' - _.' ``'--. +# '---` .-'""` +# /` +#=== Home Assistant Addon ===# + +######################## +# 1 NetBird components # +######################## + +ARG NETBIRD_VERSION=0.64.5 +ARG DASHBOARD_VERSION=2.31.0 +ARG COTURN_VERSION=4.6.2 + +FROM netbirdio/management:${NETBIRD_VERSION} AS netbird-management +FROM netbirdio/signal:${NETBIRD_VERSION} AS netbird-signal +FROM netbirdio/relay:${NETBIRD_VERSION} AS netbird-relay +FROM netbirdio/dashboard:${DASHBOARD_VERSION} AS netbird-dashboard +FROM coturn/coturn:${COTURN_VERSION} AS netbird-coturn + +################# +# 2 Base Image # +################# + +ARG BUILD_FROM +FROM ${BUILD_FROM} +ENV BASHIO_VERSION=0.14.3 + +################## +# 3 Modify Image # +################## + +# Set S6 wait time +ENV S6_CMD_WAIT_FOR_SERVICES=1 \ + S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ + S6_SERVICES_GRACETIME=0 + +# Global LSIO modifications +ADD "https://raw.githubusercontent.com/alexbelgium/hassio-addons/master/.templates/ha_lsio.sh" "/ha_lsio.sh" +ARG CONFIGLOCATION="/config" +RUN chmod 744 /ha_lsio.sh && if grep -qr "lsio" /etc; then /ha_lsio.sh "$CONFIGLOCATION"; fi && rm /ha_lsio.sh + +################## +# 4 Install apps # +################## + +# Copy local files +COPY rootfs/ / +RUN find . -type f \( -name "*.sh" -o -name "run" -o -name "finish" \) -print -exec chmod +x {} \; + +# Uses /bin for compatibility purposes +# hadolint ignore=DL4005 +RUN if [ ! -f /bin/sh ] && [ -f /usr/bin/sh ]; then ln -s /usr/bin/sh /bin/sh; fi && \ + if [ ! -f /bin/bash ] && [ -f /usr/bin/bash ]; then ln -s /usr/bin/bash /bin/bash; fi + +# Modules +ARG MODULES="00-banner.sh 01-custom_script.sh 90-disable_ingress.sh 00-local_mounts.sh 00-smb_mounts.sh 00-deprecated.sh" + +# Automatic modules download +ADD "https://raw.githubusercontent.com/alexbelgium/hassio-addons/master/.templates/ha_automodules.sh" "/ha_automodules.sh" +RUN chmod 744 /ha_automodules.sh && /ha_automodules.sh "$MODULES" && rm /ha_automodules.sh + +# Manual apps +ENV PACKAGES="nginx gettext ca-certificates" + +# Automatic apps & bashio +ADD "https://raw.githubusercontent.com/alexbelgium/hassio-addons/master/.templates/ha_autoapps.sh" "/ha_autoapps.sh" +RUN chmod 744 /ha_autoapps.sh && /ha_autoapps.sh "$PACKAGES" && rm /ha_autoapps.sh + +############################# +# 5 Copy NetBird components # +############################# + +COPY --from=netbird-management /go/bin/netbird-mgmt /usr/local/bin/netbird-mgmt +COPY --from=netbird-signal /go/bin/netbird-signal /usr/local/bin/netbird-signal +COPY --from=netbird-relay /go/bin/netbird-relay /usr/local/bin/netbird-relay +COPY --from=netbird-coturn /usr/bin/turnserver /usr/local/bin/turnserver + +COPY --from=netbird-dashboard /usr/share/nginx/html /usr/share/nginx/html +COPY --from=netbird-dashboard /usr/local/init_react_envs.sh /usr/local/bin/init_react_envs.sh + +################ +# 6 Entrypoint # +################ + +# Add entrypoint +ENV S6_STAGE2_HOOK=/ha_entrypoint.sh +ADD "https://raw.githubusercontent.com/alexbelgium/hassio-addons/master/.templates/ha_entrypoint.sh" "/ha_entrypoint.sh" +RUN chmod 777 /ha_entrypoint.sh + +# Install bashio +ADD "https://raw.githubusercontent.com/alexbelgium/hassio-addons/master/.templates/bashio-standalone.sh" "/usr/local/lib/bashio-standalone.sh" +RUN chmod 0755 /usr/local/lib/bashio-standalone.sh + +############ +# 7 Labels # +############ + +ARG BUILD_ARCH +ARG BUILD_DATE +ARG BUILD_DESCRIPTION +ARG BUILD_NAME +ARG BUILD_REF +ARG BUILD_REPOSITORY +ARG BUILD_VERSION +ENV BUILD_VERSION="${BUILD_VERSION}" +LABEL \ + io.hass.name="${BUILD_NAME}" \ + io.hass.description="${BUILD_DESCRIPTION}" \ + io.hass.arch="${BUILD_ARCH}" \ + io.hass.type="addon" \ + io.hass.version=${BUILD_VERSION} \ + maintainer="alexbelgium (https://github.com/alexbelgium)" \ + org.opencontainers.image.title="${BUILD_NAME}" \ + org.opencontainers.image.description="${BUILD_DESCRIPTION}" \ + org.opencontainers.image.vendor="Home Assistant Add-ons" \ + org.opencontainers.image.authors="alexbelgium (https://github.com/alexbelgium)" \ + org.opencontainers.image.licenses="MIT" \ + org.opencontainers.image.url="https://github.com/alexbelgium" \ + org.opencontainers.image.source="https://github.com/${BUILD_REPOSITORY}" \ + org.opencontainers.image.documentation="https://github.com/${BUILD_REPOSITORY}/blob/main/README.md" \ + org.opencontainers.image.created=${BUILD_DATE} \ + org.opencontainers.image.revision=${BUILD_REF} \ + org.opencontainers.image.version=${BUILD_VERSION} diff --git a/netbird-server/build.yaml b/netbird-server/build.yaml new file mode 100644 index 000000000..f9c24ed23 --- /dev/null +++ b/netbird-server/build.yaml @@ -0,0 +1,4 @@ +--- +build_from: + aarch64: ghcr.io/hassio-addons/base/aarch64:stable + amd64: ghcr.io/hassio-addons/base/amd64:stable diff --git a/netbird-server/config.yaml b/netbird-server/config.yaml new file mode 100644 index 000000000..f0c9bfa60 --- /dev/null +++ b/netbird-server/config.yaml @@ -0,0 +1,93 @@ +arch: + - aarch64 + - amd64 +description: "\U0001F426 NetBird self-hosted server stack (management, signal, dashboard, coturn)" +image: ghcr.io/alexbelgium/netbird-server-{arch} +init: false +ingress: false +map: + - addon_config:rw +name: NetBird Server +options: + data_dir: /config/netbird + domain: "" + external_base_url: "" + management_listen: "0.0.0.0:33073" + signal_listen: "0.0.0.0:10000" + dashboard_listen: "0.0.0.0:8080" + turn_listen_port: 3478 + turn_realm: "netbird" + turn_external_ip: "" + turn_min_port: 49152 + turn_max_port: 65535 + turn_user: "netbird" + turn_password: "" + idp_manager_type: "none" + auth_authority: "" + auth_client_id: "" + auth_client_secret: "" + auth_audience: "" + auth_supported_scopes: "openid profile email api offline_access email_verified" + auth_jwt_certs: "" + auth_user_id_claim: "sub" + auth_oidc_configuration_endpoint: "" + auth_token_endpoint: "" + use_auth0: false + idp_client_id: "" + idp_client_secret: "" + disable_default_policy: false + log_level: info + disable_dashboard: false + enable_relay: false + relay_exposed_address: "" + relay_auth_secret: "" + allow_legacy_ports: false +schema: + data_dir: str + domain: str? + external_base_url: str? + management_listen: str + signal_listen: str + dashboard_listen: str + turn_listen_port: port + turn_realm: str + turn_external_ip: str? + turn_min_port: port + turn_max_port: port + turn_user: str + turn_password: str? + idp_manager_type: str + auth_authority: str? + auth_client_id: str? + auth_client_secret: str? + auth_audience: str? + auth_supported_scopes: str? + auth_jwt_certs: str? + auth_user_id_claim: str + auth_oidc_configuration_endpoint: str? + auth_token_endpoint: str? + use_auth0: bool + idp_client_id: str? + idp_client_secret: str? + disable_default_policy: bool + log_level: list(info|debug) + disable_dashboard: bool + enable_relay: bool + relay_exposed_address: str? + relay_auth_secret: str? + allow_legacy_ports: bool +slug: netbird-server +ports: + 33073/tcp: 33073 + 10000/tcp: 10000 + 8080/tcp: 8080 + 3478/udp: 3478 + 33080/tcp: 33080 +ports_description: + 33073/tcp: Management API (HTTP/gRPC) + 10000/tcp: Signal gRPC + 8080/tcp: NetBird Dashboard (HTTP) + 3478/udp: Coturn STUN/TURN + 33080/tcp: Relay (WebSocket/QUIC) +url: https://github.com/alexbelgium/hassio-addons +version: 0.64.5-1 diff --git a/netbird-server/rootfs/etc/cont-init.d/00-config.sh b/netbird-server/rootfs/etc/cont-init.d/00-config.sh new file mode 100644 index 000000000..06b9760e5 --- /dev/null +++ b/netbird-server/rootfs/etc/cont-init.d/00-config.sh @@ -0,0 +1,214 @@ +#!/usr/bin/with-contenv bashio +# shellcheck shell=bash +set -euo pipefail + +# ============================================================================== +# Home Assistant Add-on: NetBird Server +# Configures NetBird services +# ============================================================================== + +create_or_load_secret() { + local secret_file="$1" + local provided_value="$2" + local generated="" + + if [[ -n "$provided_value" ]]; then + echo "$provided_value" + return + fi + + if [[ -f "$secret_file" ]]; then + cat "$secret_file" + return + fi + + generated=$(LC_ALL=C tr -dc 'A-Za-z0-9' "$secret_file" + chmod 600 "$secret_file" + echo "$generated" +} + +extract_port() { + local address="$1" + echo "${address##*:}" +} + +DATA_DIR=$(bashio::config 'data_dir') +DOMAIN=$(bashio::config 'domain') +EXTERNAL_BASE_URL=$(bashio::config 'external_base_url') +MANAGEMENT_LISTEN=$(bashio::config 'management_listen') +SIGNAL_LISTEN=$(bashio::config 'signal_listen') +DASHBOARD_LISTEN=$(bashio::config 'dashboard_listen') +TURN_LISTEN_PORT=$(bashio::config 'turn_listen_port') +TURN_REALM=$(bashio::config 'turn_realm') +TURN_EXTERNAL_IP=$(bashio::config 'turn_external_ip') +TURN_MIN_PORT=$(bashio::config 'turn_min_port') +TURN_MAX_PORT=$(bashio::config 'turn_max_port') +TURN_USER=$(bashio::config 'turn_user') +TURN_PASSWORD=$(bashio::config 'turn_password') +IDP_MANAGER_TYPE=$(bashio::config 'idp_manager_type') +AUTH_AUTHORITY=$(bashio::config 'auth_authority') +AUTH_AUDIENCE=$(bashio::config 'auth_audience') +AUTH_JWT_CERTS=$(bashio::config 'auth_jwt_certs') +AUTH_USER_ID_CLAIM=$(bashio::config 'auth_user_id_claim') +AUTH_OIDC_CONFIGURATION_ENDPOINT=$(bashio::config 'auth_oidc_configuration_endpoint') +AUTH_TOKEN_ENDPOINT=$(bashio::config 'auth_token_endpoint') +IDP_CLIENT_ID=$(bashio::config 'idp_client_id') +IDP_CLIENT_SECRET=$(bashio::config 'idp_client_secret') +DISABLE_DEFAULT_POLICY=$(bashio::config 'disable_default_policy') +DISABLE_DASHBOARD=$(bashio::config 'disable_dashboard') +ENABLE_RELAY=$(bashio::config 'enable_relay') +RELAY_EXPOSED_ADDRESS=$(bashio::config 'relay_exposed_address') +RELAY_AUTH_SECRET=$(bashio::config 'relay_auth_secret') + +MANAGEMENT_PORT=$(extract_port "$MANAGEMENT_LISTEN") +SIGNAL_PORT=$(extract_port "$SIGNAL_LISTEN") +DASHBOARD_PORT=$(extract_port "$DASHBOARD_LISTEN") + +if [[ -z "$DOMAIN" ]]; then + DOMAIN="localhost" + bashio::log.warning "domain is empty; defaulting to localhost in generated configs." +fi + +if [[ -z "$AUTH_AUTHORITY" || -z "$AUTH_AUDIENCE" || -z "$AUTH_JWT_CERTS" ]]; then + bashio::log.warning "OIDC configuration is incomplete. Update auth_* options or edit ${DATA_DIR}/management/management.json." +fi + +mkdir -p "$DATA_DIR" \ + "$DATA_DIR/management" \ + "$DATA_DIR/turn" \ + "$DATA_DIR/secrets" \ + "$DATA_DIR/dashboard" \ + "$DATA_DIR/relay" + +TURN_PASSWORD=$(create_or_load_secret "$DATA_DIR/secrets/turn_password" "$TURN_PASSWORD") +TURN_SECRET=$(create_or_load_secret "$DATA_DIR/secrets/turn_secret" "") +DATASTORE_ENC_KEY=$(create_or_load_secret "$DATA_DIR/secrets/management_datastore_key" "") + +if [[ "$ENABLE_RELAY" == "true" ]]; then + if [[ -z "$RELAY_EXPOSED_ADDRESS" || -z "$RELAY_AUTH_SECRET" ]]; then + bashio::log.error "Relay is enabled, but relay_exposed_address or relay_auth_secret is missing." + bashio::exit.nok + fi + rm -f /etc/services.d/relay/down + RELAY_JSON=$(cat < "$MANAGEMENT_CONFIG" +{ + "Stuns": [ + { + "Proto": "udp", + "URI": "stun:${DOMAIN}:${TURN_LISTEN_PORT}", + "Username": "", + "Password": null + } + ], + "TURNConfig": { + "Turns": [ + { + "Proto": "udp", + "URI": "turn:${DOMAIN}:${TURN_LISTEN_PORT}", + "Username": "${TURN_USER}", + "Password": "${TURN_PASSWORD}" + } + ], + "CredentialsTTL": "12h", + "Secret": "${TURN_SECRET}", + "TimeBasedCredentials": false + }, + "Relay": ${RELAY_JSON}, + "Signal": { + "Proto": "http", + "URI": "${DOMAIN}:${SIGNAL_PORT}", + "Username": "", + "Password": null + }, + "ReverseProxy": { + "TrustedHTTPProxies": [], + "TrustedHTTPProxiesCount": 0, + "TrustedPeers": [ + "0.0.0.0/0" + ] + }, + "DisableDefaultPolicy": ${DISABLE_DEFAULT_POLICY}, + "Datadir": "${DATA_DIR}/management", + "DataStoreEncryptionKey": "${DATASTORE_ENC_KEY}", + "StoreConfig": { + "Engine": "sqlite" + }, + "HttpConfig": { + "Address": "${MANAGEMENT_LISTEN}", + "AuthIssuer": "${AUTH_AUTHORITY}", + "AuthAudience": "${AUTH_AUDIENCE}", + "AuthKeysLocation": "${AUTH_JWT_CERTS}", + "AuthUserIDClaim": "${AUTH_USER_ID_CLAIM}", + "CertFile": "", + "CertKey": "", + "IdpSignKeyRefreshEnabled": false, + "OIDCConfigEndpoint": "${AUTH_OIDC_CONFIGURATION_ENDPOINT}" + }, + "IdpManagerConfig": { + "ManagerType": "${IDP_MANAGER_TYPE}", + "ClientConfig": { + "Issuer": "${AUTH_AUTHORITY}", + "TokenEndpoint": "${AUTH_TOKEN_ENDPOINT}", + "ClientID": "${IDP_CLIENT_ID}", + "ClientSecret": "${IDP_CLIENT_SECRET}", + "GrantType": "client_credentials" + }, + "ExtraConfig": {} + } +} +CONFIG +else + bashio::log.info "Using existing management config at ${MANAGEMENT_CONFIG}." +fi + +# Generate Coturn config +TURN_CONFIG="$DATA_DIR/turn/turnserver.conf" +TURN_EXTERNAL_IP_LINE="" +if [[ -n "$TURN_EXTERNAL_IP" ]]; then + TURN_EXTERNAL_IP_LINE="external-ip=${TURN_EXTERNAL_IP}" +fi + +cat < "$TURN_CONFIG" +listening-port=${TURN_LISTEN_PORT} +realm=${TURN_REALM} +fingerprint +lt-cred-mech +user=${TURN_USER}:${TURN_PASSWORD} +${TURN_EXTERNAL_IP_LINE} +min-port=${TURN_MIN_PORT} +max-port=${TURN_MAX_PORT} +CONFIG + +# Generate dashboard nginx config +sed "s/__DASHBOARD_PORT__/${DASHBOARD_PORT}/g" \ + /usr/local/share/netbird-dashboard/default.conf.tmpl \ + > /etc/nginx/http.d/default.conf + +mkdir -p /run/nginx +chmod +x /usr/local/bin/init_react_envs.sh diff --git a/netbird-server/rootfs/etc/nginx/nginx.conf b/netbird-server/rootfs/etc/nginx/nginx.conf new file mode 100644 index 000000000..060f1e68e --- /dev/null +++ b/netbird-server/rootfs/etc/nginx/nginx.conf @@ -0,0 +1,18 @@ +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + access_log /dev/stdout; + error_log /dev/stderr warn; + + sendfile on; + keepalive_timeout 65; + + include /etc/nginx/http.d/*.conf; +} diff --git a/netbird-server/rootfs/etc/services.d/coturn/run b/netbird-server/rootfs/etc/services.d/coturn/run new file mode 100644 index 000000000..e446f2852 --- /dev/null +++ b/netbird-server/rootfs/etc/services.d/coturn/run @@ -0,0 +1,19 @@ +#!/usr/bin/with-contenv bashio +# shellcheck shell=bash +set -euo pipefail + +# ============================================================================== +# Home Assistant Add-on: NetBird Server +# Runs Coturn +# ============================================================================== + +DATA_DIR=$(bashio::config 'data_dir') +TURN_CONFIG="$DATA_DIR/turn/turnserver.conf" + +if [[ ! -f "$TURN_CONFIG" ]]; then + bashio::log.error "Missing Coturn configuration at ${TURN_CONFIG}." + bashio::exit.nok +fi + +bashio::log.info "Starting Coturn..." +exec /usr/local/bin/turnserver -c "$TURN_CONFIG" --log-file stdout diff --git a/netbird-server/rootfs/etc/services.d/dashboard/run b/netbird-server/rootfs/etc/services.d/dashboard/run new file mode 100644 index 000000000..cc3778dc0 --- /dev/null +++ b/netbird-server/rootfs/etc/services.d/dashboard/run @@ -0,0 +1,43 @@ +#!/usr/bin/with-contenv bashio +# shellcheck shell=bash +set -euo pipefail + +# ============================================================================== +# Home Assistant Add-on: NetBird Server +# Runs the NetBird Dashboard +# ============================================================================== + +DOMAIN=$(bashio::config 'domain') +EXTERNAL_BASE_URL=$(bashio::config 'external_base_url') +MANAGEMENT_LISTEN=$(bashio::config 'management_listen') +AUTH_AUTHORITY=$(bashio::config 'auth_authority') +AUTH_CLIENT_ID=$(bashio::config 'auth_client_id') +AUTH_CLIENT_SECRET=$(bashio::config 'auth_client_secret') +AUTH_AUDIENCE=$(bashio::config 'auth_audience') +AUTH_SUPPORTED_SCOPES=$(bashio::config 'auth_supported_scopes') +USE_AUTH0=$(bashio::config 'use_auth0') + +MANAGEMENT_PORT="${MANAGEMENT_LISTEN##*:}" + +if [[ -n "$EXTERNAL_BASE_URL" ]]; then + NETBIRD_MGMT_API_ENDPOINT="$EXTERNAL_BASE_URL" +elif [[ -n "$DOMAIN" ]]; then + NETBIRD_MGMT_API_ENDPOINT="http://${DOMAIN}:${MANAGEMENT_PORT}" +else + bashio::log.warning "external_base_url and domain are empty; defaulting NETBIRD_MGMT_API_ENDPOINT to localhost." + NETBIRD_MGMT_API_ENDPOINT="http://127.0.0.1:${MANAGEMENT_PORT}" +fi + +export AUTH_AUTHORITY +export AUTH_CLIENT_ID +export AUTH_CLIENT_SECRET +export AUTH_AUDIENCE +export AUTH_SUPPORTED_SCOPES +export USE_AUTH0 +export NETBIRD_MGMT_API_ENDPOINT + +bashio::log.info "Preparing NetBird Dashboard assets..." +/usr/local/bin/init_react_envs.sh + +bashio::log.info "Starting NetBird Dashboard..." +exec nginx -g "daemon off;" diff --git a/netbird-server/rootfs/etc/services.d/management/run b/netbird-server/rootfs/etc/services.d/management/run new file mode 100644 index 000000000..a5e2981ab --- /dev/null +++ b/netbird-server/rootfs/etc/services.d/management/run @@ -0,0 +1,23 @@ +#!/usr/bin/with-contenv bashio +# shellcheck shell=bash +set -euo pipefail + +# ============================================================================== +# Home Assistant Add-on: NetBird Server +# Runs the NetBird Management service +# ============================================================================== + +DATA_DIR=$(bashio::config 'data_dir') +LOG_LEVEL=$(bashio::config 'log_level') +MANAGEMENT_CONFIG="$DATA_DIR/management/management.json" + +if [[ ! -f "$MANAGEMENT_CONFIG" ]]; then + bashio::log.error "Missing management configuration at ${MANAGEMENT_CONFIG}." + bashio::exit.nok +fi + +bashio::log.info "Starting NetBird Management..." +exec /usr/local/bin/netbird-mgmt management \ + --config "$MANAGEMENT_CONFIG" \ + --log-level "$LOG_LEVEL" \ + --log-file console diff --git a/netbird-server/rootfs/etc/services.d/relay/run b/netbird-server/rootfs/etc/services.d/relay/run new file mode 100644 index 000000000..570878083 --- /dev/null +++ b/netbird-server/rootfs/etc/services.d/relay/run @@ -0,0 +1,20 @@ +#!/usr/bin/with-contenv bashio +# shellcheck shell=bash +set -euo pipefail + +# ============================================================================== +# Home Assistant Add-on: NetBird Server +# Runs the NetBird Relay (optional) +# ============================================================================== + +LOG_LEVEL=$(bashio::config 'log_level') +RELAY_EXPOSED_ADDRESS=$(bashio::config 'relay_exposed_address') +RELAY_AUTH_SECRET=$(bashio::config 'relay_auth_secret') + +bashio::log.info "Starting NetBird Relay..." +exec /usr/local/bin/netbird-relay \ + --listen-address ":33080" \ + --exposed-address "$RELAY_EXPOSED_ADDRESS" \ + --auth-secret "$RELAY_AUTH_SECRET" \ + --log-level "$LOG_LEVEL" \ + --log-file console diff --git a/netbird-server/rootfs/etc/services.d/signal/run b/netbird-server/rootfs/etc/services.d/signal/run new file mode 100644 index 000000000..fe6a0f708 --- /dev/null +++ b/netbird-server/rootfs/etc/services.d/signal/run @@ -0,0 +1,18 @@ +#!/usr/bin/with-contenv bashio +# shellcheck shell=bash +set -euo pipefail + +# ============================================================================== +# Home Assistant Add-on: NetBird Server +# Runs the NetBird Signal service +# ============================================================================== + +SIGNAL_LISTEN=$(bashio::config 'signal_listen') +LOG_LEVEL=$(bashio::config 'log_level') +SIGNAL_PORT="${SIGNAL_LISTEN##*:}" + +bashio::log.info "Starting NetBird Signal on port ${SIGNAL_PORT}..." +exec /usr/local/bin/netbird-signal run \ + --port "$SIGNAL_PORT" \ + --log-level "$LOG_LEVEL" \ + --log-file console diff --git a/netbird-server/rootfs/usr/local/share/netbird-dashboard/default.conf.tmpl b/netbird-server/rootfs/usr/local/share/netbird-dashboard/default.conf.tmpl new file mode 100644 index 000000000..28589c925 --- /dev/null +++ b/netbird-server/rootfs/usr/local/share/netbird-dashboard/default.conf.tmpl @@ -0,0 +1,27 @@ +server { + listen __DASHBOARD_PORT__ default_server; + listen [::]:__DASHBOARD_PORT__ default_server; + + root /usr/share/nginx/html; + location = /netbird.wasm { + root /usr/share/nginx/html; + default_type application/wasm; + } + location = /ironrdp-pkg/ironrdp_web_bg.wasm { + root /usr/share/nginx/html; + default_type application/wasm; + } + + location / { + try_files $uri $uri.html $uri/ =404; + add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"; + expires off; + } + + error_page 404 /404.html; + location = /404.html { + internal; + add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"; + expires off; + } +} From d7ef48f54d47c2574f7a2cabe828f1c068640a36 Mon Sep 17 00:00:00 2001 From: Alexandre <44178713+alexbelgium@users.noreply.github.com> Date: Fri, 6 Feb 2026 14:32:34 +0100 Subject: [PATCH 2/2] Preserve Coturn config and drop legacy option --- netbird-server/DOCS.md | 1 - netbird-server/config.yaml | 2 -- .../rootfs/etc/cont-init.d/00-config.sh | 16 ++++++++++------ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/netbird-server/DOCS.md b/netbird-server/DOCS.md index 704ebcf24..c29e6b1dd 100644 --- a/netbird-server/DOCS.md +++ b/netbird-server/DOCS.md @@ -27,7 +27,6 @@ The Dashboard container requires the `NETBIRD_MGMT_API_ENDPOINT` environment var - `disable_dashboard`: Disable the dashboard service entirely. - `enable_relay`: Enable the NetBird relay service (requires `relay_exposed_address` and `relay_auth_secret`). - `turn_external_ip`: Public IP to advertise when Coturn is behind NAT. -- `allow_legacy_ports`: Keep legacy port exposure for pre-v0.29 agents (see NetBird docs). ### Generated configuration On first start, the add-on creates: diff --git a/netbird-server/config.yaml b/netbird-server/config.yaml index f0c9bfa60..efb454930 100644 --- a/netbird-server/config.yaml +++ b/netbird-server/config.yaml @@ -41,7 +41,6 @@ options: enable_relay: false relay_exposed_address: "" relay_auth_secret: "" - allow_legacy_ports: false schema: data_dir: str domain: str? @@ -75,7 +74,6 @@ schema: enable_relay: bool relay_exposed_address: str? relay_auth_secret: str? - allow_legacy_ports: bool slug: netbird-server ports: 33073/tcp: 33073 diff --git a/netbird-server/rootfs/etc/cont-init.d/00-config.sh b/netbird-server/rootfs/etc/cont-init.d/00-config.sh index 06b9760e5..1a393f269 100644 --- a/netbird-server/rootfs/etc/cont-init.d/00-config.sh +++ b/netbird-server/rootfs/etc/cont-init.d/00-config.sh @@ -187,14 +187,15 @@ else bashio::log.info "Using existing management config at ${MANAGEMENT_CONFIG}." fi -# Generate Coturn config +# Generate Coturn config if missing TURN_CONFIG="$DATA_DIR/turn/turnserver.conf" -TURN_EXTERNAL_IP_LINE="" -if [[ -n "$TURN_EXTERNAL_IP" ]]; then - TURN_EXTERNAL_IP_LINE="external-ip=${TURN_EXTERNAL_IP}" -fi +if [[ ! -f "$TURN_CONFIG" ]]; then + TURN_EXTERNAL_IP_LINE="" + if [[ -n "$TURN_EXTERNAL_IP" ]]; then + TURN_EXTERNAL_IP_LINE="external-ip=${TURN_EXTERNAL_IP}" + fi -cat < "$TURN_CONFIG" + cat < "$TURN_CONFIG" listening-port=${TURN_LISTEN_PORT} realm=${TURN_REALM} fingerprint @@ -204,6 +205,9 @@ ${TURN_EXTERNAL_IP_LINE} min-port=${TURN_MIN_PORT} max-port=${TURN_MAX_PORT} CONFIG +else + bashio::log.info "Using existing Coturn config at ${TURN_CONFIG}." +fi # Generate dashboard nginx config sed "s/__DASHBOARD_PORT__/${DASHBOARD_PORT}/g" \