feat(remote-speakers): enhance remote speaker management and API integration
CI / changes (push) Successful in 8s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 25s
CI / web (push) Failing after 34s
CI / go (push) Failing after 19s
CI / bird2 (push) Has been skipped
CI / release (push) Has been skipped

- Added support for remote speaker configuration in the README and documentation.
- Implemented a new endpoint for retrieving the bundle signing public key.
- Updated the `evobgp-agent` to include a `serve` command for Panel→Node sync API.
- Enhanced CI workflow to validate remote speaker compose files.
- Introduced new fields in the API and UI for managing speaker metadata, including dispatch status and sync status.
- Improved error handling and response formatting in speaker-related API endpoints.
- Updated documentation to reflect changes in remote speaker functionality and usage guidelines.
This commit is contained in:
Denozordec
2026-05-21 12:42:06 +07:00
parent ec65249bf1
commit 2aecbf96fd
29 changed files with 2003 additions and 63 deletions
@@ -0,0 +1,157 @@
# Удалённый BGP-спикер (Remnawave-style): bird2 + evobgp-agent + Traefik (LE).
# См. docs/remote-speakers.md
#
# cp .env.remote-speaker.example .env.remote-speaker
# cp .env.remote-speaker-tls.example .env.remote-speaker-tls
# docker compose -f docker-compose.remote-speaker.yaml \
# --env-file .env.remote-speaker --env-file .env.remote-speaker-tls up -d
#
# Profiles:
# production (default) — bird2 host + agent + evobgp-edge
# plain — bird2 + agent без Traefik (lab)
# fallback — + sync-bundle polling
name: evobgp-remote-speaker
x-logging: &default-logging
driver: json-file
options:
max-size: "10m"
max-file: "3"
services:
bird2:
profiles: ["production", "plain", "fallback"]
image: ${EVOBGP_REGISTRY:-git.shts.su/denozord}/evobgp-bird2:${EVOBGP_IMAGE_TAG:-latest}
restart: unless-stopped
network_mode: host
cap_add:
- NET_ADMIN
sysctls:
net.ipv4.ip_forward: "1"
net.ipv6.conf.all.forwarding: "1"
volumes:
- bird_etc:/etc/bird
- bird_run:/run/bird
logging: *default-logging
evobgp-agent:
profiles: ["production"]
image: ${EVOBGP_REGISTRY:-git.shts.su/denozord}/evobgp-agent:${EVOBGP_IMAGE_TAG:-latest}
restart: unless-stopped
depends_on:
- bird2
cap_add:
- NET_ADMIN
environment:
EVOBGP_AGENT_LISTEN: ":8443"
EVOBGP_AGENT_SECRET: ${EVOBGP_AGENT_SECRET:?set EVOBGP_AGENT_SECRET}
EVOBGP_CONTROL_PLANE_URL: ${EVOBGP_CONTROL_PLANE_URL:?set EVOBGP_CONTROL_PLANE_URL}
EVOBGP_NODE_TOKEN: ${EVOBGP_NODE_TOKEN:?set EVOBGP_NODE_TOKEN}
EVOBGP_SPEAKER_ID: ${EVOBGP_SPEAKER_ID:?set EVOBGP_SPEAKER_ID}
EVOBGP_BUNDLE_PUBKEY_BASE64: ${EVOBGP_BUNDLE_PUBKEY_BASE64:?set EVOBGP_BUNDLE_PUBKEY_BASE64}
EVOBGP_BIRD_EXTRACT_DIR: /etc/bird
EVOBGP_BIRDC_SOCKET: /run/bird/bird.ctl
volumes:
- bird_etc:/etc/bird
- bird_run:/run/bird
entrypoint: ["/usr/local/bin/evobgp-agent"]
command: ["serve", "-socket=/run/bird/bird.ctl"]
networks:
- speaker-net
labels:
- traefik.enable=true
- traefik.http.routers.evobgp-agent.rule=Host(`${AGENT_DOMAIN}`)
- traefik.http.routers.evobgp-agent.entrypoints=websecure
- traefik.http.routers.evobgp-agent.tls=true
- traefik.http.routers.evobgp-agent.tls.certresolver=letsencrypt
- traefik.http.routers.evobgp-agent.middlewares=panel-ipwhitelist@docker
- traefik.http.middlewares.panel-ipwhitelist.ipallowlist.sourcerange=${PANEL_IP_WHITELIST}
- traefik.http.services.evobgp-agent.loadbalancer.server.port=8443
logging: *default-logging
evobgp-agent-plain:
profiles: ["plain", "fallback"]
image: ${EVOBGP_REGISTRY:-git.shts.su/denozord}/evobgp-agent:${EVOBGP_IMAGE_TAG:-latest}
restart: unless-stopped
network_mode: host
depends_on:
- bird2
cap_add:
- NET_ADMIN
environment:
EVOBGP_AGENT_LISTEN: "${EVOBGP_AGENT_PORT:-8443}"
EVOBGP_AGENT_SECRET: ${EVOBGP_AGENT_SECRET:?set EVOBGP_AGENT_SECRET}
EVOBGP_CONTROL_PLANE_URL: ${EVOBGP_CONTROL_PLANE_URL:?set EVOBGP_CONTROL_PLANE_URL}
EVOBGP_NODE_TOKEN: ${EVOBGP_NODE_TOKEN:?set EVOBGP_NODE_TOKEN}
EVOBGP_SPEAKER_ID: ${EVOBGP_SPEAKER_ID:?set EVOBGP_SPEAKER_ID}
EVOBGP_BUNDLE_PUBKEY_BASE64: ${EVOBGP_BUNDLE_PUBKEY_BASE64:?set EVOBGP_BUNDLE_PUBKEY_BASE64}
EVOBGP_BIRD_EXTRACT_DIR: /etc/bird
EVOBGP_BIRDC_SOCKET: /run/bird/bird.ctl
volumes:
- bird_etc:/etc/bird
- bird_run:/run/bird
entrypoint: ["/usr/local/bin/evobgp-agent"]
command: ["serve", "-listen=:${EVOBGP_AGENT_PORT:-8443}", "-socket=/run/bird/bird.ctl"]
logging: *default-logging
evobgp-edge:
profiles: ["production"]
image: traefik:latest
restart: unless-stopped
depends_on:
- evobgp-agent
ports:
- "80:80"
- "443:443"
environment:
DOCKER_API_VERSION: "1.44"
CF_DNS_API_TOKEN: ${CF_DNS_API_TOKEN:?set CF_DNS_API_TOKEN}
command:
- --api.dashboard=false
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --certificatesresolvers.letsencrypt.acme.email=${LETSENCRYPT_EMAIL:?set LETSENCRYPT_EMAIL}
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.letsencrypt.acme.dnschallenge=true
- --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare
- --certificatesresolvers.letsencrypt.acme.dnschallenge.delaybeforecheck=15
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik_letsencrypt:/letsencrypt
networks:
- speaker-net
logging: *default-logging
sync-bundle:
profiles: ["fallback"]
image: ${EVOBGP_REGISTRY:-git.shts.su/denozord}/evobgp-node:${EVOBGP_IMAGE_TAG:-latest}
restart: unless-stopped
depends_on:
- bird2
environment:
EVOBGP_CONTROL_PLANE_URL: ${EVOBGP_CONTROL_PLANE_URL:?set EVOBGP_CONTROL_PLANE_URL}
EVOBGP_NODE_TOKEN: ${EVOBGP_NODE_TOKEN:?set EVOBGP_NODE_TOKEN}
EVOBGP_SPEAKER_ID: ${EVOBGP_SPEAKER_ID:?set EVOBGP_SPEAKER_ID}
EVOBGP_BUNDLE_PUBKEY_BASE64: ${EVOBGP_BUNDLE_PUBKEY_BASE64:?set EVOBGP_BUNDLE_PUBKEY_BASE64}
EVOBGP_SYNC_INTERVAL_SEC: ${EVOBGP_SYNC_INTERVAL_SEC:-300}
volumes:
- bird_etc:/etc/bird
- bird_run:/run/bird
- ../../scripts/sync-bundle.sh:/usr/local/bin/sync-bundle.sh:ro
entrypoint: ["/bin/sh", "/usr/local/bin/sync-bundle.sh"]
network_mode: host
logging: *default-logging
networks:
speaker-net:
volumes:
bird_etc:
bird_run:
traefik_letsencrypt:
name: evobgp_speaker_traefik_letsencrypt