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