Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/pages/selfhosted/enterprise/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ The script prompts for:

It then generates the deployment files, pulls the required images, starts Postgres, waits for it to become ready, and starts the remaining services.

The stack runs on a dedicated Docker bridge network, `172.30.0.0/24` by default, with the gateway at `172.30.0.1` and Traefik pinned to `172.30.0.10`. If that range is already used on the host, override it before running the script:

```bash
curl -fsSL https://pkgs.netbird.io/getting-started-enterprise.sh | NETBIRD_DOCKER_SUBNET=10.123.45.0/24 bash
```

The value must be a `/24` ending in `.0`. The gateway (`.1`) and Traefik's static address (`.10`) are derived from it, and the `reverseProxy.trustedPeers` and `reverseProxy.trustedHTTPProxies` `/32` pins in `config.yaml` are kept in step with that address. `0.0.0.0/8`, `127.0.0.0/8`, `169.254.0.0/16`, `224.0.0.0` and above, and `100.64.0.0/10` are rejected — the last because NetBird assigns overlay peer addresses from that range.

The subnet and gateway are written to `.env` as `NETBIRD_NETWORK_SUBNET` and `NETBIRD_NETWORK_GATEWAY`, and Traefik's address as `NETBIRD_TRAEFIK_IP`. These must stay in step with the trust pins in `config.yaml`; if you change one by hand, change all of them.

Before writing any files, the script checks the existing Docker networks and aborts with an actionable error if one overlaps the chosen subnet, rather than letting `docker compose up` fail later. Existing networks are never modified.

<Note>
Enabling traffic flow adds NATS, a flow receiver, and a flow enricher to the stack. Traffic flow is required for traffic event logging and streaming.
</Note>
Expand Down Expand Up @@ -86,6 +98,8 @@ The combined stack:
| `postgres` | `postgres:17` | Datastore for management, embedded IdP, traffic events |
| `netbird-server` | `ghcr.io/netbirdio/netbird-server-cloud:latest` | Management + signal + relay + embedded STUN on UDP/3478 |

Traefik also carries a Docker network alias for your public NetBird domain. `netbird-server` dials that domain over HTTPS to deliver traffic flow events, and on hosts behind NAT the hairpin back to the public address can fail. The alias resolves the domain to Traefik from inside the Compose network, so that request never leaves the host. No DNS or firewall change is needed, and external clients are unaffected.

Enabling traffic flow adds:

| Service | Image | Notes |
Expand Down Expand Up @@ -254,6 +268,13 @@ Each entry follows the same structure: **Symptom → Cause → Resolution → Ve
- **Resolution:** Run `docker compose ps`; if `postgres` isn't `healthy`, check `docker compose logs postgres`, then confirm the DSN uses host `postgres` with a matching user, database, and password.
- **Verification:** `docker compose ps` shows `postgres` as `healthy`; the server connects once on startup with no connection-refused loop.

### Script aborts on a Docker network conflict

- **Symptom:** The script exits before generating any files, reporting either that an existing Docker network overlaps the subnet NetBird would use, or that the `netbird` network left over from a previous install sits on a different subnet.
- **Cause:** The stack pins a fixed subnet (`172.30.0.0/24` by default) so Traefik gets a stable address the server can trust. The script checks this up front so you get a clear error instead of a `Pool overlaps with other one on this address space` failure during `docker compose up`. A leftover `netbird` network on a different subnet is also fatal, because Compose would reuse it as-is and the generated configuration would no longer match it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use “default” instead of “fixed”.

NETBIRD_DOCKER_SUBNET makes the subnet configurable. The current wording conflicts with the override documented in Line 275. Use “deterministic subnet” or “default subnet”.

🧰 Tools
🪛 LanguageTool

[grammar] ~274-~274: Ensure spelling is correct
Context: ...t so you get a clear error instead of a Pool overlaps with other one on this address space failure duri...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/selfhosted/enterprise/getting-started.mdx` at line 274, Update the
Cause text near the NETBIRD_DOCKER_SUBNET documentation to replace “fixed
subnet” with “default subnet” or “deterministic subnet,” while preserving the
explanation of stable addressing and subnet validation.

- **Resolution:** For an overlap with an unrelated network, pick a free `/24` — the conflicting network is never modified: `curl -fsSL https://pkgs.netbird.io/getting-started-enterprise.sh | NETBIRD_DOCKER_SUBNET=10.123.45.0/24 bash`. For a leftover NetBird network, remove it with `docker network rm netbird` and re-run.
- **Verification:** The script proceeds past the network check; `docker network inspect netbird` reports the subnet you chose, and `docker inspect netbird-traefik` shows Traefik holding the `.10` address in that range.

### Traefik cannot issue a TLS certificate

- **Symptom:** HTTPS to the dashboard is unreachable or shows a TLS error; `docker compose logs traefik` shows ACME challenge failures.
Expand Down
20 changes: 20 additions & 0 deletions src/pages/selfhosted/environment-variables.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@ NetBird uses two types of environment variables:
1. **Setup Variables** (`NETBIRD_` prefix) - Used in docker-compose templates and `setup.env` for initial configuration
2. **Runtime Variables** (`NB_` prefix) - Can override CLI flags at runtime using the pattern `--flag-name` → `NB_FLAG_NAME`

## Installation Script Variables

These are read from the shell environment by the install and migration scripts (`getting-started.sh`, `getting-started-enterprise.sh`, `migrate.sh`), not from `setup.env`. Pass them on the command line when you run the script.

| Variable | Default | Description |
|----------|---------|-------------|
| `NETBIRD_DOCKER_SUBNET` | `172.30.0.0/24` | The `/24` used for the generated Docker bridge network. The gateway (`.1`) and Traefik's static address (`.10`) are derived from it, along with the trusted-proxy pins in the generated server configuration. |

```bash
curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | NETBIRD_DOCKER_SUBNET=10.123.45.0/24 bash
```

The value must be a `/24` ending in `.0`. `0.0.0.0/8`, `127.0.0.0/8`, `169.254.0.0/16`, `224.0.0.0` and above, and `100.64.0.0/10` are rejected — the last because NetBird assigns overlay peer addresses from that range, so a Docker bridge there would shadow your NetBird network.

Before writing any files, the scripts check the existing Docker networks and stop with an actionable error if one overlaps the chosen subnet, instead of failing later during `docker compose up`. Existing networks are never modified. Host routes such as LANs and VPN tunnels are not inspected — use this variable if the default range collides with one of those.
Comment on lines +30 to +32

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Qualify the “before writing any files” claim.

migrate.sh creates backup and rollback files and stops the old containers before its Docker overlap check. The current sentence applies to all three scripts and can make an aborted migration appear side-effect free. Limit the claim to fresh-install generated files, or document the migration order.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/selfhosted/environment-variables.mdx` around lines 30 - 32, Qualify
the “Before writing any files” statement to apply only to fresh-install
generated files, rather than all scripts. Ensure the documentation does not
imply migrations are side-effect free before the Docker overlap check;
alternatively, document that migrate.sh creates backup/rollback files and stops
old containers first.


<Note>
If a run stops on a network conflict, see [Script exits with a Docker network conflict](/selfhosted/troubleshooting/installation#script-exits-with-a-docker-network-conflict).
</Note>

## Core Setup Variables

These variables are set in your `setup.env` file before running the configuration script.
Expand Down
40 changes: 39 additions & 1 deletion src/pages/selfhosted/migration/combined-container.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ The script runs through four phases automatically:

The script operates in one of two modes depending on your detected reverse proxy:

**Automatic (embedded Caddy setups).** If your old deployment uses the embedded Caddy proxy (the default from `configure.sh` or `getting-started.sh`), the script performs the full migration end-to-end. It stops old containers, generates a Traefik-based `docker-compose.yml`, and starts the new stack. The generated compose file creates a Docker network (`172.30.0.0/24`) with Traefik at `172.30.0.10`, and reuses your existing management volume if detected.
**Automatic (embedded Caddy setups).** If your old deployment uses the embedded Caddy proxy (the default from `configure.sh` or `getting-started.sh`), the script performs the full migration end-to-end. It stops old containers, generates a Traefik-based `docker-compose.yml`, and starts the new stack. The generated compose file creates a Docker network `172.30.0.0/24` by default, with Traefik at `172.30.0.10`and reuses your existing management volume if detected. Set [`NETBIRD_DOCKER_SUBNET`](#environment-variables) if that range is already in use on your host.

**Manual (external proxy setups).** If your deployment uses a custom or external reverse proxy (Nginx, HAProxy, etc.), the script generates the configuration files but does **not** stop or start any containers. You must handle the cutover yourself, including updating your proxy routing rules.

Expand Down Expand Up @@ -174,6 +174,22 @@ curl -sk -o /dev/null -w '%{http_code}' https://your-domain/api/accounts
| `--non-interactive` | Skip all confirmation prompts. Useful for automation and CI pipelines. |
| `-h`, `--help` | Display usage information and exit. |

### Environment variables

| Variable | Default | Description |
|---|---|---|
| `NETBIRD_DOCKER_SUBNET` | `172.30.0.0/24` | The `/24` used for the generated Docker network. Traefik takes `.10` and the gateway `.1`. Must end in `.0`; `0.0.0.0/8`, `127.0.0.0/8`, `169.254.0.0/16`, `224.0.0.0` and above, and `100.64.0.0/10` are rejected. |

```bash
NETBIRD_DOCKER_SUBNET=10.123.45.0/24 ./migrate.sh --install-dir /opt/netbird
```

Validation runs during preflight, so an invalid value fails before anything on the host is touched. The overlap check against existing Docker networks runs after the old containers are stopped, since `compose down` releases the old deployment's own network first.

<Note>
The migration script carries the `reverseProxy` trust pins over from your old `management.json` unchanged. If that configuration already pinned an address inside `172.30.0.0/24`, overriding the subnet will not rewrite the pin — review `config.yaml` after the migration.
</Note>
Comment on lines +177 to +191

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Keep NETBIRD_DOCKER_SUBNET and reverse-proxy trust pins consistent.

The shared reference says the variable derives the pins, but the migration page says migrate.sh preserves old pins. A migrated deployment can therefore place Traefik at <new-subnet>.10 while config.yaml still trusts the old proxy address.

  • src/pages/selfhosted/migration/combined-container.mdx#L177-L191: Update both trust-pin lists or document the exact manual changes for the new Traefik /32.
  • src/pages/selfhosted/environment-variables.mdx#L20-L24: State the migrate.sh exception and link to the manual pin-update procedure.
📍 Affects 2 files
  • src/pages/selfhosted/migration/combined-container.mdx#L177-L191 (this comment)
  • src/pages/selfhosted/environment-variables.mdx#L20-L24
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/selfhosted/migration/combined-container.mdx` around lines 177 -
191, Update src/pages/selfhosted/migration/combined-container.mdx lines 177-191
to keep both reverse-proxy trust-pin lists consistent with
NETBIRD_DOCKER_SUBNET, or document the exact manual changes required to replace
the old proxy address with the new Traefik /32. Update
src/pages/selfhosted/environment-variables.mdx lines 20-24 to state the
migrate.sh exception and link to that manual pin-update procedure.


## Troubleshooting

### Script exits with "External IdP detected"
Expand All @@ -188,6 +204,28 @@ This means the installation directory already contains a `config.yaml` file, whi
mv config.yaml config.yaml.bak
```

### Script exits with a Docker network conflict

The script stops if an existing Docker network overlaps the subnet it is about to use, or if a leftover NetBird network sits on a different subnet than the one being generated. Both checks happen before the new `docker-compose.yml` is written.

Because this check runs after the old containers are stopped, the old deployment is down at that point. The error output includes the rollback command to bring it back:

```bash
bash <backup-dir>/rollback.sh
```
Comment on lines +213 to +215

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use shell-safe placeholders in the commands.

bash <backup-dir>/rollback.sh and docker network rm <network-name> use shell redirection syntax. Replace them with safe placeholders such as /path/to/backup-dir/rollback.sh and NETWORK_NAME, or show the exact values produced by the script.

Also applies to: 223-227

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/selfhosted/migration/combined-container.mdx` around lines 213 -
215, Update the command examples in the migration documentation, including the
rollback command and docker network removal command, to replace angle-bracket
placeholders that shell interprets as redirection with shell-safe path or
variable-style placeholders such as /path/to/backup-dir/rollback.sh and
NETWORK_NAME.


Then either pick a free `/24` and re-run:

```bash
NETBIRD_DOCKER_SUBNET=10.123.45.0/24 ./migrate.sh --install-dir /opt/netbird
```

Or, if the reported network belongs to the old NetBird deployment and is no longer in use, remove it and re-run:

```bash
docker network rm <network-name>
```

### Script cannot detect the installation directory

If the script cannot find `management.json` in any of the default locations (`$PWD`, `/opt/netbird`, `/opt/wiretrustee`), use the `--install-dir` flag to specify the path explicitly:
Expand Down
10 changes: 10 additions & 0 deletions src/pages/selfhosted/selfhosted-quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting
Once finished, you can manage the resources via `docker compose`. The quick start script generates a full, production-ready NetBird installation. If you'd like to customize the install or gain a better understanding of the files
generated by the script, including the docker compose file, please refer to our [Configuration files](/selfhosted/maintenance/configuration-files) guide.

### Docker Network Subnet

The services run on their own Docker bridge network, `172.30.0.0/24` by default. If that range is already in use on your host, override it when you run the script:

```bash
curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | NETBIRD_DOCKER_SUBNET=10.123.45.0/24 bash
```

The script stops with a clear error if an existing Docker network overlaps the range it is about to use. See [Installation Script Variables](/selfhosted/environment-variables#installation-script-variables) for accepted values.

### Reverse Proxy Selection

The script will prompt you to select a reverse proxy option:
Expand Down
32 changes: 32 additions & 0 deletions src/pages/selfhosted/troubleshooting/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,38 @@ A valid response is JSON containing `"issuer"`. Anything else points to where to

**Confirm**: The probe succeeds and the script continues on its own. You can leave it waiting while you debug. To start over instead, stop it with Ctrl+C, run `docker compose down -v`, fix the issue, and re-run.

## Script exits with a Docker network conflict

**Symptom**: The script stops before generating any files, with one of these two errors:

```
ERROR: the existing Docker network 'some-network' (172.30.0.0/16) overlaps 172.30.0.0/24, the subnet NetBird would use.
```

```
ERROR: the Docker network 'netbird_netbird', left over from a previous NetBird install, uses 172.16.0.0/24 instead of 172.30.0.0/24.
```

**Cause**: NetBird's Compose network defaults to `172.30.0.0/24`. The script checks this up front so you get a clear error here rather than a `Pool overlaps with other one on this address space` failure later in `docker compose up`.

The first error means an unrelated Docker network already covers that range. The second means a network from an earlier NetBird install is still present on a *different* subnet — Compose would reuse it as-is, and the generated configuration would not match it.

**Fix**: For the first error, pick a free `/24` and re-run. The conflicting network belongs to something else, so the script never touches it:

```bash
NETBIRD_DOCKER_SUBNET=10.123.45.0/24 ./getting-started.sh
```
Comment on lines +72 to +76

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the rerun command match the installation flow.

The quickstart downloads getting-started.sh through a pipe. It does not create ./getting-started.sh. This command fails unless the user separately downloads the file. Use the same pipe command with NETBIRD_DOCKER_SUBNET, or add a download step.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/selfhosted/troubleshooting/installation.mdx` around lines 72 - 76,
Update the rerun command in the troubleshooting installation instructions to
match the quickstart’s piped download flow by setting NETBIRD_DOCKER_SUBNET
while downloading and executing getting-started.sh through the pipe. Do not
reference a local ./getting-started.sh file unless the instructions explicitly
add a preceding download step.


For the second error, remove the stale NetBird network and re-run:

```bash
docker network rm netbird_netbird
```

The subnet must be a `/24` ending in `.0`. See [Installation Script Variables](/selfhosted/environment-variables#installation-script-variables) for the full list of rejected ranges, including `100.64.0.0/10`, which NetBird uses for overlay peer addresses.

**Confirm**: Re-run the script; it proceeds past the network check and starts provisioning. Verify the result with `docker network inspect <project>_netbird`, which should report the subnet you chose.

Comment on lines +78 to +87

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use the network name reported by the script.

The command hard-codes netbird_netbird, but Line 86 uses the project-dependent form <project>_netbird. Use the exact network name from the error output and state that the name depends on the Compose project.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/selfhosted/troubleshooting/installation.mdx` around lines 78 - 87,
Update the Docker network removal command in the troubleshooting instructions to
use the exact network name reported by the script instead of hard-coding
netbird_netbird, and state that the name depends on the Docker Compose project.

## Script fails on existing installation check

**Symptom**: The script exits immediately with a message about generated files already existing.
Expand Down
Loading