aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--backup.sh23
-rw-r--r--docker-compose.yml152
-rw-r--r--update.sh7
4 files changed, 186 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bf9e8f3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+backup/**
+*.env
+config.yaml
+traefik-dynamic.yaml
diff --git a/backup.sh b/backup.sh
new file mode 100644
index 0000000..2d957e0
--- /dev/null
+++ b/backup.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+DATE="$(date +'%Y-%m-%d_%H-%M-%S')"
+BACKUP_DIR="backup/$DATE"
+
+echo "Creating backup directory: $BACKUP_DIR"
+mkdir -p "$BACKUP_DIR"
+
+echo "Copying compose configuration..."
+cp *.yaml *.yml *.env "$BACKUP_DIR/"
+
+echo "Stopping netbird-server..."
+docker compose stop netbird-server
+
+echo "Copying container data..."
+docker compose cp -a netbird-server:/var/lib/netbird "$BACKUP_DIR/"
+
+echo "Starting netbird-server..."
+docker compose start netbird-server
+
+echo "Backup completed:"
+echo "$BACKUP_DIR"
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..5f8d71d
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,152 @@
+services:
+ # Traefik reverse proxy (automatic TLS via Let's Encrypt)
+ traefik:
+ image: traefik:v3.6
+ container_name: netbird-traefik
+ restart: unless-stopped
+ networks:
+ netbird:
+ ipv4_address: 172.30.0.10
+ command:
+ # Logging
+ - "--log.level=INFO"
+ - "--accesslog=true"
+ # Docker provider
+ - "--providers.docker=true"
+ - "--providers.docker.exposedbydefault=false"
+ - "--providers.docker.network=netbird"
+ # Entrypoints
+ - "--entrypoints.web.address=:80"
+ - "--entrypoints.websecure.address=:443"
+ - "--entrypoints.websecure.allowACMEByPass=true"
+ # Disable timeouts for long-lived gRPC streams
+ - "--entrypoints.websecure.transport.respondingTimeouts.readTimeout=0"
+ - "--entrypoints.websecure.transport.respondingTimeouts.writeTimeout=0"
+ - "--entrypoints.websecure.transport.respondingTimeouts.idleTimeout=0"
+ # HTTP to HTTPS redirect
+ - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
+ - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
+ # Let's Encrypt ACME
+ - "--certificatesresolvers.letsencrypt.acme.email=${LETSENCRYPT_EMAIL}"
+ - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
+ - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
+ # gRPC transport settings
+ - "--serverstransport.forwardingtimeouts.responseheadertimeout=0s"
+ - "--serverstransport.forwardingtimeouts.idleconntimeout=0s"
+ - "--providers.file.filename=/etc/traefik/dynamic.yaml"
+ ports:
+ - '443:443'
+ - '80:80'
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock:ro
+ - netbird_traefik_letsencrypt:/letsencrypt
+ - ./traefik-dynamic.yaml:/etc/traefik/dynamic.yaml:ro
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "500m"
+ max-file: "2"
+
+ # UI dashboard
+ dashboard:
+ image: netbirdio/dashboard:latest
+ container_name: netbird-dashboard
+ restart: unless-stopped
+ networks: [netbird]
+ env_file:
+ - ./dashboard.env
+ labels:
+ - traefik.enable=true
+ - traefik.http.routers.netbird-dashboard.rule=Host(`bird.p2net.cloud`)
+ - traefik.http.routers.netbird-dashboard.entrypoints=websecure
+ - traefik.http.routers.netbird-dashboard.tls=true
+ - traefik.http.routers.netbird-dashboard.tls.certresolver=letsencrypt
+ - traefik.http.routers.netbird-dashboard.service=dashboard
+ - traefik.http.routers.netbird-dashboard.priority=1
+ - traefik.http.services.dashboard.loadbalancer.server.port=80
+ 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: [netbird]
+ ports:
+ - '3478:3478/udp'
+ volumes:
+ - netbird_data:/var/lib/netbird
+ - ./config.yaml:/etc/netbird/config.yaml
+ command: ["--config", "/etc/netbird/config.yaml"]
+ labels:
+ - traefik.enable=true
+ # gRPC router (needs h2c backend for HTTP/2 cleartext)
+ - traefik.http.routers.netbird-grpc.rule=Host(`bird.p2net.cloud`) && (PathPrefix(`/signalexchange.SignalExchange/`) || PathPrefix(`/management.ManagementService/`))
+ - traefik.http.routers.netbird-grpc.entrypoints=websecure
+ - traefik.http.routers.netbird-grpc.tls=true
+ - traefik.http.routers.netbird-grpc.tls.certresolver=letsencrypt
+ - 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(`bird.p2net.cloud`) && (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=letsencrypt
+ - 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
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "500m"
+ max-file: "2"
+
+ # NetBird Proxy - exposes internal resources to the internet
+ proxy:
+ image: netbirdio/reverse-proxy:latest
+ container_name: netbird-proxy
+ ports:
+ - 51820:51820/udp
+ restart: unless-stopped
+ networks: [netbird]
+ depends_on:
+ - netbird-server
+ env_file:
+ - ./proxy.env
+ volumes:
+ - netbird_proxy_certs:/certs
+ labels:
+ # TCP passthrough for any unmatched domain (proxy handles its own TLS)
+ - traefik.enable=true
+ - traefik.tcp.routers.proxy-passthrough.entrypoints=websecure
+ - traefik.tcp.routers.proxy-passthrough.rule=HostSNI(`*`)
+ - traefik.tcp.routers.proxy-passthrough.tls.passthrough=true
+ - traefik.tcp.routers.proxy-passthrough.service=proxy-tls
+ - traefik.tcp.routers.proxy-passthrough.priority=1
+ - traefik.tcp.services.proxy-tls.loadbalancer.server.port=8443
+ - traefik.tcp.services.proxy-tls.loadbalancer.serverstransport=pp-v2@file
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "500m"
+ max-file: "2"
+
+volumes:
+ netbird_data:
+ netbird_traefik_letsencrypt:
+ netbird_proxy_certs:
+
+networks:
+ netbird:
+ driver: bridge
+ ipam:
+ config:
+ - subnet: 172.30.0.0/24
+ gateway: 172.30.0.1
diff --git a/update.sh b/update.sh
new file mode 100644
index 0000000..37bc58d
--- /dev/null
+++ b/update.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+apt update
+apt -y upgrade netbird
+docker compose pull netbird-server dashboard
+docker compose up -d --force-recreate netbird-server dashboard