[GH-ISSUE #5392] Problems with setup of reverse-proxy in self-hosted environment #11156

Closed
opened 2026-08-05 01:28:42 -04:00 by saavagebueno · 6 comments
Owner

Originally created by @micudaj on GitHub (Feb 19, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5392

I tried to install the new reverse-proxy feature following this guide: https://docs.netbird.io/selfhosted/migration/enable-reverse-proxy

when I add a service I get the following logs in the reverse-proxy container and the service is stuck in state "issuing certificate"

`2026-02-19T14:01:32Z WARN client/internal/profilemanager/service.go:360: failed to get active profile state: failed to set default active profile state: failed to set active profile to default: failed to write active profile state: create temp: open /var/lib/netbird/.2200146100active_profile.json: permission denied

2026-02-19T14:01:32Z ERRO client/iface/configurer/uapi.go:15: failed to open uapi socket: mkdir /var/run/wireguard: permission denied

2026-02-19T14:01:32Z ERRO client/iface/configurer/usp.go:308: failed to open uapi listener: mkdir /var/run/wireguard: permission denied

2026-02-19T14:01:32Z WARN client/firewall/create_linux.go:49: failed to create native firewall: create firewall: no firewall manager found. Proceeding with userspace`

Originally created by @micudaj on GitHub (Feb 19, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5392 I tried to install the new reverse-proxy feature following this guide: https://docs.netbird.io/selfhosted/migration/enable-reverse-proxy when I add a service I get the following logs in the reverse-proxy container and the service is stuck in state "issuing certificate" `2026-02-19T14:01:32Z WARN client/internal/profilemanager/service.go:360: failed to get active profile state: failed to set default active profile state: failed to set active profile to default: failed to write active profile state: create temp: open /var/lib/netbird/.2200146100active_profile.json: permission denied 2026-02-19T14:01:32Z ERRO client/iface/configurer/uapi.go:15: failed to open uapi socket: mkdir /var/run/wireguard: permission denied 2026-02-19T14:01:32Z ERRO client/iface/configurer/usp.go:308: failed to open uapi listener: mkdir /var/run/wireguard: permission denied 2026-02-19T14:01:32Z WARN client/firewall/create_linux.go:49: failed to create native firewall: create firewall: no firewall manager found. Proceeding with userspace`
Author
Owner

@t40mas commented on GitHub (Feb 19, 2026):

Maybe duplicated: #5349

<!-- gh-comment-id:3929745177 --> @t40mas commented on GitHub (Feb 19, 2026): Maybe duplicated: #5349
Author
Owner

@2TAP2B commented on GitHub (Feb 23, 2026):

Same problem here, Any updates about this?

<!-- gh-comment-id:3944478622 --> @2TAP2B commented on GitHub (Feb 23, 2026): Same problem here, Any updates about this?
Author
Owner

@lixmal commented on GitHub (Feb 23, 2026):

These are just warnings because of the tight permissions of the container Image. These don't impact operation and will be silenced in a future release

<!-- gh-comment-id:3945079367 --> @lixmal commented on GitHub (Feb 23, 2026): These are just warnings because of the tight permissions of the container Image. These don't impact operation and will be silenced in a future release
Author
Owner

@selenecodes commented on GitHub (Feb 23, 2026):

@lixmal I do have a question then because right now the only error I'm getting in my instance when opening a service through the reverse proxy is the error shown above as well as a "Issuing Certificate" which does not actually resolve into an actual certificate.

<!-- gh-comment-id:3945141067 --> @selenecodes commented on GitHub (Feb 23, 2026): @lixmal I do have a question then because right now the only error I'm getting in my instance when opening a service through the reverse proxy is the error shown above as well as a "Issuing Certificate" which does not actually resolve into an actual certificate.
Author
Owner

@t40mas commented on GitHub (Feb 23, 2026):

@selenecodes take a look at #5349

<!-- gh-comment-id:3945165606 --> @t40mas commented on GitHub (Feb 23, 2026): @selenecodes take a look at #5349
Author
Owner

@selenecodes commented on GitHub (Feb 23, 2026):

I tried the suggestions laid out there with both the netbird-server:80 solution as well as the external connection solution e.g. netbird.example.com. Fyi the only things changed in this docker compose from my live deployment is the redaction of my acme email and my domain name as well as the various envvars relating to credentials.

Edit: I am also not using rosenpass or preshared keys.

name: netbird
services:
  dashboard:
    image: netbirdio/dashboard:v2.32.5
    container_name: netbird-dashboard
    environment:
      # Endpoints
      NETBIRD_MGMT_API_ENDPOINT: https://netbird.example.com
      NETBIRD_MGMT_GRPC_API_ENDPOINT: https://netbird.example.com
      # OIDC - using embedded IdP
      AUTH_AUDIENCE: netbird-dashboard
      AUTH_CLIENT_ID: netbird-dashboard
      AUTH_CLIENT_SECRET:
      AUTH_AUTHORITY: https://netbird.example.com/oauth2
      USE_AUTH0: false
      AUTH_SUPPORTED_SCOPES: openid profile email groups
      AUTH_REDIRECT_URI: /nb-auth
      AUTH_SILENT_REDIRECT_URI: /nb-silent-auth
      # SSL
      NGINX_SSL_PORT: 443
      # Letsencrypt
      LETSENCRYPT_DOMAIN: none
    env_file:
      - /shared-config/.env.shared
    networks: [ netbird ]
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"
    labels:
      traefik.enable: true
      traefik.http.routers.netbird-dashboard.rule: Host(`netbird.example.com`)
      traefik.http.routers.netbird-dashboard.entrypoints: websecure
      traefik.http.routers.netbird-dashboard.tls: true
      traefik.http.routers.netbird-dashboard.tls.certresolver: letsencrypt
      traefik.http.routers.netbird-dashboard.service: dashboard
      traefik.http.routers.netbird-dashboard.priority: 1
      traefik.http.services.dashboard.loadbalancer.server.port: 80
      # Unraid UI labels
      net.unraid.docker.managed: portainer
      net.unraid.docker.webui: https://netbird.example.com
      net.unraid.docker.icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/netbird.png
  db:
    image: "postgres:18.2"
    container_name: netbird-db
    volumes:
      - /mnt/cache/appdata/netbird-db:/var/lib/postgresql/18/docker
    environment:
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_INITDB_ARGS: --encoding=UTF-8 --lc-collate=C --lc-ctype=C
    env_file:
      - /shared-config/.env.shared
    networks:
      - netbird
    restart: unless-stopped
    labels:
      # Unraid UI labels
      net.unraid.docker.managed: portainer
      net.unraid.docker.icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/postgres.png
  # Combined server (Management + Signal + Relay + STUN)
  netbird-server:
    image: netbirdio/netbird-server:0.65.3
    container_name: netbird-server
    depends_on:
      - db
    volumes:
      - /mnt/cache/appdata/netbird/data:/var/lib/netbird
      - /mnt/cache/appdata/netbird/config.yaml:/etc/netbird/config.yaml
    environment:
      NETBIRD_STORE_ENGINE_POSTGRES_DSN: host=db user=${DB_USERNAME} password=${DB_PASSWORD} dbname=${DB_DATABASE_NAME} port=5432
    ports:
      - '3478:3478/udp'
    networks: [ netbird ]
    command: [ "--config", "/etc/netbird/config.yaml" ]
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"
    labels:
      traefik.enable: true
      # gRPC router (needs h2c backend for HTTP/2 cleartext)
      traefik.http.routers.netbird-grpc.rule: Host(`netbird.example.com`) && (PathPrefix(`/signalexchange.SignalExchange/`) || PathPrefix(`/management.ManagementService/`) || PathPrefix(`/management.ProxyService/`))
      traefik.http.routers.netbird-grpc.entrypoints: websecure
      traefik.http.routers.netbird-grpc.tls: true
      traefik.http.routers.netbird-grpc.tls.certresolver: letsencrypt
      traefik.http.routers.netbird-grpc.service: netbird-server-h2c
      traefik.http.routers.netbird-grpc.priority: 100
      # Backend router (relay, WebSocket, API, OAuth2)
      traefik.http.routers.netbird-backend.rule: Host(`netbird.example.com`) && (PathPrefix(`/relay`) || PathPrefix(`/ws-proxy/`) || PathPrefix(`/api`) || PathPrefix(`/oauth2`))
      traefik.http.routers.netbird-backend.entrypoints: websecure
      traefik.http.routers.netbird-backend.tls: true
      traefik.http.routers.netbird-backend.tls.certresolver: letsencrypt
      traefik.http.routers.netbird-backend.service: netbird-server
      traefik.http.routers.netbird-backend.priority: 100
      # Services
      traefik.http.services.netbird-server.loadbalancer.server.port: 80
      traefik.http.services.netbird-server-h2c.loadbalancer.server.port: 80
      traefik.http.services.netbird-server-h2c.loadbalancer.server.scheme: h2c
      # Unraid UI labels
      net.unraid.docker.managed: portainer
      net.unraid.docker.webui: https://netbird.example.com
      net.unraid.docker.icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/netbird.png

  # NetBird Proxy - exposes internal resources to the internet
  proxy:
    image: netbirdio/reverse-proxy:0.65.3
    container_name: netbird-proxy
    depends_on:
      - netbird-server
    volumes:
      - /mnt/cache/appdata/netbird-proxy/certs:/certs
    extra_hosts:
      - "netbird.example.com:172.30.0.10"
    environment:
      NB_PROXY_DOMAIN: proxy.example.com
      NB_PROXY_MANAGEMENT_ADDRESS: https://netbird.example.com:443
      NB_PROXY_ALLOW_INSECURE: true
      NB_PROXY_ADDRESS: :8443
      NB_PROXY_ACME_CERTIFICATES: true
      NB_PROXY_ACME_CHALLENGE_TYPE: tls-alpn-01
      NB_PROXY_CERTIFICATE_DIRECTORY: /certs
      # Placeholder - will be updated with token after netbird-server starts
      # The proxy authenticates with the management server using an access token. Generate one using the server CLI.
      # https://docs.netbird.io/selfhosted/migration/enable-reverse-proxy#step-2-generate-a-proxy-access-token
      #
      # docker exec -it netbird-server /go/bin/netbird-server token create --name "my-proxy" --config /etc/netbird/config.yaml
      #
      NB_PROXY_TOKEN: ${NB_PROXY_TOKEN}
    env_file:
      - /shared-config/.env.shared
    ports:
      - '51820:51820/udp'
    networks: [ netbird ]
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"
    labels:
      # TCP passthrough for any unmatched domain (proxy handles its own TLS)
      traefik.enable: true
      traefik.tcp.routers.proxy-passthrough.entrypoints: websecure
      traefik.tcp.routers.proxy-passthrough.rule: HostSNI(`*`)
      traefik.tcp.routers.proxy-passthrough.tls.passthrough: true
      traefik.tcp.routers.proxy-passthrough.service: proxy-tls
      traefik.tcp.routers.proxy-passthrough.priority: 1
      traefik.tcp.services.proxy-tls.loadbalancer.server.port: 8443
      traefik.tcp.services.proxy-tls.loadbalancer.serverstransport: pp-v2@file
      # Unraid UI labels
      net.unraid.docker.managed: portainer
      net.unraid.docker.webui: https://netbird.example.com
      net.unraid.docker.icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/netbird.png
  traefik:
    image: traefik:v3.6.8
    container_name: netbird-traefik
    volumes:
      - /mnt/cache/appdata/traefik/letsencrypt:/letsencrypt
      - /mnt/cache/appdata/traefik/traefik-dynamic.yaml:/etc/traefik/dynamic.yaml:ro
    env_file:
      - /shared-config/.env.shared
    ports:
      - '80:80'
      - '443:443'
    networks:
      docker-socket-proxy:
      netbird:
        ipv4_address: 172.30.0.10
    command:
      # Logging
      - "--log.level=${TRAEFIK_LOG_LEVEL:-INFO}"
      - "--accesslog=true"
      # Docker provider
      - "--providers.docker=true"
      - "--providers.docker.endpoint=tcp://docker-socket-proxy:2375"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=netbird"
      # Entrypoints
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.websecure.allowACMEByPass=true"
      # Disable timeouts for long-lived gRPC streams
      - "--entrypoints.websecure.transport.respondingTimeouts.readTimeout=0"
      - "--entrypoints.websecure.transport.respondingTimeouts.writeTimeout=0"
      - "--entrypoints.websecure.transport.respondingTimeouts.idleTimeout=0"
      # HTTP to HTTPS redirect
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      # Let's Encrypt ACME
      - "--certificatesresolvers.letsencrypt.acme.email=email@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
      # gRPC transport settings
      - "--serverstransport.forwardingtimeouts.responseheadertimeout=0s"
      - "--serverstransport.forwardingtimeouts.idleconntimeout=0s"
      - "--providers.file.filename=/etc/traefik/dynamic.yaml"
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"
    labels:
      # Unraid UI labels
      net.unraid.docker.managed: portainer
      net.unraid.docker.webui: https://traefik.example.com
      net.unraid.docker.icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/traefik.png

networks:
  docker-socket-proxy:
    external: true
  netbird:
    name: netbird
    driver: bridge
    ipam:
      config:
        - subnet: 172.30.0.0/24
          gateway: 172.30.0.1
<!-- gh-comment-id:3945551167 --> @selenecodes commented on GitHub (Feb 23, 2026): I tried the suggestions laid out there with both the netbird-server:80 solution as well as the external connection solution e.g. netbird.example.com. Fyi the only things changed in this docker compose from my live deployment is the redaction of my acme email and my domain name as well as the various envvars relating to credentials. Edit: I am also not using rosenpass or preshared keys. ```yaml name: netbird services: dashboard: image: netbirdio/dashboard:v2.32.5 container_name: netbird-dashboard environment: # Endpoints NETBIRD_MGMT_API_ENDPOINT: https://netbird.example.com NETBIRD_MGMT_GRPC_API_ENDPOINT: https://netbird.example.com # OIDC - using embedded IdP AUTH_AUDIENCE: netbird-dashboard AUTH_CLIENT_ID: netbird-dashboard AUTH_CLIENT_SECRET: AUTH_AUTHORITY: https://netbird.example.com/oauth2 USE_AUTH0: false AUTH_SUPPORTED_SCOPES: openid profile email groups AUTH_REDIRECT_URI: /nb-auth AUTH_SILENT_REDIRECT_URI: /nb-silent-auth # SSL NGINX_SSL_PORT: 443 # Letsencrypt LETSENCRYPT_DOMAIN: none env_file: - /shared-config/.env.shared networks: [ netbird ] restart: unless-stopped logging: driver: "json-file" options: max-size: "500m" max-file: "2" labels: traefik.enable: true traefik.http.routers.netbird-dashboard.rule: Host(`netbird.example.com`) traefik.http.routers.netbird-dashboard.entrypoints: websecure traefik.http.routers.netbird-dashboard.tls: true traefik.http.routers.netbird-dashboard.tls.certresolver: letsencrypt traefik.http.routers.netbird-dashboard.service: dashboard traefik.http.routers.netbird-dashboard.priority: 1 traefik.http.services.dashboard.loadbalancer.server.port: 80 # Unraid UI labels net.unraid.docker.managed: portainer net.unraid.docker.webui: https://netbird.example.com net.unraid.docker.icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/netbird.png db: image: "postgres:18.2" container_name: netbird-db volumes: - /mnt/cache/appdata/netbird-db:/var/lib/postgresql/18/docker environment: POSTGRES_USER: ${DB_USERNAME} POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_INITDB_ARGS: --encoding=UTF-8 --lc-collate=C --lc-ctype=C env_file: - /shared-config/.env.shared networks: - netbird restart: unless-stopped labels: # Unraid UI labels net.unraid.docker.managed: portainer net.unraid.docker.icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/postgres.png # Combined server (Management + Signal + Relay + STUN) netbird-server: image: netbirdio/netbird-server:0.65.3 container_name: netbird-server depends_on: - db volumes: - /mnt/cache/appdata/netbird/data:/var/lib/netbird - /mnt/cache/appdata/netbird/config.yaml:/etc/netbird/config.yaml environment: NETBIRD_STORE_ENGINE_POSTGRES_DSN: host=db user=${DB_USERNAME} password=${DB_PASSWORD} dbname=${DB_DATABASE_NAME} port=5432 ports: - '3478:3478/udp' networks: [ netbird ] command: [ "--config", "/etc/netbird/config.yaml" ] restart: unless-stopped logging: driver: "json-file" options: max-size: "500m" max-file: "2" labels: traefik.enable: true # gRPC router (needs h2c backend for HTTP/2 cleartext) traefik.http.routers.netbird-grpc.rule: Host(`netbird.example.com`) && (PathPrefix(`/signalexchange.SignalExchange/`) || PathPrefix(`/management.ManagementService/`) || PathPrefix(`/management.ProxyService/`)) traefik.http.routers.netbird-grpc.entrypoints: websecure traefik.http.routers.netbird-grpc.tls: true traefik.http.routers.netbird-grpc.tls.certresolver: letsencrypt traefik.http.routers.netbird-grpc.service: netbird-server-h2c traefik.http.routers.netbird-grpc.priority: 100 # Backend router (relay, WebSocket, API, OAuth2) traefik.http.routers.netbird-backend.rule: Host(`netbird.example.com`) && (PathPrefix(`/relay`) || PathPrefix(`/ws-proxy/`) || PathPrefix(`/api`) || PathPrefix(`/oauth2`)) traefik.http.routers.netbird-backend.entrypoints: websecure traefik.http.routers.netbird-backend.tls: true traefik.http.routers.netbird-backend.tls.certresolver: letsencrypt traefik.http.routers.netbird-backend.service: netbird-server traefik.http.routers.netbird-backend.priority: 100 # Services traefik.http.services.netbird-server.loadbalancer.server.port: 80 traefik.http.services.netbird-server-h2c.loadbalancer.server.port: 80 traefik.http.services.netbird-server-h2c.loadbalancer.server.scheme: h2c # Unraid UI labels net.unraid.docker.managed: portainer net.unraid.docker.webui: https://netbird.example.com net.unraid.docker.icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/netbird.png # NetBird Proxy - exposes internal resources to the internet proxy: image: netbirdio/reverse-proxy:0.65.3 container_name: netbird-proxy depends_on: - netbird-server volumes: - /mnt/cache/appdata/netbird-proxy/certs:/certs extra_hosts: - "netbird.example.com:172.30.0.10" environment: NB_PROXY_DOMAIN: proxy.example.com NB_PROXY_MANAGEMENT_ADDRESS: https://netbird.example.com:443 NB_PROXY_ALLOW_INSECURE: true NB_PROXY_ADDRESS: :8443 NB_PROXY_ACME_CERTIFICATES: true NB_PROXY_ACME_CHALLENGE_TYPE: tls-alpn-01 NB_PROXY_CERTIFICATE_DIRECTORY: /certs # Placeholder - will be updated with token after netbird-server starts # The proxy authenticates with the management server using an access token. Generate one using the server CLI. # https://docs.netbird.io/selfhosted/migration/enable-reverse-proxy#step-2-generate-a-proxy-access-token # # docker exec -it netbird-server /go/bin/netbird-server token create --name "my-proxy" --config /etc/netbird/config.yaml # NB_PROXY_TOKEN: ${NB_PROXY_TOKEN} env_file: - /shared-config/.env.shared ports: - '51820:51820/udp' networks: [ netbird ] restart: unless-stopped logging: driver: "json-file" options: max-size: "500m" max-file: "2" labels: # TCP passthrough for any unmatched domain (proxy handles its own TLS) traefik.enable: true traefik.tcp.routers.proxy-passthrough.entrypoints: websecure traefik.tcp.routers.proxy-passthrough.rule: HostSNI(`*`) traefik.tcp.routers.proxy-passthrough.tls.passthrough: true traefik.tcp.routers.proxy-passthrough.service: proxy-tls traefik.tcp.routers.proxy-passthrough.priority: 1 traefik.tcp.services.proxy-tls.loadbalancer.server.port: 8443 traefik.tcp.services.proxy-tls.loadbalancer.serverstransport: pp-v2@file # Unraid UI labels net.unraid.docker.managed: portainer net.unraid.docker.webui: https://netbird.example.com net.unraid.docker.icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/netbird.png traefik: image: traefik:v3.6.8 container_name: netbird-traefik volumes: - /mnt/cache/appdata/traefik/letsencrypt:/letsencrypt - /mnt/cache/appdata/traefik/traefik-dynamic.yaml:/etc/traefik/dynamic.yaml:ro env_file: - /shared-config/.env.shared ports: - '80:80' - '443:443' networks: docker-socket-proxy: netbird: ipv4_address: 172.30.0.10 command: # Logging - "--log.level=${TRAEFIK_LOG_LEVEL:-INFO}" - "--accesslog=true" # Docker provider - "--providers.docker=true" - "--providers.docker.endpoint=tcp://docker-socket-proxy:2375" - "--providers.docker.exposedbydefault=false" - "--providers.docker.network=netbird" # Entrypoints - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--entrypoints.websecure.allowACMEByPass=true" # Disable timeouts for long-lived gRPC streams - "--entrypoints.websecure.transport.respondingTimeouts.readTimeout=0" - "--entrypoints.websecure.transport.respondingTimeouts.writeTimeout=0" - "--entrypoints.websecure.transport.respondingTimeouts.idleTimeout=0" # HTTP to HTTPS redirect - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - "--entrypoints.web.http.redirections.entrypoint.scheme=https" # Let's Encrypt ACME - "--certificatesresolvers.letsencrypt.acme.email=email@example.com" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true" # gRPC transport settings - "--serverstransport.forwardingtimeouts.responseheadertimeout=0s" - "--serverstransport.forwardingtimeouts.idleconntimeout=0s" - "--providers.file.filename=/etc/traefik/dynamic.yaml" restart: unless-stopped logging: driver: "json-file" options: max-size: "500m" max-file: "2" labels: # Unraid UI labels net.unraid.docker.managed: portainer net.unraid.docker.webui: https://traefik.example.com net.unraid.docker.icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/traefik.png networks: docker-socket-proxy: external: true netbird: name: netbird driver: bridge ipam: config: - subnet: 172.30.0.0/24 gateway: 172.30.0.1 ```
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11156