Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions deploy/openshift/openwebui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# OpenWebUI OpenShift Integration

This directory contains the OpenShift deployment manifests for OpenWebUI, integrated with the existing semantic-router deployment.

## Architecture

- **Namespace**: `vllm-semantic-router-system` (same as semantic-router)
- **Backend Integration**: Connects to Envoy proxy endpoint with load balancing
- **External Access**: Available via OpenShift Route with HTTPS
- **Storage**: Persistent volume for user data and configurations

## Quick Deployment

### Using Scripts (Recommended)

```bash
# Deploy OpenWebUI with full validation and setup
./deploy-openwebui-on-openshift.sh

# Uninstall OpenWebUI (preserves data by default)
./uninstall-openwebui.sh
```

### Using Kubernetes Manifests

```bash
# Deploy OpenWebUI manifests individually
oc apply -f pvc.yaml
oc apply -f deployment.yaml
oc apply -f service.yaml
oc apply -f route.yaml

# Check deployment status
oc get pods -n vllm-semantic-router-system -l app=openwebui

# Get the external URL
oc get route openwebui -n vllm-semantic-router-system -o jsonpath='{.spec.host}'
```

## Configuration

OpenWebUI is configured to connect to the Envoy proxy automatically:

- **Backend URL**: `http://semantic-router.vllm-semantic-router-system.svc.cluster.local:8801/v1`
- **Available Models**: `auto` (load balancer), `Model-A`, `Model-B`
- **Port**: Service exposed on port 3000, mapped to container port 8080
- **Storage**: 2Gi persistent volume for user data

### OpenWebUI Settings

When configuring OpenWebUI in the interface:

- **API Base URL**: `http://semantic-router.vllm-semantic-router-system.svc.cluster.local:8801/v1`
- **API Key**: `not-needed-for-local-models` (or leave empty)
- **Models**: Will auto-discover `auto`, `Model-A`, and `Model-B`

## Files

- `deploy-openwebui-on-openshift.sh` - Complete deployment script with validation
- `uninstall-openwebui.sh` - Safe uninstall script with data preservation options
- `deployment.yaml` - OpenWebUI deployment with OpenShift security contexts
- `service.yaml` - ClusterIP service exposing port 3000
- `route.yaml` - OpenShift route for external HTTPS access
- `pvc.yaml` - Persistent volume claim for data storage
- `kustomization.yaml` - Kustomize configuration for easy deployment

## Usage

1. **Deploy**: Run `./deploy-openwebui-on-openshift.sh`
2. **Access**: Open the provided HTTPS URL in your browser
3. **Configure**: Models are pre-configured and auto-discovered
4. **Chat**: Start conversations with Model-A, Model-B, or auto (load balanced)

## Cleanup

```bash
# Safe uninstall with data preservation option
./uninstall-openwebui.sh

# Or remove all resources immediately
oc delete -f route.yaml -f service.yaml -f deployment.yaml -f pvc.yaml
```

## Features

- **Zero-config Setup**: Automatically connects to semantic-router
- **Load Balancing**: Access both models through Envoy proxy
- **Persistent Data**: User conversations and settings preserved
- **OpenShift Security**: Runs with restricted security contexts
- **HTTPS Access**: Secure external access via OpenShift routes
- **Health Monitoring**: Built-in health checks and monitoring

## Troubleshooting

- **503 Errors**: Check if service endpoints are available with `oc get endpoints openwebui`
- **Connection Issues**: Verify semantic-router is running with `oc get pods -l app=semantic-router`
- **Model Discovery**: Test backend connectivity with the deployment script validation
129 changes: 129 additions & 0 deletions deploy/openshift/openwebui/deploy-openwebui-on-openshift.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#!/bin/bash

# Deploy OpenWebUI on OpenShift
# This script deploys OpenWebUI to work with the existing semantic-router deployment

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

echo -e "${BLUE}🚀 OpenWebUI OpenShift Deployment Script${NC}"
echo "================================================"

# Check if oc is installed and logged in
if ! command -v oc &> /dev/null; then
echo -e "${RED}❌ Error: 'oc' command not found. Please install OpenShift CLI.${NC}"
exit 1
fi

if ! oc whoami &> /dev/null; then
echo -e "${RED}❌ Error: Not logged into OpenShift. Please run 'oc login'.${NC}"
exit 1
fi

# Get current user and project
CURRENT_USER=$(oc whoami)
echo -e "${GREEN}✅ Logged in as: ${CURRENT_USER}${NC}"

# Check if we're in the right namespace or if it exists
NAMESPACE="vllm-semantic-router-system"
if ! oc get namespace "$NAMESPACE" &> /dev/null; then
echo -e "${RED}❌ Error: Namespace '$NAMESPACE' not found.${NC}"
echo "Please ensure the semantic-router is deployed first."
exit 1
fi

# Switch to the namespace
echo -e "${YELLOW}📁 Switching to namespace: ${NAMESPACE}${NC}"
oc project "$NAMESPACE"

# Check if semantic-router is running
echo -e "${YELLOW}🔍 Checking semantic-router deployment...${NC}"
if ! oc get deployment semantic-router &> /dev/null; then
echo -e "${RED}❌ Error: semantic-router deployment not found.${NC}"
echo "Please deploy semantic-router first."
exit 1
fi

if ! oc get deployment semantic-router -o jsonpath='{.status.readyReplicas}' | grep -q "1"; then
echo -e "${YELLOW}⚠️ Warning: semantic-router deployment may not be ready.${NC}"
echo "Continuing with OpenWebUI deployment..."
fi

echo -e "${GREEN}✅ semantic-router found and ready${NC}"

# Deploy OpenWebUI components
echo -e "${YELLOW}🔧 Deploying OpenWebUI components...${NC}"

echo " 📦 Creating Persistent Volume Claim..."
oc apply -f "$SCRIPT_DIR/pvc.yaml"

echo " 🚀 Creating Deployment..."
oc apply -f "$SCRIPT_DIR/deployment.yaml"

echo " 🌐 Creating Service..."
oc apply -f "$SCRIPT_DIR/service.yaml"

echo " 🔗 Creating Route..."
oc apply -f "$SCRIPT_DIR/route.yaml"

# Wait for deployment to be ready
echo -e "${YELLOW}⏳ Waiting for OpenWebUI deployment to be ready...${NC}"
oc rollout status deployment/openwebui --timeout=300s

# Get the route URL
ROUTE_URL=$(oc get route openwebui -o jsonpath='{.spec.host}')
if [ -z "$ROUTE_URL" ]; then
echo -e "${RED}❌ Error: Could not get route URL${NC}"
exit 1
fi

# Check if OpenWebUI is responding
echo -e "${YELLOW}🔍 Testing OpenWebUI endpoint...${NC}"
if curl -k -s -o /dev/null -w "%{http_code}" "https://$ROUTE_URL" | grep -q "200"; then
echo -e "${GREEN}✅ OpenWebUI is responding${NC}"
else
echo -e "${YELLOW}⚠️ OpenWebUI may still be starting up...${NC}"
fi

# Test backend connectivity
echo -e "${YELLOW}🔍 Testing backend connectivity...${NC}"
if oc exec deployment/openwebui -- curl -s -o /dev/null -w "%{http_code}" \
"http://semantic-router.vllm-semantic-router-system.svc.cluster.local:8801/v1/models" | grep -q "200"; then
echo -e "${GREEN}✅ Backend connectivity working${NC}"
else
echo -e "${YELLOW}⚠️ Backend connectivity may need time to establish...${NC}"
fi

# Display deployment information
echo ""
echo -e "${GREEN}🎉 OpenWebUI deployment completed successfully!${NC}"
echo "================================================"
echo -e "${BLUE}📊 Deployment Summary:${NC}"
echo " 🌐 URL: https://$ROUTE_URL"
echo " 🎯 Backend: http://semantic-router.vllm-semantic-router-system.svc.cluster.local:8801/v1"
echo " 📂 Namespace: $NAMESPACE"
echo ""
echo -e "${BLUE}🔧 Available Models:${NC}"
echo " • auto (load balancer)"
echo " • Model-A (Qwen/Qwen3-0.6B)"
echo " • Model-B (Qwen/Qwen3-0.6B)"
echo ""
echo -e "${BLUE}📝 Configuration for OpenWebUI:${NC}"
echo " • API Base URL: http://semantic-router.vllm-semantic-router-system.svc.cluster.local:8801/v1"
echo " • API Key: not-needed-for-local-models (or leave empty)"
echo ""
echo -e "${YELLOW}💡 Next Steps:${NC}"
echo " 1. Open https://$ROUTE_URL in your browser"
echo " 2. Complete initial setup in OpenWebUI"
echo " 3. The models should be automatically available"
echo ""
echo -e "${GREEN}✨ Happy chatting with your models!${NC}"
85 changes: 85 additions & 0 deletions deploy/openshift/openwebui/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: openwebui
namespace: vllm-semantic-router-system
labels:
app: openwebui
component: frontend
spec:
replicas: 1
selector:
matchLabels:
app: openwebui
template:
metadata:
labels:
app: openwebui
component: frontend
spec:
containers:
- name: openwebui
image: ghcr.io/open-webui/open-webui:main
ports:
- containerPort: 8080
name: http
protocol: TCP
env:
# OpenWebUI Configuration - Connect to Envoy proxy
- name: OPENAI_API_BASE_URL
value: "http://semantic-router.vllm-semantic-router-system.svc.cluster.local:8801/v1"
- name: OPENAI_API_KEY
value: "not-needed-for-local-models"
- name: WEBUI_SECRET_KEY
value: "your-secret-key-change-in-production"
- name: DATA_DIR
value: "/app/backend/data"
# Enable multiple OpenAI-compatible endpoints
- name: ENABLE_OPENAI_API
value: "true"
# OpenShift compatible paths
- name: HOME
value: "/tmp/home"
- name: TMPDIR
value: "/tmp"
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
volumeMounts:
- name: openwebui-data
mountPath: /app/backend/data
- name: tmp-volume
mountPath: /tmp
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 3
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
volumes:
- name: openwebui-data
persistentVolumeClaim:
claimName: openwebui-data
- name: tmp-volume
emptyDir: {}
22 changes: 22 additions & 0 deletions deploy/openshift/openwebui/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

metadata:
name: openwebui
namespace: vllm-semantic-router-system

# Resources that make up the OpenWebUI deployment
resources:
- pvc.yaml
- deployment.yaml
- service.yaml
- route.yaml

# Common labels applied to all resources
commonLabels:
app.kubernetes.io/name: openwebui
app.kubernetes.io/component: frontend
app.kubernetes.io/part-of: semantic-router

# Namespace for all resources
namespace: vllm-semantic-router-system
16 changes: 16 additions & 0 deletions deploy/openshift/openwebui/pvc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: openwebui-data
namespace: vllm-semantic-router-system
labels:
app: openwebui
component: frontend
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
# Use default storage class for OpenShift
# storageClassName: ""
22 changes: 22 additions & 0 deletions deploy/openshift/openwebui/route.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: openwebui
namespace: vllm-semantic-router-system
labels:
app: openwebui
component: frontend
annotations:
haproxy.router.openshift.io/timeout: "300s"
spec:
host: openwebui-vllm-semantic-router-system.apps.cluster-pbd96.pbd96.sandbox5333.opentlc.com
to:
kind: Service
name: openwebui
weight: 100
port:
targetPort: http
tls:
termination: edge
insecureEdgeTerminationPolicy: Redirect
wildcardPolicy: None
Loading
Loading