feat: enhance deployment configuration for secure Web UI with Traefik integration
CI / changes (push) Successful in 6s
CI / openapi (push) Has been skipped
CI / go (push) Has been skipped
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Has been skipped
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Has been skipped
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / docker-go-prime (push) Has been skipped
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Has been skipped
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Has been skipped
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Has been skipped
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Has been skipped
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Has been skipped
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Has been skipped
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Has been skipped
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Has been skipped

Added support for a secure Web UI using Traefik with Let's Encrypt and Cloudflare DNS challenge. Updated docker-compose files to include new service definitions and environment variables for configuration. Improved documentation to guide users in setting up the secure UI environment.
This commit is contained in:
Denozordec
2026-04-07 21:29:19 +07:00
parent 1e77e1a2b8
commit 4acd6857c9
6 changed files with 155 additions and 14 deletions
+3
View File
@@ -3,3 +3,6 @@
EVOBGP_REGISTRY=git.shts.su/denozord
EVOBGP_IMAGE_TAG=latest
# Для защищенного Web UI (Traefik + Let's Encrypt + Cloudflare DNS challenge)
# используйте второй файл рядом: .env.web-sec (шаблон: .env.web-sec.example)
@@ -0,0 +1,14 @@
# Standalone stack env (Linux): stack.microvps-full.yaml
# Использование:
# cp .env.stack.microvps-full.example .env.stack.microvps-full
# docker compose --env-file .env.stack.microvps-full -f stack.microvps-full.yaml up -d
# Образы EvoBGP
EVOBGP_REGISTRY=git.shts.su/denozord
EVOBGP_IMAGE_TAG=latest
# Защищенный Web UI (Traefik + Let's Encrypt + Cloudflare DNS challenge)
WEBUI_DOMAIN=bgp.example.com
WEBUI_IP_WHITELIST=203.0.113.10/32,198.51.100.0/24
LETSENCRYPT_EMAIL=[email protected]
CF_DNS_API_TOKEN=replace_me
+16
View File
@@ -0,0 +1,16 @@
# Параметры защищенного Web UI (Traefik + Let's Encrypt DNS challenge через Cloudflare).
# Используйте вместе с deploy/compose/.env:
# docker compose --env-file .env --env-file .env.web-sec ...
# FQDN для Web UI (A/AAAA запись должна указывать на VPS; Cloudflare: DNS only).
WEBUI_DOMAIN=bgp.example.com
# Разрешенные IP/CIDR (через запятую).
# Пример: один IP + подсеть офиса.
WEBUI_IP_WHITELIST=203.0.113.10/32,198.51.100.0/24
# Email для ACME аккаунта Let's Encrypt.
LETSENCRYPT_EMAIL=[email protected]
# Cloudflare API token с правами Zone:DNS:Edit только на нужную зону.
CF_DNS_API_TOKEN=replace_me
+44 -2
View File
@@ -243,8 +243,15 @@ services:
restart: unless-stopped
depends_on:
- evobgp-all
ports:
- "3000:80"
labels:
- traefik.enable=true
- traefik.http.routers.evobgp-web.rule=Host(`${WEBUI_DOMAIN}`)
- traefik.http.routers.evobgp-web.entrypoints=websecure
- traefik.http.routers.evobgp-web.tls=true
- traefik.http.routers.evobgp-web.tls.certresolver=letsencrypt
- traefik.http.routers.evobgp-web.middlewares=webui-ipwhitelist@docker
- traefik.http.middlewares.webui-ipwhitelist.ipallowlist.sourcerange=${WEBUI_IP_WHITELIST}
- traefik.http.services.evobgp-web.loadbalancer.server.port=80
logging: *default-logging
deploy:
resources:
@@ -252,6 +259,40 @@ services:
cpus: "0.5"
memory: 128M
evobgp-edge:
profiles: ["microvps-full"]
image: traefik:v3.1
restart: unless-stopped
depends_on:
- evobgp-web-microvps
ports:
- "80:80"
- "443:443"
environment:
CF_DNS_API_TOKEN: ${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}
- --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
logging: *default-logging
deploy:
resources:
limits:
cpus: "0.35"
memory: 128M
prometheus-microvps:
profiles: ["microvps-full"]
image: prom/prometheus:v2.54.1
@@ -340,3 +381,4 @@ volumes:
pgdata:
bird_etc:
bird_run:
traefik_letsencrypt:
+49 -5
View File
@@ -3,6 +3,9 @@
# с встроенными configs для Prometheus (как у вас).
#
# Postgres: shm_size + start_period — иначе часто «dependency postgres failed» на слабом хосте.
# Для защищенного Web UI задайте переменные окружения перед запуском:
# WEBUI_DOMAIN, WEBUI_IP_WHITELIST, LETSENCRYPT_EMAIL, CF_DNS_API_TOKEN
# Cloudflare запись для WEBUI_DOMAIN: DNS only (серый облачок).
name: evobgp-microvps-full
configs:
@@ -58,7 +61,7 @@ services:
max-file: "3"
bird2:
image: git.shts.su/denozord/evobgp-bird2:latest
image: ${EVOBGP_REGISTRY:-git.shts.su/denozord}/evobgp-bird2:${EVOBGP_IMAGE_TAG:-latest}
restart: unless-stopped
cap_add:
- NET_ADMIN
@@ -77,7 +80,7 @@ services:
max-file: "3"
evobgp-agent:
image: git.shts.su/denozord/evobgp-agent:latest
image: ${EVOBGP_REGISTRY:-git.shts.su/denozord}/evobgp-agent:${EVOBGP_IMAGE_TAG:-latest}
restart: unless-stopped
depends_on:
bird2:
@@ -96,7 +99,7 @@ services:
max-file: "3"
evobgp-all:
image: git.shts.su/denozord/evobgp-all:latest
image: ${EVOBGP_REGISTRY:-git.shts.su/denozord}/evobgp-all:${EVOBGP_IMAGE_TAG:-latest}
restart: unless-stopped
depends_on:
postgres:
@@ -127,13 +130,53 @@ services:
max-file: "3"
evobgp-web:
image: git.shts.su/denozord/evobgp-web-all:latest
image: ${EVOBGP_REGISTRY:-git.shts.su/denozord}/evobgp-web-all:${EVOBGP_IMAGE_TAG:-latest}
restart: unless-stopped
depends_on:
evobgp-all:
condition: service_started
labels:
- traefik.enable=true
- traefik.http.routers.evobgp-web.rule=Host(`${WEBUI_DOMAIN}`)
- traefik.http.routers.evobgp-web.entrypoints=websecure
- traefik.http.routers.evobgp-web.tls=true
- traefik.http.routers.evobgp-web.tls.certresolver=letsencrypt
- traefik.http.routers.evobgp-web.middlewares=webui-ipwhitelist@docker
- traefik.http.middlewares.webui-ipwhitelist.ipallowlist.sourcerange=${WEBUI_IP_WHITELIST}
- traefik.http.services.evobgp-web.loadbalancer.server.port=80
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
evobgp-edge:
image: traefik:v3.1
restart: unless-stopped
depends_on:
evobgp-web:
condition: service_started
ports:
- "3000:80"
- "80:80"
- "443:443"
environment:
CF_DNS_API_TOKEN: ${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}
- --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
logging:
driver: json-file
options:
@@ -168,3 +211,4 @@ volumes:
pgdata:
bird_etc:
bird_run:
traefik_letsencrypt:
+29 -7
View File
@@ -109,35 +109,57 @@ docker compose --profile microvps down -v
Из каталога `deploy\compose` (как в варианте 1: `.env` из `.env.example`, при необходимости `docker login git.shts.su`):
1. Подготовьте отдельный файл параметров защищенного UI:
```powershell
Copy-Item .env.web-sec.example .env.web-sec -Force
```
2. Заполните в `.env.web-sec`:
- `WEBUI_DOMAIN` — домен панели;
- `WEBUI_IP_WHITELIST` — список разрешенных IP/CIDR через запятую;
- `LETSENCRYPT_EMAIL` — email для ACME;
- `CF_DNS_API_TOKEN` — Cloudflare token для `DNS challenge` (минимальные права `Zone:DNS:Edit` на нужной зоне).
3. В Cloudflare для `WEBUI_DOMAIN` используйте запись в режиме **DNS only** (серый облачок), указывающую на публичный IP VPS.
4. Запускайте compose с двумя env-файлами:
```powershell
# С ужатыми лимитами и EVOBGP_BROKER_URL=nats://… (ориентир под ~1 ГиБ RAM на хосте)
docker compose -f docker-compose.yaml -f docker-compose.microvps-full.yaml --profile microvps-full pull
docker compose -f docker-compose.yaml -f docker-compose.microvps-full.yaml --profile microvps-full up -d
docker compose --env-file .env --env-file .env.web-sec -f docker-compose.yaml -f docker-compose.microvps-full.yaml --profile microvps-full pull
docker compose --env-file .env --env-file .env.web-sec -f docker-compose.yaml -f docker-compose.microvps-full.yaml --profile microvps-full up -d
```
Только профиль `microvps-full` и **без** файла `docker-compose.microvps-full.yaml` (лимиты как в базовом compose, без принудительной подстановки брокера в `evobgp-all`):
```powershell
docker compose --profile microvps-full pull
docker compose --profile microvps-full up -d
docker compose --env-file .env --env-file .env.web-sec --profile microvps-full pull
docker compose --env-file .env --env-file .env.web-sec --profile microvps-full up -d
```
При необходимости задайте брокер вручную для `evobgp-all` (override или `.env` рядом с compose): `EVOBGP_BROKER_URL=nats://nats:4222`.
| Порт | Назначение |
|------|------------|
| **3000** | Web UI (nginx → API под капотом) |
| **80** | HTTP вход (редирект на HTTPS через Traefik) |
| **443** | HTTPS Web UI (Traefik + Let's Encrypt) |
| **8080** | Прямой HTTP API (`evobgp-all`) |
| **9090** | Prometheus (`prometheus-microvps`) |
| **4222** | NATS |
| **179** | BGP (BIRD2), как в варианте 1 |
Проверка UI: откройте `http://<IP-вашей-VPS>:3000`. Health API: `http://<IP>:8080/v1/health`.
Проверка UI:
- `http://<WEBUI_DOMAIN>` должен редиректить на `https://<WEBUI_DOMAIN>`;
- с IP из `WEBUI_IP_WHITELIST` UI доступен по HTTPS;
- с неразрешенного IP Traefik вернет `403`.
Health API: `http://<IP>:8080/v1/health`.
Остановка (если поднимали с двумя `-f`):
```powershell
docker compose -f docker-compose.yaml -f docker-compose.microvps-full.yaml --profile microvps-full down
docker compose --env-file .env --env-file .env.web-sec -f docker-compose.yaml -f docker-compose.microvps-full.yaml --profile microvps-full down
```
## Вариант 2: Docker, профиль reference