Jack Carter 4061897914 fix: update self-hosted docs for the Traefik reverse proxy (#911)
* fix: update self-hosted docs for the Traefik reverse proxy

`getting-started-enterprise.sh` deploys Traefik instead of Caddy, but the
enterprise getting-started page still described the Caddy stack. The worst of it
was the custom-TLS appendix, which edits a `Caddyfile` the installer no longer
generates, so it could not be followed at all.

- Rewrite the custom TLS certificate appendix for Traefik: supply the
  certificate through the file provider, then remove both the ACME resolver
  flags and the four router `certresolver` labels. Removing the labels alone is
  not enough, because the certificate already stored in `acme.json` continues to
  be served in preference to the supplied one.
- Document renewal correctly. Traefik watches the dynamic configuration file
  rather than the certificate files it references, so replacing the certificates
  has no effect until that file is touched. No container restart is needed.
- Correct the certificate issuance guidance on the enterprise page and in
  certificate troubleshooting. The generated stack uses the TLS-ALPN-01
  challenge only, so TCP/443 is what must be reachable; port 80 serves the
  HTTP→HTTPS redirect and is never used for validation. The community installer
  sets the same flag, so this applies to both.
- Drop the `Caddyfile` row from the generated-files table. The installer writes
  `.env`, `docker-compose.yml` and `config.yaml` only, and configures routing
  and TLS through Traefik labels and command flags.
- Replace `caddy` with `traefik` in the stack components table, the log
  commands, and the cleanup instructions, and fix `selfhosted-guide` still
  calling the bundled proxy Caddy where the same page elsewhere says Traefik.
- Add the consequences that were previously unstated: a peer that does not trust
  a private issuing CA fails to connect, `config.yaml`'s empty `server.tls`
  block is intentional, and dropping the `80:80` mapping costs the HTTP→HTTPS
  redirect.

* fix: mount the Traefik dynamic config as a directory, not a single file

A bind-mounted single file is pinned to one inode, so any tool that replaces the
file rather than editing it in place — most editors, `sed -i`, many
configuration-management tools — leaves the container reading the old content
indefinitely, with no error and no way to recover by touching the new file.
Traefik's own documentation recommends `directory` over `filename` for this
reason.

Switch to `--providers.file.directory=/etc/traefik/dynamic` with `./traefik`
bind-mounted, and move the dynamic configuration to `traefik/dynamic.yaml`. The
renewal instruction is otherwise unchanged: the certificates are referenced
rather than watched, so they are picked up by touching the dynamic configuration,
without restarting any container.

Also drop the `tls.certificates` list from the example. It is redundant next to
`stores.default.defaultCertificate`, which already covers every connection
including clients that send no SNI.

* docs: scope the custom TLS appendix to the fresh enterprise install

The appendix sits on a page that also documents `migrate-to-enterprise.sh`, and
the two paths differ. A migrated deployment is built on the community
`getting-started.sh` render, which already configures a file provider when the
reverse proxy is enabled. `providers.file.filename` and
`providers.file.directory` are mutually exclusive, so following these steps
verbatim there would declare a conflicting second provider.

Note that deployments which already have a file provider should extend its
dynamic configuration instead, and adjust router names to match their own
Compose file.

* docs: apply NetBird house style to the custom TLS appendix

Replace the em dashes added by the previous commits with commas, colons and
parentheses. House convention is to reach for an em dash deliberately or not at
all, and the appendix had accumulated eleven of them.

Also state when not to follow the appendix at all: the default Let's Encrypt
path renews itself, and everything in the appendix makes renewal the operator's
responsibility. Expand SNI on first use.

* docs: correct the migrate-path guidance in the custom TLS appendix

Running the appendix against a real migrated deployment (community install with
the built-in Traefik, then migrate-to-enterprise.sh with Postgres and traffic
flow) showed the previous note pointed at the wrong difference. The four router
names are identical to the fresh install, so there is nothing to adjust there.

What actually differs is which file holds each label. `netbird-dashboard`,
`netbird-grpc` and `netbird-backend` are in `docker-compose.yml`, while
`netbird-flow` is on the `flow-receiver` service in
`docker-compose.override.yml`, so the deletions span two files. The `traefik`
service and the ACME flags stay in `docker-compose.yml`.

Also state why a deployment that already has a file provider must extend it
rather than add a second one: `providers.file.directory` and
`providers.file.filename` are mutually exclusive.

* docs: tighten the custom TLS appendix

The appendix had grown to four stacked callouts, two of them before the reader
reaches the first step. Cut it from 690 to 554 words and from four callouts to
two, without dropping anything load-bearing.

Move the migrate-path and existing-file-provider caveats out of a 106 word
preamble block and into the two steps they actually affect. Drop a decorative
sentence about all routes passing through Traefik, shorten the inode note, and
trim the SNI gloss to expanding the acronym.

* docs: find the resolver labels by grep instead of enumerating them

The appendix is the supported way to serve a custom certificate, not a stopgap,
so it should not hard-code "four labels, one on dashboard, two on
netbird-server, one on receiver". That count goes stale the moment a router is
added, and silently.

Replace the enumeration with a grep over `docker-compose*.yml`. It is shorter,
survives new routers, and spans `docker-compose.override.yml` on a migrated
deployment, which removes the need for a separate note about where the
`netbird-flow` label lives.

Also reword the intro so the file provider reads as the mechanism you enable
rather than something the installer failed to configure.

* docs: fix three gaps in the custom TLS appendix

- The `traefik` directory was never created. "Create `traefik/dynamic.yaml`"
  fails in any editor that will not create a missing parent, so add the
  `mkdir -p traefik` the steps assumed.
- `/certs` appeared in the dynamic configuration one step before the mount that
  defines it. Say that it is a container path and where it comes from.
- Point the file-provider caveat at the named edit it refers to instead of "the
  next step's first edit", and reword the grep sentence.
2026-08-10 17:06:13 +02:00
2024-03-08 16:27:55 +01:00
2023-05-25 11:32:38 +02:00
2026-07-27 11:08:52 +02:00
2026-07-27 11:08:52 +02:00
2025-11-21 11:24:17 +01:00
2026-01-12 23:01:42 +01:00

The NetBird documentation

This repository contains assets required to build the documentation website for NetBird. It is built using Next.js with MDX support, a modern React framework for building static and dynamic websites.

We're glad that you want to contribute!

Requirements

  • node 16
  • npm 8+

Installation

$ npm install

Local Development

$ npm run dev

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

Contributing to the docs

You can click the Fork button in the upper-right area of the screen to create a copy of this repository in your GitHub account. This copy is called a fork. Make any changes you want in your fork, and when you are ready to send those changes to us, go to your fork and create a new pull request to let us know about it.

Once your pull request is created, a NetBird reviewer will take responsibility for providing clear, actionable feedback. As the owner of the pull request, it is your responsibility to modify your pull request to address the feedback that has been provided to you by the NetBird reviewer.

Also, note that you may end up having more than one NetBird reviewer provide you feedback or you may end up getting feedback from a NetBird reviewer that is different than the one initially assigned to provide you feedback.

Furthermore, in some cases, one of your reviewers might ask for a technical review from a NetBird author when needed. Reviewers will do their best to provide feedback in a timely fashion but response time can vary based on circumstances.

Code of conduct

Participation in the NetBird community is governed by the NetBirds' Code of Conduct.

Components and Use

This documentation uses several custom MDX components. Here's a guide to the most commonly used components:

Alert Components

Use these components to highlight important information:

Note

Displays informational content with an orange theme:

import {Note} from "@/components/mdx"

<Note>
    NetBird is an **[open-source](https://github.com/netbirdio/netbird)** project and can be self-hosted.
    See a comparison between the self-hosted and cloud-hosted versions [here](/selfhosted/self-hosted-vs-cloud-netbird).
</Note>

Warning

Displays warning content with a red theme:

import {Warning} from "@/components/mdx"

<Warning>
    The API is still in Beta state so some errors might not be handled properly yet.
</Warning>

Success

Displays success messages with a green theme:

import {Success} from "@/components/mdx"

<Success>
    Your configuration has been successfully applied.
</Success>

Tiles Component

Displays a grid of clickable cards with hover effects. Perfect for listing related resources or guides:

import {Tiles} from "@/components/Tiles"

<Tiles 
  title="About NetBird" 
  id="about-netbird" 
  items={[
    {
      href: '/about-netbird/how-netbird-works',
      name: 'How NetBird Works',
      description: 'Learn about NetBird concepts, architecture, protocols, and how it creates secure networks.',
    },
    {
      href: '/about-netbird/netbird-vs-traditional-vpn',
      name: 'NetBird vs. Traditional VPN',
      description: 'Discover how NetBird compares to traditional VPNs and understand the advantages of Zero Trust networking.',
    },
  ]} 
/>

Props:

  • title (string, required): The heading title for the tiles section
  • id (string, optional): Optional id for the heading anchor
  • items (array, required): Array of objects with href, name, and description
  • buttonText (string, optional): Button text (defaults to "Read more" - currently unused as cards are fully clickable)

YouTube Component

Embeds YouTube videos with customizable parameters:

import {YouTube} from "@/components/YouTube"

<YouTube videoId="CFa7SY4Up9k" />

// With custom parameters
<YouTube 
  videoId="CFa7SY4Up9k" 
  title="Video Title"
  start={175}
  color="white"
  modestbranding={1}
  rel={1}
/>

// Or use a URL instead of videoId
<YouTube url="https://www.youtube.com/watch?v=CFa7SY4Up9k" />

Props:

  • videoId (string): YouTube video ID
  • url (string): YouTube URL (alternative to videoId)
  • title (string, optional): Video title
  • start (number, optional): Start time in seconds
  • color (string, optional): Progress bar color - 'white' or 'red' (default: 'white')
  • modestbranding (number, optional): Reduces YouTube branding - 0 or 1 (default: 1)
  • controls (number, optional): Show/hide controls - 0, 1, or 2 (default: 1)
  • rel (number, optional): Show related videos - 0 or 1 (default: 1)

Button Component

Creates styled buttons with multiple variants:

import {Button} from "@/components/Button"

// Primary button (default)
<Button href="https://app.netbird.io/install" arrow="right">
  Get started
</Button>

// Secondary button
<Button href="/path" variant="secondary">
  Learn more
</Button>

// Outline button
<Button href="/path" variant="outline">
  Explore
</Button>

// Text button
<Button href="/path" variant="text" arrow="right">
  Read more
</Button>

// With left arrow
<Button href="/path" arrow="left">
  Back
</Button>

Props:

  • variant (string, optional): Button style - 'primary', 'secondary', 'filled', 'outline', or 'text' (default: 'primary')
  • href (string, optional): Link URL (creates a link if provided, otherwise renders as button)
  • arrow (string, optional): Arrow icon - 'left' or 'right'
  • children (required): Button text content

Other Common Components

Row and Col

Create two-column layouts:

import {Row, Col} from "@/components/mdx"

<Row>
  <Col>
    Left column content
  </Col>
  <Col sticky>
    Right column content (sticky on scroll)
  </Col>
</Row>

Properties and Property

Define API properties or configuration options:

import {Properties, Property} from "@/components/mdx"

<Properties>
  <Property name="apiKey" type="string" required>
    Your API key for authentication.
  </Property>
  <Property name="timeout" type="number" min={0} max={300}>
    Request timeout in seconds (default: 30).
  </Property>
</Properties>

Badge

Displays small status badges:

import {Badge} from "@/components/mdx"

<Badge>New</Badge>
<Badge variant="secondary">Beta</Badge>

Code Blocks

Code syntax highlighting (automatically available):

\`\`\`bash
npm install
npm run dev
\`\`\`

// Or use code groups for multiple languages
<CodeGroup>
  ```bash title="Installation"
  npm install
yarn install
```

Thank you

NetBird thrives on community participation, and we appreciate your contributions to our website and our documentation!

Description
No description provided
Readme BSD-3-Clause 310 MiB
Languages
MDX 91.2%
JavaScript 7.7%
TypeScript 0.5%
Shell 0.3%
CSS 0.1%