From 808c7e74b1455d0f9fc316c5b5756adb097421ac Mon Sep 17 00:00:00 2001 From: Supremist Date: Fri, 17 Apr 2026 15:53:28 +0300 Subject: Initial commit --- .gitignore | 4 ++ backup.sh | 23 ++++++++ docker-compose.yml | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++ update.sh | 7 +++ 4 files changed, 186 insertions(+) create mode 100644 .gitignore create mode 100644 backup.sh create mode 100644 docker-compose.yml create mode 100644 update.sh 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 -- cgit v1.2.3