prod version

This commit is contained in:
2026-03-10 11:06:14 +01:00
commit a61351a210
9 changed files with 376 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
# secrets
.env
# generated configs
.yaml
# Data
netbird/data/
traefik/acme/
prometheus/data/

108
README.md Normal file
View File

@@ -0,0 +1,108 @@
# NetBird + Traefik + Prometheus — Deployment Stack
Ten projekt zawiera gotowy zestaw konfiguracji Docker Compose do uruchomienia:
* **NetBird** prywatna sieć mesh / VPN
* **Traefik** reverse proxy + SSL (Let's Encrypt)
* **Prometheus** monitoring
Repozytorium zawiera przykładowe pliki konfiguracyjne `.example`, które należy skopiować i dostosować przed uruchomieniem infrastruktury.
***
## 📁 Struktura repozytorium
|-- README.md
|-- compose.yaml
|-- netbird
| |-- configs
| | |-- config.yaml.example
| | `-- dashboard.env.example
| `-- data
|-- prometheus
| `-- prometheus.yml
`-- traefik
|-- acme
|-- dynamic
| `-- dynamic.yml
|-- traefik.env.example
`-- traefik.yml
***
## 🚀 Przygotowanie środowiska
### 1. Skopiuj pliki konfiguracyjne
Usuń rozszerzenie `.example`:
```bash
cp netbird/configs/config.yaml.example netbird/configs/config.yaml
cp netbird/configs/dashboard.env.example netbird/configs/dashboard.env
cp traefik/traefik.env.example traefik/traefik.env
```
***
## ✏️ Edycja konfiguracji
### 2. Zamień domenę
W plikach:
* `netbird/configs/config.yaml`
* `netbird/configs/dashboard.env`
* `traefik/traefik.env`
Zamień:
vpn.example.com
na **swoją domenę**, np.:
vpn.twojadomena.pl
***
### 3. Wygeneruj klucze cryptograficzne dla NetBird
W pliku:
`netbird/configs/config.yaml`
Wypełnij:
```yaml
authSecret: "<wygenerowany_secret>"
encryptionKey: "<wygenerowany_klucz>"
```
Użyj generatorów:
```bash
openssl rand -base64 33
```
```bash
openssl rand -base64 32
```
***
## ▶️ Uruchomienie
Po przygotowaniu wszystkich plików:
```bash
docker compose up -d
```
***
## 📌 Dodatkowe informacje
* Katalog `traefik/acme/` zostanie automatycznie wypełniony certyfikatami Lets Encrypt.
* Katalog `netbird/data/` przechowuje dane NetBird Controller / Management.
* Traefik ładuje reguły dynamiczne z `traefik/dynamic/dynamic.yml`.

122
compose.yaml Normal file
View File

@@ -0,0 +1,122 @@
services:
traefik:
image: traefik
container_name: traefik
restart: unless-stopped
ports:
- 80:80
- 443:443/tcp
- 443:443/udp
- 8080:8080
env_file:
- traefik.env
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /etc/localtime:/etc/localtime:ro
- ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
- ./traefik/dynamic/:/etc/traefik/dynamic
- ./traefik/acme:/etc/traefik/acme
networks: [traefik]
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "1"
labels:
# Watchtower auto update
- com.centurylinklabs.watchtower.enable=true
watchtower:
image: nickfedor/watchtower
container_name: watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /etc/localtime:/etc/localtime:ro
environment:
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_LABEL_ENABLE=true
- WATCHTOWER_SCHEDULE=0 1 * * *
network_mode: bridge
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- ./prometheus/data:/prometheus
ports:
- "9090:9090"
networks: [traefik]
labels:
# Watchtower auto update
- com.centurylinklabs.watchtower.enable=true
dashboard:
image: netbirdio/dashboard:latest
container_name: netbird-dashboard
restart: unless-stopped
networks: [traefik]
labels:
- traefik.enable=true
- traefik.http.routers.netbird-dashboard.rule=Host(`${HOSTNAME}`)
- traefik.http.routers.netbird-dashboard.entrypoints=websecure
- traefik.http.routers.netbird-dashboard.tls=true
- traefik.http.routers.netbird-dashboard.tls.certresolver=tls-resolver
- traefik.http.routers.netbird-dashboard.service=dashboard
- traefik.http.routers.netbird-dashboard.priority=10
- traefik.http.services.dashboard.loadbalancer.server.port=80
# Watchtower auto update
- com.centurylinklabs.watchtower.enable=true
env_file:
- ./netbird/configs/dashboard.env
logging:
driver: "json-file"
options:
max-size: "500m"
max-file: "2"
# Combined server (Management + Signal + Relay + STUN)
netbird-server:
image: netbirdio/netbird-server:latest
container_name: netbird-server
restart: unless-stopped
networks: [traefik]
ports:
- "3478:3478/udp"
labels:
- traefik.enable=true
# gRPC router (needs h2c backend for HTTP/2 cleartext)
- traefik.http.routers.netbird-grpc.rule=Host(`${HOSTNAME}`) && (PathPrefix(`/signalexchange.SignalExchange/`) || PathPrefix(`/management.ManagementService/`) || PathPrefix(`/management.ProxyService/`))
- traefik.http.routers.netbird-grpc.entrypoints=websecure
- traefik.http.routers.netbird-grpc.tls=true
- traefik.http.routers.netbird-grpc.tls.certresolver=tls-resolver
- traefik.http.routers.netbird-grpc.service=netbird-server-h2c
- traefik.http.routers.netbird-grpc.priority=100
# Backend router (relay, WebSocket, API, OAuth2)
- traefik.http.routers.netbird-backend.rule=Host(`${HOSTNAME}`) && (PathPrefix(`/relay`) || PathPrefix(`/ws-proxy/`) || PathPrefix(`/api`) || PathPrefix(`/oauth2`))
- traefik.http.routers.netbird-backend.entrypoints=websecure
- traefik.http.routers.netbird-backend.tls=true
- traefik.http.routers.netbird-backend.tls.certresolver=tls-resolver
- traefik.http.routers.netbird-backend.service=netbird-server
- traefik.http.routers.netbird-backend.priority=100
# Services
- traefik.http.services.netbird-server.loadbalancer.server.port=80
- traefik.http.services.netbird-server-h2c.loadbalancer.server.port=80
- traefik.http.services.netbird-server-h2c.loadbalancer.server.scheme=h2c
# Watchtower auto update
- com.centurylinklabs.watchtower.enable=true
volumes:
- ./netbird/data:/var/lib/netbird
- ./netbird/configs/config.yaml:/etc/netbird/config.yaml
command: ["--config", "/etc/netbird/config.yaml"]
logging:
driver: "json-file"
options:
max-size: "500m"
max-file: "2"
networks:
traefik:
external: true

View File

@@ -0,0 +1,29 @@
server:
listenAddress: ":80"
exposedAddress: "https://vpn.example.com:443"
stunPorts:
- 3478
metricsPort: 9090
healthcheckAddress: ":9000"
logLevel: "info"
logFile: "console"
authSecret: "" # openssl rand -base64 33
dataDir: "/var/lib/netbird"
auth:
issuer: "https://vpn.example.com/oauth2"
signKeyRefreshEnabled: true
dashboardRedirectURIs:
- "https://vpn.example.com/nb-auth"
- "https://vpn.example.com/nb-silent-auth"
cliRedirectURIs:
- "http://localhost:53000/"
store:
engine: "sqlite"
encryptionKey: "" # openssl rand -base64 32
# Metrics and updates
disableAnonymousMetrics: true
disableGeoliteUpdate: false

View File

@@ -0,0 +1,17 @@
# Endpoints
NETBIRD_MGMT_API_ENDPOINT=https://vpn.example.com
NETBIRD_MGMT_GRPC_API_ENDPOINT=https://vpn.example.com
# OIDC - using embedded IdP
AUTH_AUDIENCE=netbird-dashboard
AUTH_CLIENT_ID=netbird-dashboard
AUTH_CLIENT_SECRET=
AUTH_AUTHORITY=https://vpn.example.com/oauth2
USE_AUTH0=false
AUTH_SUPPORTED_SCOPES=openid profile email groups
AUTH_REDIRECT_URI=/nb-auth
AUTH_SILENT_REDIRECT_URI=/nb-silent-auth
# SSL - disabled when behind reverse proxy (Traefik handles TLS)
NGINX_SSL_PORT=443
LETSENCRYPT_DOMAIN=none

View File

@@ -0,0 +1,7 @@
global:
scrape_interval: 15s
scrape_configs:
- job_name: "netbird-server"
static_configs:
- targets: ["netbird-server:9090"]

View File

View File

@@ -0,0 +1,2 @@
# Netbird hostname
HOSTNAME=vpn.example.com

81
traefik/traefik.yml Normal file
View File

@@ -0,0 +1,81 @@
################################################################
# Global configuration
################################################################
global:
checkNewVersion: true
sendAnonymousUsage: false
################################################################
# EntryPoints configuration
################################################################
entryPoints:
web:
address: :80
http:
redirections:
entryPoint:
to: "websecure"
scheme: "https"
websecure:
address: :443
http3: {}
forwardedHeaders:
trustedIPs:
- "0.0.0.0/0"
transport:
respondingTimeouts:
idleTimeout: "0s"
readTimeout: "0s"
writeTimeout: "0s"
################################################################
# API and dashboard configuration
################################################################
api:
insecure: true
dashboard: true
################################################################
# Docker configuration backend
################################################################
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: "traefik"
file:
directory: "/etc/traefik/dynamic"
watch: true
providersThrottleDuration: 10
certificatesResolvers:
tls-resolver:
acme:
email: postmaster@example.com
storage: "/etc/traefik/acme/acme.json"
tlsChallenge: {}
################################################################
# Allow HTTPs apps
################################################################
serversTransport:
insecureSkipVerify: true
################################################################
# Logging
################################################################
metrics:
prometheus:
buckets:
- 0.1
- 0.3
- 1.2
- 5.0
addRoutersLabels: true