diff --git a/dashboard/README.md b/dashboard/README.md index 2c815bb1..25a83de9 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -200,6 +200,11 @@ After startup, access: - **Dashboard**: http://localhost:8700 - **Grafana** (direct access): http://localhost:3000 (admin/admin) - **Prometheus** (direct access): http://localhost:9090 +- **OpenWeb UI** (direct access): http://localhost:3001 + +Note: + +- In **Admin Panel > settings > pipelines** set `Vsr Base Url`: http://envoy:8801 ### Method 2: Local Development Mode diff --git a/dashboard/deploy/kubernetes/.gitkeep b/dashboard/deploy/kubernetes/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/dashboard/deploy/kubernetes/deployment.yaml b/dashboard/deploy/kubernetes/deployment.yaml deleted file mode 100644 index 530f9f49..00000000 --- a/dashboard/deploy/kubernetes/deployment.yaml +++ /dev/null @@ -1,100 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: semantic-router-dashboard - labels: - app: semantic-router-dashboard -spec: - replicas: 1 - selector: - matchLabels: - app: semantic-router-dashboard - template: - metadata: - labels: - app: semantic-router-dashboard - spec: - containers: - - name: dashboard - image: ghcr.io/vllm-project/semantic-router/dashboard:latest - imagePullPolicy: IfNotPresent - args: ["-port=8700", "-static=/app/frontend", "-config=/app/config/config.yaml"] - env: - - name: TARGET_GRAFANA_URL - valueFrom: - configMapKeyRef: - name: semantic-router-dashboard-config - key: TARGET_GRAFANA_URL - - name: TARGET_PROMETHEUS_URL - valueFrom: - configMapKeyRef: - name: semantic-router-dashboard-config - key: TARGET_PROMETHEUS_URL - - name: TARGET_ROUTER_API_URL - valueFrom: - configMapKeyRef: - name: semantic-router-dashboard-config - key: TARGET_ROUTER_API_URL - - name: TARGET_ROUTER_METRICS_URL - valueFrom: - configMapKeyRef: - name: semantic-router-dashboard-config - key: TARGET_ROUTER_METRICS_URL - - name: TARGET_OPENWEBUI_URL - valueFrom: - configMapKeyRef: - name: semantic-router-dashboard-config - key: TARGET_OPENWEBUI_URL - - name: ROUTER_CONFIG_PATH - value: /app/config/config.yaml - ports: - - name: http - containerPort: 8700 - volumeMounts: - - name: router-config - mountPath: /app/config - readOnly: true - volumes: - - name: router-config - configMap: - name: semantic-router-config ---- -apiVersion: v1 -kind: Service -metadata: - name: semantic-router-dashboard - labels: - app: semantic-router-dashboard -spec: - type: ClusterIP - selector: - app: semantic-router-dashboard - ports: - - name: http - port: 80 - targetPort: http ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: semantic-router-dashboard-config -data: - TARGET_GRAFANA_URL: http://grafana.vllm-semantic-router-system.svc.cluster.local:3000 - TARGET_PROMETHEUS_URL: http://prometheus.vllm-semantic-router-system.svc.cluster.local:9090 - TARGET_ROUTER_API_URL: http://semantic-router.vllm-semantic-router-system.svc.cluster.local:8080 - TARGET_ROUTER_METRICS_URL: http://semantic-router.vllm-semantic-router-system.svc.cluster.local:9190/metrics - TARGET_OPENWEBUI_URL: "" - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: semantic-router-config -data: - # Minimal config.yaml to let /api/router/config/all return something. - # Replace with your real configuration or mount a different ConfigMap/Secret. - config.yaml: | - default_model: example-model - default_reasoning_effort: medium - vllm_endpoints: [] - model_config: {} diff --git a/dashboard/deploy/local/.gitkeep b/dashboard/deploy/local/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/deploy/docker-compose/README.md b/deploy/docker-compose/README.md index 3a200167..6f0dd49a 100644 --- a/deploy/docker-compose/README.md +++ b/deploy/docker-compose/README.md @@ -16,6 +16,19 @@ Example mappings: - `testing` : enables `mock-vllm` and `llm-katan` - `llm-katan` : only `llm-katan` +## Services and Ports + +These host ports are exposed when you bring the stack up: + +- Dashboard: http://localhost:8700 (Semantic Router Dashboard) +- Envoy proxy: http://localhost:8801 +- Envoy admin: http://localhost:19000 +- Grafana: http://localhost:3000 (admin/admin) +- Prometheus: http://localhost:9090 +- Open WebUI: http://localhost:3001 +- Mock vLLM (testing profile): http://localhost:8000 +- LLM Katan (testing/llm-katan profiles): http://localhost:8002 + ## Common Commands ```bash @@ -29,6 +42,8 @@ docker compose -f deploy/docker-compose/docker-compose.yml --profile testing up docker compose -f deploy/docker-compose/docker-compose.yml down ``` +After the stack is healthy, open the Dashboard at http://localhost:8700. + ## Overrides You can place a `docker-compose.override.yml` at repo root and combine: @@ -40,3 +55,55 @@ docker compose -f deploy/docker-compose/docker-compose.yml -f docker-compose.ove - Local observability only: `tools/observability/docker-compose.obs.yml` - Tracing stack: `tools/tracing/docker-compose.tracing.yaml` + +## Dashboard + +The Dashboard service provides a single entry point to explore and manage the stack: + +- URL: http://localhost:8700 +- Health check: http://localhost:8700/healthz +- Features: + - Router status and config visibility (reads `config/config.yaml` mounted into the container) + - Embedded Grafana dashboard (live metrics from Prometheus) + - Links to Envoy, Prometheus, and Open WebUI Playground + +### How it is wired + +From `docker-compose.yml`: + +- Service name: `dashboard` +- Image: `ghcr.io/vllm-project/semantic-router/dashboard:latest` (override with `DASHBOARD_IMAGE`) +- Build fallback: builds from `dashboard/backend/Dockerfile` at repo root +- Port: `8700:8700` +- Volumes: mounts `../../config` as `/app/config` (read-write) so the Dashboard can read your active `config.yaml` +- Depends on: `semantic-router`, `grafana`, `prometheus`, `openwebui`, `pipelines` + +Environment variables passed to Dashboard: + +- `DASHBOARD_PORT=8700` +- `TARGET_GRAFANA_URL=http://grafana:3000` +- `TARGET_PROMETHEUS_URL=http://prometheus:9090` +- `TARGET_ROUTER_API_URL=http://semantic-router:8080` +- `TARGET_ROUTER_METRICS_URL=http://semantic-router:9190/metrics` +- `TARGET_OPENWEBUI_URL=http://openwebui:8080` +- `ROUTER_CONFIG_PATH=/app/config/config.yaml` + +Note: The Router’s HTTP API (8080) and metrics (9190) are only available inside the Docker network (not published to host). The Dashboard connects to them internally so you don’t need to expose extra ports. + +### Credentials and defaults + +- Grafana is provisioned with `admin/admin` (see `GF_SECURITY_ADMIN_*` env in compose). For convenient embedding, anonymous viewing is enabled and suitable for local development only. +- Open WebUI is published at http://localhost:3001 and defaults to routing OpenAI-compatible traffic to the Pipelines service. + +### Customizing + +- Use `DASHBOARD_IMAGE` to point at a different prebuilt Dashboard image if desired: + - Example (bash): `export DASHBOARD_IMAGE=ghcr.io/your-org/semantic-router-dashboard:tag` +- Edit `config/config.yaml` to change Router behavior; the Dashboard reads that file from the mounted `config/` directory. +- If a port conflicts on your machine, change the left-hand port mapping in `docker-compose.yml` (e.g., `"3000:3000"` -> `"33000:3000"`). + +### Troubleshooting + +- Dashboard not loading charts: ensure Prometheus and Grafana containers are up and healthy. +- Grafana asks for login: use `admin/admin` or enable anonymous as already configured in compose; for production, disable anonymous and set strong credentials. +- Health checks failing initially can be normal while services warm up; Compose has `start_period` set to lessen flakiness. diff --git a/deploy/docker-compose/docker-compose.yml b/deploy/docker-compose/docker-compose.yml index 6b91bb5a..257fa5cb 100644 --- a/deploy/docker-compose/docker-compose.yml +++ b/deploy/docker-compose/docker-compose.yml @@ -72,8 +72,6 @@ services: command: - --config.file=/etc/prometheus/prometheus.yaml - --storage.tsdb.retention.time=15d - environment: - - ROUTER_TARGET=semantic-router:9190 ports: - "9090:9090" networks: @@ -85,7 +83,6 @@ services: environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=admin - - PROMETHEUS_URL=prometheus:9090 - GF_SECURITY_ALLOW_EMBEDDING=true - GF_SECURITY_COOKIE_SAMESITE=lax # Configure for subpath serving through dashboard proxy diff --git a/tools/observability/grafana-datasource.yaml b/tools/observability/grafana-datasource.yaml index a96c705e..9d80360d 100644 --- a/tools/observability/grafana-datasource.yaml +++ b/tools/observability/grafana-datasource.yaml @@ -7,7 +7,7 @@ datasources: - name: Prometheus type: prometheus access: proxy - url: http://${PROMETHEUS_URL:-localhost:9090} + url: http://prometheus:9090 isDefault: true editable: true jsonData: diff --git a/tools/observability/prometheus.yaml b/tools/observability/prometheus.yaml index 74172124..66e8d1b8 100644 --- a/tools/observability/prometheus.yaml +++ b/tools/observability/prometheus.yaml @@ -1,12 +1,4 @@ # Prometheus configuration for semantic-router observability -# -# This configuration works for both: -# - Local development (router running natively, observability in Docker) -# - Docker Compose (all services in containers) -# -# The target address is controlled by environment variable: -# - Local mode: ROUTER_TARGET=localhost:9190 -# - Compose mode: ROUTER_TARGET=semantic-router:9190 global: scrape_interval: 15s @@ -17,7 +9,7 @@ scrape_configs: - job_name: semantic-router metrics_path: /metrics static_configs: - - targets: ["${ROUTER_TARGET:-localhost:9190}"] + - targets: ["prometheus:9190"] labels: service: semantic-router environment: docker