291 lines
12 KiB
YAML
291 lines
12 KiB
YAML
services:
|
|
# UI dashboard
|
|
dashboard:
|
|
image: netbirdio/dashboard:latest
|
|
restart: unless-stopped
|
|
networks:
|
|
- netbird
|
|
- traefik_traefik
|
|
env_file:
|
|
- ./dashboard.env
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.docker.network=traefik_default
|
|
- traefik.http.services.netbird-dashboard.loadbalancer.server.port=80
|
|
- traefik.http.routers.netbird-dashboard.rule=Host(`netbird.rozic-dev.com`)
|
|
- 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.priority=50
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "500m"
|
|
max-file: "2"
|
|
|
|
# Signal
|
|
signal:
|
|
image: netbirdio/signal:latest
|
|
restart: unless-stopped
|
|
networks:
|
|
- netbird
|
|
- traefik_traefik
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.docker.network=traefik_default
|
|
- traefik.http.services.netbird-signal.loadbalancer.server.port=10000
|
|
- traefik.http.services.netbird-signal.loadbalancer.server.scheme=h2c
|
|
- traefik.http.routers.netbird-signal.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/signalexchange.SignalExchange/`)
|
|
- traefik.http.routers.netbird-signal.entrypoints=websecure
|
|
- traefik.http.routers.netbird-signal.service=netbird-signal
|
|
- traefik.http.routers.netbird-signal.tls=true
|
|
- traefik.http.routers.netbird-signal.tls.certresolver=letsencrypt
|
|
- traefik.http.routers.netbird-signal.priority=200
|
|
# WebSocket route for signal - pass through without stripping prefix
|
|
- traefik.http.services.netbird-signal-ws.loadbalancer.server.port=80
|
|
- traefik.http.routers.netbird-signal-ws.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/ws-proxy/signal`)
|
|
- traefik.http.routers.netbird-signal-ws.entrypoints=websecure
|
|
- traefik.http.routers.netbird-signal-ws.service=netbird-signal-ws
|
|
- traefik.http.routers.netbird-signal-ws.tls=true
|
|
- traefik.http.routers.netbird-signal-ws.tls.certresolver=letsencrypt
|
|
- traefik.http.routers.netbird-signal-ws.priority=300
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "500m"
|
|
max-file: "2"
|
|
|
|
# Relay
|
|
relay:
|
|
image: netbirdio/relay:latest
|
|
restart: unless-stopped
|
|
networks:
|
|
- netbird
|
|
- traefik_traefik
|
|
env_file:
|
|
- ./relay.env
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.docker.network=traefik_default
|
|
- traefik.http.services.netbird-relay.loadbalancer.server.port=33080
|
|
- traefik.http.routers.netbird-relay.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/relay`)
|
|
- traefik.http.routers.netbird-relay.entrypoints=websecure
|
|
- traefik.http.routers.netbird-relay.tls=true
|
|
- traefik.http.routers.netbird-relay.tls.certresolver=letsencrypt
|
|
- traefik.http.routers.netbird-relay.priority=200
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "500m"
|
|
max-file: "2"
|
|
|
|
# Management
|
|
management:
|
|
image: netbirdio/management:latest
|
|
restart: unless-stopped
|
|
networks:
|
|
- netbird
|
|
- traefik_traefik
|
|
volumes:
|
|
- netbird_management:/var/lib/netbird
|
|
- ./management.json:/etc/netbird/management.json
|
|
command: [
|
|
"--port", "80",
|
|
"--log-file", "console",
|
|
"--log-level", "info",
|
|
"--disable-anonymous-metrics=false",
|
|
"--single-account-mode-domain=netbird.selfhosted",
|
|
"--dns-domain=netbird.selfhosted",
|
|
"--idp-sign-key-refresh-enabled"
|
|
]
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.docker.network=traefik_default
|
|
- traefik.http.services.netbird-management.loadbalancer.server.port=80
|
|
- traefik.http.services.netbird-management-grpc.loadbalancer.server.port=80
|
|
- traefik.http.services.netbird-management-grpc.loadbalancer.server.scheme=h2c
|
|
# REST API
|
|
- traefik.http.routers.netbird-api.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/api`)
|
|
- traefik.http.routers.netbird-api.entrypoints=websecure
|
|
- traefik.http.routers.netbird-api.service=netbird-management
|
|
- traefik.http.routers.netbird-api.tls=true
|
|
- traefik.http.routers.netbird-api.tls.certresolver=letsencrypt
|
|
- traefik.http.routers.netbird-api.priority=200
|
|
# gRPC
|
|
- traefik.http.routers.netbird-management-grpc.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/management.ManagementService/`)
|
|
- traefik.http.routers.netbird-management-grpc.entrypoints=websecure
|
|
- traefik.http.routers.netbird-management-grpc.service=netbird-management-grpc
|
|
- traefik.http.routers.netbird-management-grpc.tls=true
|
|
- traefik.http.routers.netbird-management-grpc.tls.certresolver=letsencrypt
|
|
- traefik.http.routers.netbird-management-grpc.priority=200
|
|
# WebSocket route for management
|
|
- traefik.http.routers.netbird-management-ws.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/ws-proxy/management`)
|
|
- traefik.http.routers.netbird-management-ws.entrypoints=websecure
|
|
- traefik.http.routers.netbird-management-ws.service=netbird-management
|
|
- traefik.http.routers.netbird-management-ws.tls=true
|
|
- traefik.http.routers.netbird-management-ws.tls.certresolver=letsencrypt
|
|
- traefik.http.routers.netbird-management-ws.priority=300
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "500m"
|
|
max-file: "2"
|
|
|
|
# Coturn
|
|
coturn:
|
|
image: coturn/coturn
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ./turnserver.conf:/etc/turnserver.conf:ro
|
|
network_mode: host
|
|
command:
|
|
- -c /etc/turnserver.conf
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "500m"
|
|
max-file: "2"
|
|
|
|
# Zitadel - identity provider
|
|
zitadel:
|
|
restart: 'always'
|
|
image: 'ghcr.io/zitadel/zitadel:v2.59.3'
|
|
command: 'start-from-init --masterkeyFromEnv --tlsMode external'
|
|
ports:
|
|
- "8085:8080" # <-- added
|
|
env_file:
|
|
- ./zitadel.env
|
|
environment:
|
|
ZITADEL_PROJECTIONS_MAXFAILURES: "3"
|
|
ZITADEL_PROJECTIONS_RETRYDELAY: "2s"
|
|
ZITADEL_PROJECTIONS_MAXPARALLELPROJECTIONS: "4"
|
|
ZITADEL_PROJECTIONS_TARGETS1_PARALLEL_PREFILLS: "2"
|
|
ZITADEL_PROJECTIONS_TARGETS1_BATCHSIZE: "500"
|
|
depends_on:
|
|
zdb:
|
|
condition: 'service_healthy'
|
|
volumes:
|
|
- ./machinekey:/machinekey
|
|
- netbird_zitadel_certs:/zdb-certs:ro
|
|
networks:
|
|
- netbird
|
|
- traefik_traefik
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.docker.network=traefik_default
|
|
- traefik.http.services.zitadel.loadbalancer.server.port=8080
|
|
- traefik.http.services.zitadel.loadbalancer.server.scheme=h2c
|
|
# OIDC wellknown
|
|
- traefik.http.routers.zitadel-wellknown.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/.well-known`)
|
|
- traefik.http.routers.zitadel-wellknown.entrypoints=websecure
|
|
- traefik.http.routers.zitadel-wellknown.service=zitadel
|
|
- traefik.http.routers.zitadel-wellknown.priority=300
|
|
- traefik.http.routers.zitadel-wellknown.tls=true
|
|
- traefik.http.routers.zitadel-wellknown.tls.certresolver=letsencrypt
|
|
# OAuth
|
|
- traefik.http.routers.zitadel-oauth.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/oauth`)
|
|
- traefik.http.routers.zitadel-oauth.entrypoints=websecure
|
|
- traefik.http.routers.zitadel-oauth.service=zitadel
|
|
- traefik.http.routers.zitadel-oauth.priority=300
|
|
- traefik.http.routers.zitadel-oauth.tls=true
|
|
- traefik.http.routers.zitadel-oauth.tls.certresolver=letsencrypt
|
|
# OIDC
|
|
- traefik.http.routers.zitadel-oidc.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/oidc`)
|
|
- traefik.http.routers.zitadel-oidc.entrypoints=websecure
|
|
- traefik.http.routers.zitadel-oidc.service=zitadel
|
|
- traefik.http.routers.zitadel-oidc.priority=300
|
|
- traefik.http.routers.zitadel-oidc.tls=true
|
|
- traefik.http.routers.zitadel-oidc.tls.certresolver=letsencrypt
|
|
# UI Console
|
|
- traefik.http.routers.zitadel-ui.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/ui`)
|
|
- traefik.http.routers.zitadel-ui.entrypoints=websecure
|
|
- traefik.http.routers.zitadel-ui.service=zitadel
|
|
- traefik.http.routers.zitadel-ui.priority=300
|
|
- traefik.http.routers.zitadel-ui.tls=true
|
|
- traefik.http.routers.zitadel-ui.tls.certresolver=letsencrypt
|
|
# Device flow
|
|
- traefik.http.routers.zitadel-device.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/device`)
|
|
- traefik.http.routers.zitadel-device.entrypoints=websecure
|
|
- traefik.http.routers.zitadel-device.service=zitadel
|
|
- traefik.http.routers.zitadel-device.priority=300
|
|
- traefik.http.routers.zitadel-device.tls=true
|
|
- traefik.http.routers.zitadel-device.tls.certresolver=letsencrypt
|
|
# Management API
|
|
- traefik.http.routers.zitadel-mgmt.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/management/v1`)
|
|
- traefik.http.routers.zitadel-mgmt.entrypoints=websecure
|
|
- traefik.http.routers.zitadel-mgmt.service=zitadel
|
|
- traefik.http.routers.zitadel-mgmt.priority=300
|
|
- traefik.http.routers.zitadel-mgmt.tls=true
|
|
- traefik.http.routers.zitadel-mgmt.tls.certresolver=letsencrypt
|
|
# Admin API
|
|
- traefik.http.routers.zitadel-admin.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/admin/v1`)
|
|
- traefik.http.routers.zitadel-admin.entrypoints=websecure
|
|
- traefik.http.routers.zitadel-admin.service=zitadel
|
|
- traefik.http.routers.zitadel-admin.priority=300
|
|
- traefik.http.routers.zitadel-admin.tls=true
|
|
- traefik.http.routers.zitadel-admin.tls.certresolver=letsencrypt
|
|
# gRPC endpoints
|
|
- traefik.http.routers.zitadel-grpc-auth.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/zitadel.auth.v1.AuthService/`)
|
|
- traefik.http.routers.zitadel-grpc-auth.entrypoints=websecure
|
|
- traefik.http.routers.zitadel-grpc-auth.service=zitadel
|
|
- traefik.http.routers.zitadel-grpc-auth.priority=400
|
|
- traefik.http.routers.zitadel-grpc-auth.tls=true
|
|
- traefik.http.routers.zitadel-grpc-auth.tls.certresolver=letsencrypt
|
|
- traefik.http.routers.zitadel-grpc-admin.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/zitadel.admin.v1.AdminService/`)
|
|
- traefik.http.routers.zitadel-grpc-admin.entrypoints=websecure
|
|
- traefik.http.routers.zitadel-grpc-admin.service=zitadel
|
|
- traefik.http.routers.zitadel-grpc-admin.priority=400
|
|
- traefik.http.routers.zitadel-grpc-admin.tls=true
|
|
- traefik.http.routers.zitadel-grpc-admin.tls.certresolver=letsencrypt
|
|
- traefik.http.routers.zitadel-grpc-mgmt.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/zitadel.management.v1.ManagementService/`)
|
|
- traefik.http.routers.zitadel-grpc-mgmt.entrypoints=websecure
|
|
- traefik.http.routers.zitadel-grpc-mgmt.service=zitadel
|
|
- traefik.http.routers.zitadel-grpc-mgmt.priority=400
|
|
- traefik.http.routers.zitadel-grpc-mgmt.tls=true
|
|
- traefik.http.routers.zitadel-grpc-mgmt.tls.certresolver=letsencrypt
|
|
# === CRITICAL ROUTE: /auth/v1 for PAT + wait_api ===
|
|
- traefik.http.routers.zitadel-auth-v1.rule=Host(`netbird.rozic-dev.com`) && PathPrefix(`/auth/v1`)
|
|
- traefik.http.routers.zitadel-auth-v1.entrypoints=websecure
|
|
- traefik.http.routers.zitadel-auth-v1.service=zitadel
|
|
- traefik.http.routers.zitadel-auth-v1.tls=true
|
|
- traefik.http.routers.zitadel-auth-v1.tls.certresolver=letsencrypt
|
|
- traefik.http.routers.zitadel-auth-v1.priority=950
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "500m"
|
|
max-file: "2"
|
|
|
|
# Postgres for Zitadel
|
|
zdb:
|
|
restart: 'always'
|
|
networks: [netbird]
|
|
image: 'postgres:15-alpine'
|
|
env_file:
|
|
- ./zdb.env
|
|
volumes:
|
|
- netbird_zdb_data:/var/lib/postgresql/data:rw
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U root"]
|
|
interval: 5s
|
|
timeout: 60s
|
|
retries: 10
|
|
start_period: 5s
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "500m"
|
|
max-file: "2"
|
|
|
|
volumes:
|
|
netbird_zdb_data:
|
|
netbird_management:
|
|
netbird_zitadel_certs:
|
|
|
|
networks:
|
|
netbird:
|
|
driver: bridge
|
|
traefik_traefik:
|
|
external: true
|
|
name: traefik_default
|