From a61351a210081031e0148a8a0e05ea3718814aca Mon Sep 17 00:00:00 2001 From: Kacper Date: Tue, 10 Mar 2026 11:06:14 +0100 Subject: [PATCH] prod version --- .gitignore | 10 +++ README.md | 108 +++++++++++++++++++++++ compose.yaml | 122 ++++++++++++++++++++++++++ netbird/configs/config.yaml.example | 29 ++++++ netbird/configs/dashboard.env.example | 17 ++++ prometheus/prometheus.yml | 7 ++ traefik/dynamic/dynamic.yml | 0 traefik/traefik.env.example | 2 + traefik/traefik.yml | 81 +++++++++++++++++ 9 files changed, 376 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 compose.yaml create mode 100644 netbird/configs/config.yaml.example create mode 100644 netbird/configs/dashboard.env.example create mode 100644 prometheus/prometheus.yml create mode 100644 traefik/dynamic/dynamic.yml create mode 100644 traefik/traefik.env.example create mode 100644 traefik/traefik.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c04f291 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# secrets +.env + +# generated configs +.yaml + +# Data +netbird/data/ +traefik/acme/ +prometheus/data/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..bf03682 --- /dev/null +++ b/README.md @@ -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: "" +encryptionKey: "" +``` + +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 Let’s Encrypt. +* Katalog `netbird/data/` przechowuje dane NetBird Controller / Management. +* Traefik ładuje reguły dynamiczne z `traefik/dynamic/dynamic.yml`. + + diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..ca53fe5 --- /dev/null +++ b/compose.yaml @@ -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 \ No newline at end of file diff --git a/netbird/configs/config.yaml.example b/netbird/configs/config.yaml.example new file mode 100644 index 0000000..67e26c8 --- /dev/null +++ b/netbird/configs/config.yaml.example @@ -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 diff --git a/netbird/configs/dashboard.env.example b/netbird/configs/dashboard.env.example new file mode 100644 index 0000000..d798d86 --- /dev/null +++ b/netbird/configs/dashboard.env.example @@ -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 diff --git a/prometheus/prometheus.yml b/prometheus/prometheus.yml new file mode 100644 index 0000000..fd4d826 --- /dev/null +++ b/prometheus/prometheus.yml @@ -0,0 +1,7 @@ +global: + scrape_interval: 15s + +scrape_configs: + - job_name: "netbird-server" + static_configs: + - targets: ["netbird-server:9090"] diff --git a/traefik/dynamic/dynamic.yml b/traefik/dynamic/dynamic.yml new file mode 100644 index 0000000..e69de29 diff --git a/traefik/traefik.env.example b/traefik/traefik.env.example new file mode 100644 index 0000000..ff9d291 --- /dev/null +++ b/traefik/traefik.env.example @@ -0,0 +1,2 @@ +# Netbird hostname +HOSTNAME=vpn.example.com \ No newline at end of file diff --git a/traefik/traefik.yml b/traefik/traefik.yml new file mode 100644 index 0000000..505349d --- /dev/null +++ b/traefik/traefik.yml @@ -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 \ No newline at end of file