Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Netbird Ubuntu
GUIDEInstall Guides

How to Install NetBird on Ubuntu 24.04 VPS — Self-Hosted WireGuard Mesh VPN

28 min read

How to Install NetBird on Ubuntu 24.04 VPS — Self-Hosted WireGuard Mesh VPN

Corporate VPN appliances and cloud-hosted mesh services were built for a different era. Today you want a flat, zero-trust network where laptops, servers, and containers connect directly to each other with WireGuard-grade encryption, authenticate against your own identity provider, and obey fine-grained access policies — without sending any data to a third-party control plane. NetBird is the open-source answer to that requirement, and this guide walks you through a production self-hosted install on a single Ubuntu 24.04 VPS.

By the end, you will have a working NetBird deployment with a web dashboard, a Zitadel SSO login flow, reusable setup keys, peer groups, ACL policies, and enrolled Linux, macOS, and Windows clients talking to each other over a private 100.64.0.0/10 mesh.

Skip the manual setup? Deploy NetBird on a pre-provisioned VPS in minutes. Launch a Professional VPS now and follow along — you will have your mesh running by the end of the afternoon.

Table of Contents

  • What is NetBird?
  • Why Self-Host a Mesh VPN?
  • NetBird vs. Tailscale vs. Headscale
  • Prerequisites
  • Step 1: Prepare the Ubuntu VPS
  • Step 2: Configure DNS and Firewall
  • Step 3: Install Docker and Docker Compose
  • Step 4: Run the getting-started.sh Installer
  • Step 5: Understanding the Five Components
  • Step 6: Sign in to the Dashboard and Zitadel
  • Step 7: Create Setup Keys and Groups
  • Step 8: Write ACL Policies
  • Step 9: Enroll Linux, macOS, and Windows Clients
  • Step 10: Verify NAT Traversal and Peer-to-Peer Tunnels
  • Hardening and Production Tips
  • Troubleshooting
  • FAQ
  • Next Steps
  • What is NetBird?

    NetBird is an open-source zero-trust mesh VPN built on top of WireGuard. Instead of routing all traffic through a central concentrator, NetBird orchestrates direct peer-to-peer WireGuard tunnels between every device in your network. A small control plane handles peer registration, public-key exchange, and access-control evaluation; the actual encrypted data flows between endpoints.

    The project is written in Go, released under the BSD-3-Clause license, and ships five cooperating services in its self-hosted edition:

    • Management server — the brain. Stores peers, groups, setup keys, and ACL policies in an SQLite or PostgreSQL database. Exposes a REST API to the dashboard and a gRPC stream to connected agents.
    • Signal server — a stateless relay that brokers WebRTC-style SDP exchanges so peers behind NAT can discover each other and punch holes for direct UDP tunnels.
    • Coturn — a STUN/TURN server that provides fallback relay when two peers fail to establish a direct tunnel (typically caused by symmetric NAT on both sides).
    • Dashboard — a React single-page app that talks to the management REST API. Lets admins invite users, manage peers, write policies, and audit events. Internally served on port 8080 behind the Caddy reverse proxy.
    • Zitadel IDP — an embedded OIDC identity provider that bootstraps login without requiring an external service. You can swap it for Google Workspace, Okta, Auth0, or a standalone Zitadel deployment.
    Everything runs in Docker containers behind a Caddy reverse proxy that handles automatic Let's Encrypt certificates for your domain.

    Why Self-Host a Mesh VPN?

    Commercial mesh VPNs are convenient, but a self-hosted NetBird delivers several tangible advantages:

    • Data sovereignty — all peer metadata, access logs, and authentication events stay on infrastructure you control. No SaaS telemetry leaves your VPS.
    • No peer cap — the hosted NetBird Cloud free tier is generous but finite. Self-hosted has no artificial limit; you scale with your VPS.
    • Bring-your-own-identity — pair NetBird with any OIDC IdP, including your existing Google Workspace, Azure AD, Keycloak, or Zitadel tenant.
    • GDPR- and HIPAA-friendly — keeping the control plane on an EU VPS simplifies data residency conversations. You hold the encryption keys for the database.
    • Flat predictable cost — a single Professional VPS covers hundreds of peers for EUR 19.99/month. No per-seat billing.
    • Full audit access — every admin action and peer event is in a database and log file you can query, export, or forward to your SIEM.
    • Custom integrations — the REST API is well-documented, so you can provision peers during cloud-init, sync groups from your HR system, or rotate setup keys from CI.

    NetBird vs. Tailscale vs. Headscale

    If you are evaluating mesh-VPN options, here is how NetBird stacks up against the two most common alternatives.

    FeatureNetBird (self-hosted)TailscaleHeadscale
    Control plane sourceOpen (BSD-3)ClosedOpen (BSD-3)
    Underlying tunnelWireGuardWireGuardWireGuard
    Bundled IDPZitadel (built-in)No (uses Google/MS/etc.)No (OIDC required)
    Built-in dashboardYes (React SPA)Yes (SaaS only)No (CLI only; community UIs exist)
    ACL modelGroups + rules + posture checksTailnet policy file (HuJSON)Tailnet policy file (imported from Tailscale)
    Coturn/TURN fallbackBundled and configuredManaged DERP relaysNot included (BYO)
    Free-tier peer capUnlimited (self-hosted)100 devices / 3 usersUnlimited
    Native clientsLinux, macOS, Windows, iOS, Android, DockerSameUses official Tailscale clients
    Setup keysYes (reusable, ephemeral, group-scoped)Yes (auth keys)Yes (pre-auth keys)
    Posture checks (OS version, geo)YesYes (paid)No
    Self-contained installgetting-started.sh (one command)N/A (SaaS)Manual Docker Compose
    When to choose NetBird: you want the full self-hosted experience with a polished dashboard, built-in identity, and no client compatibility worries. This is the right pick for most teams that rejected Tailscale on open-source or pricing grounds.

    When to choose Tailscale: you want zero operational overhead and a generous free tier is acceptable. The closed control plane is a non-starter for some organisations.

    When to choose Headscale: you are already committed to Tailscale clients and want to run your own coordination server while preserving the official desktop apps. Headscale has no dashboard out of the box.

    For the rest of this guide we focus on NetBird. If Headscale fits your needs better, see our Headscale install guide.

    Prerequisites

    Before starting, make sure you have:

    • A VPS running Ubuntu 24.04 LTS with root or sudo access.
    • A public IPv4 address — NAT-behind-NAT setups will not work for the control plane.
    • A domain name you control (for example netbird.example.com) with the ability to create A records.
    • 4 vCPU, 8 GB RAM, 100 GB NVMe for a comfortable production deployment supporting up to a few hundred peers.
    • Ports open — 80, 443, 33073, 10000 (TCP) and 3478, 49152-65535 (UDP). See Step 2 for details.

    Recommended Plan: CloudCore Professional

    We recommend the CloudCore Professional plan for self-hosted NetBird:

    • 4 vCPU cores
    • 8 GB RAM
    • 100 GB NVMe SSD
    • Unmetered bandwidth on a 1 Gbps port
    • EUR 19.99/month
    Sizing tiers for different deployments:
    Deployment sizePlanSpecsPrice
    Pilot / small team (up to ~30 peers)CloudCore Starter2 vCPU / 4 GB RAM / 50 GB NVMeEUR 7.99/mo
    Production (up to ~300 peers)CloudCore Professional4 vCPU / 8 GB RAM / 100 GB NVMeEUR 19.99/mo
    Large fleet / heavy TURN traffic (1,000+ peers)CloudCore Business8 vCPU / 16 GB RAM / 200 GB NVMeEUR 29.99+/mo
    Connect to the server via SSH:

    bash
    ssh root@your-server-ip

    Step 1: Prepare the Ubuntu VPS

    Begin with the usual hygiene of a fresh VPS: apply updates and install a few tools you will need along the way.

    bash
    sudo apt update && sudo apt upgrade -y
    sudo apt install -y curl wget ufw jq ca-certificates gnupg lsb-release

    Reboot if the kernel was updated:

    bash
    sudo reboot

    Verify you are on 24.04 after reconnecting:

    bash
    lsb_release -a

    Expected output:

    text
    Distributor ID: Ubuntu
    Description:    Ubuntu 24.04 LTS
    Release:        24.04
    Codename:       noble

    Set a proper hostname so logs and certificates are tidy:

    bash
    sudo hostnamectl set-hostname netbird

    Step 2: Configure DNS and Firewall

    NetBird needs one publicly resolvable hostname for the dashboard, API, and embedded Zitadel IDP. Create an A record in your DNS provider pointing to your VPS:

    text
    netbird.example.com.        A      203.0.113.10

    Wait a few minutes for propagation, then verify from the server:

    bash
    dig +short netbird.example.com

    Expected output:

    text
    203.0.113.10

    Next, open the ports NetBird requires with UFW:

    bash
    sudo ufw allow 22/tcp             # SSH
    sudo ufw allow 80/tcp             # Let's Encrypt HTTP-01 + redirect
    sudo ufw allow 443/tcp            # Dashboard, API, Zitadel
    sudo ufw allow 33073/tcp          # Management gRPC
    sudo ufw allow 10000/tcp          # Signal server
    sudo ufw allow 3478/udp           # Coturn STUN
    sudo ufw allow 49152:65535/udp    # Coturn relay range
    sudo ufw enable
    sudo ufw status numbered

    The only client-side requirement is outbound UDP — NetBird agents never need inbound ports open on end-user devices.

    Step 3: Install Docker and Docker Compose

    NetBird ships as a Docker Compose stack. Install Docker Engine from the official repository (the Ubuntu-packaged docker.io works but lags upstream).

    bash
    sudo install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
      sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    sudo chmod a+r /etc/apt/keyrings/docker.gpg

    echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin

    Verify both Docker and the Compose plugin:

    bash
    docker --version
    docker compose version

    Expected output:

    text
    Docker version 27.3.1, build ce12230
    Docker Compose version v2.29.7

    Enable Docker on boot:

    bash
    sudo systemctl enable --now docker

    Step 4: Run the getting-started.sh Installer

    NetBird ships a single installer script that pulls the Compose file, generates secrets, renders Zitadel configuration, and brings up all five services. This is the officially supported self-hosted flow — see docs.netbird.io for the upstream reference.

    Create a working directory and run the installer:

    bash
    sudo mkdir -p /opt/netbird
    cd /opt/netbird
    export NETBIRD_DOMAIN="netbird.example.com"
    sudo -E bash -c "$(curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started-with-zitadel.sh)"

    The script will:

  • Detect or create a configuration directory at ./artifacts.
  • Prompt for admin email and password for the embedded Zitadel instance.
  • Render docker-compose.yml, management.json, turnserver.conf, and Caddyfile with your domain and generated secrets.
  • Launch Caddy to obtain a Let's Encrypt certificate for your domain.
  • Start the management, signal, dashboard (on internal port 8080), Coturn, and Zitadel containers.
  • Print the URL you should open (https://netbird.example.com) and the initial admin credentials.
  • Expected final output (abbreviated):

    text
    [+] Running 8/8
     ✔ Container netbird-caddy         Started
     ✔ Container netbird-dashboard     Started
     ✔ Container netbird-management    Started
     ✔ Container netbird-signal        Started
     ✔ Container netbird-coturn        Started
     ✔ Container netbird-zitadel       Started
     ✔ Container netbird-zitadel-db    Started

    Dashboard available at: https://netbird.example.com Zitadel admin: [email protected] Zitadel password: (printed once — save it now)

    Save the Zitadel admin password in your password manager immediately. It is printed once and not recoverable from the filesystem without significant effort.

    Step 5: Understanding the Five Components

    Before touching the dashboard, take a moment to understand what you just installed. Run docker compose ps from /opt/netbird:

    bash
    sudo docker compose -f /opt/netbird/docker-compose.yml ps

    Expected output:

    text
    NAME                  IMAGE                                      STATUS          PORTS
    netbird-caddy         caddy:2                                    Up 2 minutes    0.0.0.0:80->80, 0.0.0.0:443->443
    netbird-dashboard     netbirdio/dashboard:latest                 Up 2 minutes    8080/tcp
    netbird-management    netbirdio/management:latest                Up 2 minutes    33073/tcp
    netbird-signal        netbirdio/signal:latest                    Up 2 minutes    10000/tcp
    netbird-coturn        coturn/coturn:latest                       Up 2 minutes    0.0.0.0:3478->3478/udp
    netbird-zitadel       ghcr.io/zitadel/zitadel:stable             Up 2 minutes    8080/tcp
    netbird-zitadel-db    cockroachdb/cockroach:latest-v24.1         Up 2 minutes    26257/tcp

    Each container has a specific role:

    • caddy — TLS termination and reverse proxy. Routes / to the dashboard (port 8080), /api to the management REST endpoint, /management.ManagementService/ to the management gRPC, /signalexchange.SignalExchange/ to the signal server, and /zitadel to the Zitadel UI.
    • dashboard — static React single-page app served by Nginx on port 8080. Talks to the management API via the browser's fetch() calls.
    • management — REST/gRPC API on port 33073. Persists data to ./artifacts/store.db (SQLite) by default; swap to Postgres for larger deployments by editing management.json.
    • signal — gRPC service on port 10000. Brokers WireGuard key exchange between peers attempting to connect.
    • coturn — STUN on UDP 3478 and TURN on the 49152-65535 range. Only a fraction of peer pairs need TURN relay; most establish direct tunnels via hole-punching.
    • zitadel + zitadel-db — the embedded OIDC provider plus a CockroachDB backing store.
    The architecture means a compromised peer cannot read traffic between other peers — all tunnels are end-to-end encrypted with WireGuard keys that never leave the devices. The management server only sees public keys and metadata, never user payloads.

    Step 6: Sign in to the Dashboard and Zitadel

    Open https://netbird.example.com in a browser. You will be redirected to Zitadel for authentication. Sign in with the admin credentials printed by the installer. On first login Zitadel will force you to set a permanent password and optionally register a second factor (TOTP or WebAuthn).

    After logging in you land on the NetBird dashboard. The left navigation exposes:

    • Peers — all enrolled devices, their assigned 100.64.0.0/10 IP, OS, version, and last-seen timestamp.
    • Setup Keys — reusable and one-off enrollment tokens, optionally tied to groups and auto-expire dates.
    • Groups — logical collections of peers used in ACL rules (for example servers, laptops, ci-runners).
    • Access Control — ACL policies that allow or block traffic between groups.
    • Network Routes — advertise CIDR ranges (typically office LAN subnets) through a designated peer.
    • DNS — nameserver groups and custom domain records that NetBird pushes to clients.
    • Users — Zitadel-managed human accounts with roles (admin, user, billing admin).
    • Activity — audit log of admin and peer events.

    Swapping Zitadel for an External IdP

    If you would rather use Google Workspace, Okta, or an existing Zitadel tenant, stop the stack, edit /opt/netbird/artifacts/setup.env, and set:

    text
    NETBIRD_AUTH_CLIENT_ID=...
    NETBIRD_AUTH_CLIENT_SECRET=...
    NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT=https://accounts.google.com/.well-known/openid-configuration
    NETBIRD_USE_AUTH0=false
    NETBIRD_AUTH_AUDIENCE=<your client id>

    Then re-run getting-started.sh, which is idempotent and will re-render configs without wiping data.

    Step 7: Create Setup Keys and Groups

    Peers join the network by presenting a setup key during agent startup. Keys can be reusable (good for auto-scaling server pools), one-off (good for onboarding a new employee laptop), time-limited, and scoped to groups.

    In the dashboard, go to Setup Keys → Add Setup Key. For a typical server fleet:

    • Name: production-servers
    • Type: Reusable
    • Usage limit: Unlimited
    • Expires: Never
    • Auto-assigned groups: servers, production
    Click Create and copy the generated key (format nb-xxxxx-xxxx-...). You cannot see the key again — store it in your secrets manager.

    Repeat for any logical segment you want to enroll independently: laptops, ci-runners, kubernetes-nodes, customers, and so on.

    Creating Groups

    Groups can be created on-the-fly when issuing a setup key, or explicitly under Groups → Add Group. A peer can belong to multiple groups simultaneously, which gives you flexibility when writing ACL rules.

    Common group taxonomies:

    • Environment: production, staging, development
    • Function: web, database, monitoring, ci
    • Trust level: bastion, restricted, internal
    • Owner: team-backend, team-frontend, team-ops
    Groups can also be auto-populated via the REST API or by matching OIDC claims (for example, everyone in the Google Workspace group [email protected] lands in the NetBird engineers group automatically).

    Step 8: Write ACL Policies

    By default, NetBird denies all peer-to-peer traffic — a zero-trust starting position. You explicitly allow what should be reachable.

    Navigate to Access Control → Add Policy.

    Example 1: Engineers reach production via bastion only

    • Name: engineers-to-bastion
    • Source group: engineers
    • Destination group: bastion
    • Protocol: TCP
    • Ports: 22
    • Action: Accept
    Example 2: Bastion reaches all production servers

    • Name: bastion-to-production
    • Source group: bastion
    • Destination group: production
    • Protocol: ALL
    • Ports: ALL
    • Action: Accept
    Example 3: Monitoring scrapes everywhere

    • Name: prometheus-scrape
    • Source group: monitoring
    • Destination group: All
    • Protocol: TCP
    • Ports: 9100, 9090, 3000
    • Action: Accept
    Rules evaluate in order with an implicit deny at the end. You can also create Posture Checks (OS version, NetBird agent version, country) and attach them as preconditions — a peer must pass every posture check before the rule applies.

    For advanced routing, Network Routes let you expose an entire LAN CIDR (for example 10.0.0.0/16) through a designated peer acting as a gateway. This is how you connect an office network or a VPC without enrolling every server individually.

    Step 9: Enroll Linux, macOS, and Windows Clients

    With setup keys issued and policies in place, install the NetBird agent on each device.

    Linux (Ubuntu, Debian, RHEL, Arch)

    bash
    curl -fsSL https://pkgs.netbird.io/install.sh | sh
    sudo netbird up --setup-key nb-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
                    --management-url https://netbird.example.com:443

    The agent installs as a systemd service, generates a WireGuard keypair, registers with your management server, and assigns itself an IP in the 100.64.0.0/10 range.

    Verify the tunnel:

    bash
    sudo netbird status

    Expected output:

    text
    Peers count: 4/4 Connected
    NetBird IP: 100.64.0.12/16
    Interface type: userspace
    Management: Connected to https://netbird.example.com:443
    Signal: Connected to https://netbird.example.com:443
    FQDN: srv-web-01.netbird.cloud

    macOS

    bash
    brew install netbirdio/tap/netbird
    sudo netbird up --setup-key nb-... --management-url https://netbird.example.com:443

    A GUI client is also available via a signed .pkg installer from the dashboard's Install page.

    Windows

    Download the MSI from the Install page in the dashboard (or from netbird.io/download). Run the installer, open the NetBird tray icon, paste your setup key, and confirm the management URL. Windows Defender Firewall will prompt once for network profile permissions — allow both Private and Public.

    Interactive SSO Enrollment

    For human users (laptops), you can skip setup keys entirely and use SSO:

    bash
    sudo netbird up --management-url https://netbird.example.com:443

    The agent opens a browser window, you authenticate via Zitadel, and the peer is registered against your user identity. This is the recommended flow for employee laptops because peers are automatically associated with the correct user.

    Docker

    Run NetBird inside a container to mesh a Docker host or Swarm node:

    bash
    docker run -d \
      --name netbird \
      --cap-add NET_ADMIN --cap-add SYS_ADMIN --cap-add SYS_RESOURCE \
      --device /dev/net/tun:/dev/net/tun \
      -v netbird-client:/etc/netbird \
      -e NB_SETUP_KEY=nb-... \
      -e NB_MANAGEMENT_URL=https://netbird.example.com:443 \
      netbirdio/netbird:latest

    Step 10: Verify NAT Traversal and Peer-to-Peer Tunnels

    NetBird's magic is its NAT traversal. The signal server coordinates a WebRTC-style ICE negotiation so two peers behind residential routers can punch a hole for direct UDP. Only about 5-10% of peer pairs end up needing TURN relay via Coturn.

    Check the tunnel mode for each peer:

    bash
    sudo netbird status --detail

    Look for the relayed field in each peer entry:

    text
    peer: srv-db-01.netbird.cloud
      status:         Connected
      ip:             100.64.0.15
      relayed:        false
      direct:         true
      latency:        8.42ms
      last_handshake: 12 seconds ago
    • direct: true, relayed: false — peers established a direct WireGuard tunnel. Traffic is peer-to-peer with no control-plane hop.
    • direct: false, relayed: true — peers fell back to Coturn relay. Throughput is limited by your VPS's bandwidth. This is expected when both peers are behind symmetric NAT (some cellular carriers, some corporate firewalls).
    You can also confirm end-to-end reachability with ping over the overlay:

    bash
    ping 100.64.0.15

    Hardening and Production Tips

    Once the basic stack is running, tighten a few things for production:

    1. Move SQLite to Postgres. Edit /opt/netbird/artifacts/management.json and set "StoreConfig": {"Engine": "postgres", ...} with connection details for a managed Postgres instance. This improves concurrency and makes backups simpler.

    2. Back up /opt/netbird/artifacts nightly. The whole control-plane state (management DB, Zitadel DB, Caddy certificates, setup.env) lives here. A simple tarball to S3 or a BorgBackup repo is sufficient.

    3. Enable automatic Docker image updates. Add Watchtower or a weekly cron running docker compose pull && docker compose up -d to stay current with NetBird releases.

    4. Front with Cloudflare or Fastly only if you must. The dashboard and Zitadel are safe behind a CDN, but the signal and management gRPC endpoints need long-lived connections — keep them on direct domains.

    5. Restrict the Zitadel admin UI. Once you have created your human-facing users, limit /zitadel access by IP via the Caddyfile:

    text
    @zitadel path /zitadel/*
    handle @zitadel {
        @allowed remote_ip 203.0.113.0/24
        handle @allowed { reverse_proxy zitadel:8080 }
        respond "Forbidden" 403
    }

    6. Forward audit logs to a SIEM. The management container writes JSON logs to stdout. Ship them to Loki, Elasticsearch, or any syslog destination via the Docker logging driver.

    7. Rotate setup keys regularly. Time-bound every key and replace the long-lived server-pool keys quarterly.

    8. Enable fail2ban for SSH. Even though NetBird provides a secure overlay, the underlying VPS still accepts public SSH. sudo apt install fail2ban closes the brute-force surface.

    Troubleshooting

    ProblemCauseSolution
    x509: certificate signed by unknown authority when running netbird upCaddy has not yet obtained a Let's Encrypt certificateWait 1-2 minutes after install, check docker logs netbird-caddy, ensure port 80 is reachable from the public internet
    Peer shows Connected but cannot ping other peersACL policy blocking trafficGo to Access Control, verify a rule exists from source group to destination group; remember the default is deny
    All peers show relayed: trueCoturn ports blocked or STUN brokenVerify UDP 3478 and 49152-65535 are open in UFW and at the cloud provider firewall level
    netbird up hangs at "Waiting for IdP"Zitadel URL misconfigured or IdP downCheck docker logs netbird-zitadel, confirm https://netbird.example.com/zitadel/.well-known/openid-configuration returns valid JSON
    Dashboard shows 502 Bad GatewayManagement or dashboard container crashedCheck docker logs netbird-management and docker logs netbird-dashboard; most commonly a database migration error — pin image versions and redeploy
    High CPU on the VPSToo many peers relayed via CoturnInvestigate why hole punching fails (often a cloud provider firewall), move Coturn to a separate VPS if sustained relay load is expected
    Setup key rejectedKey expired, group deleted, or usage limit reachedGenerate a fresh key in the dashboard; use reusable keys for long-lived fleets
    Error: interface netbird0 already existsStale state from a previous installsudo netbird down && sudo ip link delete netbird0, then netbird up again
    Windows client stuck "Connecting"Windows Firewall blocking WireGuardAllow NetBird in Windows Defender Firewall, both private and public profiles
    Dashboard loads but login button does nothingBrowser blocking third-party cookies for ZitadelZitadel and dashboard share the same domain, so check browser console for CORS errors and verify Caddy is forwarding /zitadel correctly

    Useful Logs

    bash
    sudo docker logs -f netbird-management
    sudo docker logs -f netbird-signal
    sudo docker logs -f netbird-coturn
    sudo docker logs -f netbird-zitadel
    sudo journalctl -u netbird -f          # client-side agent

    FAQ

    Is self-hosted NetBird free?

    Yes. NetBird is licensed under BSD-3-Clause and the self-hosted edition imposes no peer, user, or feature limits. Your only ongoing cost is the VPS hosting the control plane. On a CloudCore Professional VPS at EUR 19.99/month you can comfortably run hundreds of peers, which works out to pennies per device per month.

    How does NetBird compare to Tailscale?

    Both are WireGuard-based mesh VPNs with similar client UX. The differences: NetBird is fully open-source including the control plane, while Tailscale's coordination server is closed. NetBird bundles Zitadel so identity works out of the box; Tailscale requires Google/Microsoft/Okta. Tailscale's free tier caps at 100 devices and 3 users; self-hosted NetBird is uncapped. On the other hand, Tailscale's DERP relay network is globally distributed, while your NetBird Coturn runs on a single VPS — for a multi-continent peer topology you may want to run regional Coturn instances. See our Tailscale guide for the comparison from the other direction.

    What ports does NetBird require?

    TCP 80 (Let's Encrypt challenge and HTTP redirect), TCP 443 (dashboard, API, Zitadel), TCP 33073 (management gRPC), TCP 10000 (signal server), UDP 3478 (Coturn STUN), and UDP 49152-65535 (Coturn relay). Client devices do not need any inbound ports — WireGuard punches outbound UDP holes through NAT.

    Do I need a GPU or dedicated hardware?

    No. The NetBird control plane is lightweight Go code and runs comfortably on a 4 vCPU / 8 GB RAM VPS. Coturn is the only bandwidth-heavy component, and only for relayed peers (typically 5-10% of connections). If you serve many video-calling peers through TURN, budget extra bandwidth and CPU for Coturn; otherwise the Professional plan is sufficient.

    Can I use my existing Google Workspace or Okta for login?

    Yes. NetBird supports any OIDC-compliant identity provider. Edit setup.env, set NETBIRD_AUTH_CLIENT_ID, NETBIRD_AUTH_CLIENT_SECRET, and NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT to your provider's discovery URL, and re-run getting-started.sh. Zitadel is only the default because it makes the install zero-dependency — you can also run Zitadel on a separate VPS and point NetBird at it, which is recommended for larger organisations.

    Does NetBird work across cloud providers?

    Yes. NetBird is cloud-agnostic — it only needs outbound UDP connectivity from the client. You can mesh AWS EC2 instances, Hetzner servers, a Mac Mini in a co-location, a developer's laptop on a home connection, and a Kubernetes pod on GKE all into the same overlay network. The 100.64.0.0/10 IP space is unrouted CGNAT space and will not conflict with typical VPC CIDRs.

    How do I back up the NetBird state?

    Everything persistent lives under /opt/netbird/artifacts. A nightly tar czf of that directory is a complete backup for SQLite deployments. For Postgres, take a pg_dump of the management and Zitadel databases in addition to the artifacts directory (which still holds Caddy certificates and setup.env).

    How is NetBird different from a plain WireGuard setup?

    A plain WireGuard deployment requires you to manually distribute public keys, assign IPs, and configure allowed CIDRs for every peer — which is fine for a handful of servers but becomes unmanageable at scale. NetBird automates key exchange, IP assignment, NAT traversal, and access control through its management plane. You still get the same WireGuard performance and encryption, plus a dashboard, SSO, group-based ACLs, and one-command client enrollment.

    Next Steps

    Your NetBird mesh is live — here are recommended follow-ups:

    • Deploy a second Coturn near your users — if you have peers on different continents, run an additional coturn container on a regional VPS and advertise both in management.json's TURNConfig.Turns array. Relayed traffic will pick the closest option.
    • Automate peer enrollment with cloud-init — include curl -fsSL https://pkgs.netbird.io/install.sh | sh && netbird up --setup-key $NB_KEY --management-url https://netbird.example.com:443 in your cloud-init script so every new VM auto-joins the mesh.
    • Integrate with your CI/CD — use the NetBird REST API to generate short-lived setup keys for ephemeral CI runners. Revoke them after the job completes.
    • Layer in posture checks — enforce minimum OS version, require the latest NetBird agent, or block peers from specific countries via posture rules in the dashboard.
    • Combine with WireGuard for site-to-site — use NetBird for user access and a classic WireGuard tunnel for static datacenter-to-datacenter routing. They coexist peacefully.
    • Explore the NetBird API — the full OpenAPI spec at docs.netbird.io documents every endpoint. Build custom dashboards, Slack bots, or integrations.
    • Read the official docs — for advanced topics like custom DNS, multi-tenancy, HA Postgres setups, and SCIM provisioning, the official NetBird documentation is the authoritative reference.
    • Scale up when you grow — if peer counts or Coturn relay traffic exceed what the Professional plan handles, migrate to the CloudCore Business plan (8 vCPU / 16 GB RAM, EUR 29.99+/month) or split Coturn onto its own VPS.

    Ready to deploy NetBird on production-grade infrastructure?
    >
    Our CloudCore Professional VPS plan is purpose-sized for self-hosted mesh VPNs:
    >
    - 4 vCPU / 8 GB RAM / 100 GB NVMe
    - Unmetered 1 Gbps bandwidth (perfect for Coturn relay)
    - DDoS protection included
    - Provision in under 60 seconds
    - EUR 19.99/month — no per-peer fees, no SaaS lock-in
    >
    Starter deployments begin at EUR 7.99/month, and Business-tier environments start at EUR 29.99/month for larger fleets.
    >
    Launch your VPS and follow this guide to have NetBird serving your whole organisation by the end of the afternoon.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket