diff options
| author | Supremist <sergkarv@gmail.com> | 2026-04-17 15:53:28 +0300 |
|---|---|---|
| committer | Supremist <sergkarv@gmail.com> | 2026-04-17 15:53:28 +0300 |
| commit | 808c7e74b1455d0f9fc316c5b5756adb097421ac (patch) | |
| tree | c974dd7d7115bb6a37d04b0cbbe69d8558dd6d47 /docker-compose.yml | |
| download | netbird-808c7e74b1455d0f9fc316c5b5756adb097421ac.tar.xz netbird-808c7e74b1455d0f9fc316c5b5756adb097421ac.zip | |
Initial commit
Diffstat (limited to 'docker-compose.yml')
| -rw-r--r-- | docker-compose.yml | 152 |
1 files changed, 152 insertions, 0 deletions
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 |
