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?
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.
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.
| Feature | NetBird (self-hosted) | Tailscale | Headscale |
|---|---|---|---|
| Control plane source | Open (BSD-3) | Closed | Open (BSD-3) |
| Underlying tunnel | WireGuard | WireGuard | WireGuard |
| Bundled IDP | Zitadel (built-in) | No (uses Google/MS/etc.) | No (OIDC required) |
| Built-in dashboard | Yes (React SPA) | Yes (SaaS only) | No (CLI only; community UIs exist) |
| ACL model | Groups + rules + posture checks | Tailnet policy file (HuJSON) | Tailnet policy file (imported from Tailscale) |
| Coturn/TURN fallback | Bundled and configured | Managed DERP relays | Not included (BYO) |
| Free-tier peer cap | Unlimited (self-hosted) | 100 devices / 3 users | Unlimited |
| Native clients | Linux, macOS, Windows, iOS, Android, Docker | Same | Uses official Tailscale clients |
| Setup keys | Yes (reusable, ephemeral, group-scoped) | Yes (auth keys) | Yes (pre-auth keys) |
| Posture checks (OS version, geo) | Yes | Yes (paid) | No |
| Self-contained install | getting-started.sh (one command) | N/A (SaaS) | Manual Docker Compose |
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
| Deployment size | Plan | Specs | Price |
|---|---|---|---|
| Pilot / small team (up to ~30 peers) | CloudCore Starter | 2 vCPU / 4 GB RAM / 50 GB NVMe | EUR 7.99/mo |
| Production (up to ~300 peers) | CloudCore Professional | 4 vCPU / 8 GB RAM / 100 GB NVMe | EUR 19.99/mo |
| Large fleet / heavy TURN traffic (1,000+ peers) | CloudCore Business | 8 vCPU / 16 GB RAM / 200 GB NVMe | EUR 29.99+/mo |
ssh root@your-server-ipStep 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.
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget ufw jq ca-certificates gnupg lsb-releaseReboot if the kernel was updated:
sudo rebootVerify you are on 24.04 after reconnecting:
lsb_release -aExpected output:
Distributor ID: Ubuntu
Description: Ubuntu 24.04 LTS
Release: 24.04
Codename: nobleSet a proper hostname so logs and certificates are tidy:
sudo hostnamectl set-hostname netbirdStep 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:
netbird.example.com. A 203.0.113.10Wait a few minutes for propagation, then verify from the server:
dig +short netbird.example.comExpected output:
203.0.113.10Next, open the ports NetBird requires with UFW:
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 numberedThe 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).
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.gpgecho \ "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:
docker --version
docker compose versionExpected output:
Docker version 27.3.1, build ce12230
Docker Compose version v2.29.7Enable Docker on boot:
sudo systemctl enable --now dockerStep 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:
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:
./artifacts.docker-compose.yml, management.json, turnserver.conf, and Caddyfile with your domain and generated secrets.https://netbird.example.com) and the initial admin credentials.Expected final output (abbreviated):
[+] 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:
sudo docker compose -f /opt/netbird/docker-compose.yml psExpected output:
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/tcpEach container has a specific role:
- caddy — TLS termination and reverse proxy. Routes
/to the dashboard (port 8080),/apito the management REST endpoint,/management.ManagementService/to the management gRPC,/signalexchange.SignalExchange/to the signal server, and/zitadelto 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 editingmanagement.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.
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/10IP, 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:
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
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
[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
- Name:
bastion-to-production - Source group:
bastion - Destination group:
production - Protocol: ALL
- Ports: ALL
- Action: Accept
- Name:
prometheus-scrape - Source group:
monitoring - Destination group:
All - Protocol: TCP
- Ports: 9100, 9090, 3000
- Action: Accept
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)
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:443The 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:
sudo netbird statusExpected output:
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.cloudmacOS
brew install netbirdio/tap/netbird
sudo netbird up --setup-key nb-... --management-url https://netbird.example.com:443A 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:
sudo netbird up --management-url https://netbird.example.com:443The 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:
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:latestStep 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:
sudo netbird status --detailLook for the relayed field in each peer entry:
peer: srv-db-01.netbird.cloud
status: Connected
ip: 100.64.0.15
relayed: false
direct: true
latency: 8.42ms
last_handshake: 12 seconds agodirect: 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).
ping 100.64.0.15Hardening 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:
@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
| Problem | Cause | Solution |
|---|---|---|
x509: certificate signed by unknown authority when running netbird up | Caddy has not yet obtained a Let's Encrypt certificate | Wait 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 peers | ACL policy blocking traffic | Go to Access Control, verify a rule exists from source group to destination group; remember the default is deny |
All peers show relayed: true | Coturn ports blocked or STUN broken | Verify 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 down | Check docker logs netbird-zitadel, confirm https://netbird.example.com/zitadel/.well-known/openid-configuration returns valid JSON |
Dashboard shows 502 Bad Gateway | Management or dashboard container crashed | Check docker logs netbird-management and docker logs netbird-dashboard; most commonly a database migration error — pin image versions and redeploy |
| High CPU on the VPS | Too many peers relayed via Coturn | Investigate why hole punching fails (often a cloud provider firewall), move Coturn to a separate VPS if sustained relay load is expected |
| Setup key rejected | Key expired, group deleted, or usage limit reached | Generate a fresh key in the dashboard; use reusable keys for long-lived fleets |
Error: interface netbird0 already exists | Stale state from a previous install | sudo netbird down && sudo ip link delete netbird0, then netbird up again |
| Windows client stuck "Connecting" | Windows Firewall blocking WireGuard | Allow NetBird in Windows Defender Firewall, both private and public profiles |
| Dashboard loads but login button does nothing | Browser blocking third-party cookies for Zitadel | Zitadel and dashboard share the same domain, so check browser console for CORS errors and verify Caddy is forwarding /zitadel correctly |
Useful Logs
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 agentFAQ
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
coturncontainer on a regional VPS and advertise both inmanagement.json'sTURNConfig.Turnsarray. 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:443in 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.