|
| 1 | +#!/bin/bash |
| 2 | +set -e |
| 3 | + |
| 4 | +# Script to build and deploy custom dashboard image to OpenShift |
| 5 | +# This builds the dashboard with OpenWebUI integration patches for demo purposes |
| 6 | + |
| 7 | +NAMESPACE="vllm-semantic-router-system" |
| 8 | +IMAGE_NAME="dashboard-custom" |
| 9 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 10 | + |
| 11 | +echo "==========================================" |
| 12 | +echo "Building Custom Dashboard Image" |
| 13 | +echo "==========================================" |
| 14 | + |
| 15 | +# Get OpenShift internal registry |
| 16 | +REGISTRY=$(oc get route default-route -n openshift-image-registry -o jsonpath='{.spec.host}' 2>/dev/null) |
| 17 | +if [ -z "$REGISTRY" ]; then |
| 18 | + echo "Error: Could not find OpenShift internal registry route" |
| 19 | + echo "Creating registry route..." |
| 20 | + oc patch configs.imageregistry.operator.openshift.io/cluster --type merge -p '{"spec":{"defaultRoute":true}}' |
| 21 | + echo "Waiting for route to be created..." |
| 22 | + sleep 5 |
| 23 | + REGISTRY=$(oc get route default-route -n openshift-image-registry -o jsonpath='{.spec.host}') |
| 24 | +fi |
| 25 | + |
| 26 | +echo "Registry: $REGISTRY" |
| 27 | +echo "Namespace: $NAMESPACE" |
| 28 | + |
| 29 | +# Login to registry |
| 30 | +echo "" |
| 31 | +echo "Logging in to OpenShift registry..." |
| 32 | +TOKEN=$(oc whoami -t) |
| 33 | +docker login -u $(oc whoami) -p $TOKEN $REGISTRY |
| 34 | + |
| 35 | +# Prepare build directory |
| 36 | +echo "" |
| 37 | +echo "Preparing build directory with patched files..." |
| 38 | +BUILD_DIR="/tmp/dashboard-build-$$" |
| 39 | +mkdir -p $BUILD_DIR |
| 40 | +cp -r dashboard $BUILD_DIR/ |
| 41 | + |
| 42 | +# Apply patches |
| 43 | +echo "Applying OpenWebUI integration patches..." |
| 44 | +if [ -f "$SCRIPT_DIR/main.go.patch" ]; then |
| 45 | + cp "$SCRIPT_DIR/main.go.patch" "$BUILD_DIR/dashboard/backend/main.go" |
| 46 | + echo " ✓ Applied main.go patch (OpenWebUI proxy + auth)" |
| 47 | +fi |
| 48 | + |
| 49 | +if [ -f "$SCRIPT_DIR/PlaygroundPage.tsx.patch" ]; then |
| 50 | + cp "$SCRIPT_DIR/PlaygroundPage.tsx.patch" "$BUILD_DIR/dashboard/frontend/src/pages/PlaygroundPage.tsx" |
| 51 | + echo " ✓ Applied PlaygroundPage.tsx patch (proxy path fix)" |
| 52 | +fi |
| 53 | + |
| 54 | +# Create Dockerfile |
| 55 | +echo "" |
| 56 | +echo "Creating Dockerfile..." |
| 57 | +cat > $BUILD_DIR/dashboard/Dockerfile.custom <<'DOCKERFILE_EOF' |
| 58 | +# Build frontend |
| 59 | +FROM node:18-alpine AS frontend-builder |
| 60 | +WORKDIR /app/frontend |
| 61 | +COPY frontend/package*.json ./ |
| 62 | +RUN npm ci |
| 63 | +COPY frontend/ ./ |
| 64 | +RUN npm run build |
| 65 | +
|
| 66 | +# Build backend |
| 67 | +FROM golang:1.21-alpine AS backend-builder |
| 68 | +WORKDIR /app/backend |
| 69 | +COPY backend/go.* ./ |
| 70 | +RUN go mod download |
| 71 | +COPY backend/ ./ |
| 72 | +RUN CGO_ENABLED=0 GOOS=linux go build -o dashboard-server . |
| 73 | +
|
| 74 | +# Final image |
| 75 | +FROM alpine:3.18 |
| 76 | +RUN apk add --no-cache ca-certificates |
| 77 | +WORKDIR /app |
| 78 | +COPY --from=backend-builder /app/backend/dashboard-server . |
| 79 | +COPY --from=frontend-builder /app/frontend/dist ./frontend |
| 80 | +ENV DASHBOARD_STATIC_DIR=./frontend |
| 81 | +EXPOSE 8700 |
| 82 | +CMD ["./dashboard-server"] |
| 83 | +DOCKERFILE_EOF |
| 84 | + |
| 85 | +# Ensure imagestream exists |
| 86 | +echo "" |
| 87 | +if ! oc get imagestream $IMAGE_NAME -n $NAMESPACE &>/dev/null; then |
| 88 | + echo "Creating imagestream $IMAGE_NAME..." |
| 89 | + oc create imagestream $IMAGE_NAME -n $NAMESPACE |
| 90 | +else |
| 91 | + echo "Imagestream $IMAGE_NAME already exists" |
| 92 | +fi |
| 93 | + |
| 94 | +# Build image |
| 95 | +echo "" |
| 96 | +echo "Building docker image for linux/amd64 with no cache..." |
| 97 | +cd $BUILD_DIR/dashboard |
| 98 | +docker buildx build --no-cache --platform linux/amd64 -f Dockerfile.custom -t $REGISTRY/$NAMESPACE/$IMAGE_NAME:latest --load . |
| 99 | + |
| 100 | +echo "" |
| 101 | +echo "Pushing image to registry..." |
| 102 | +docker push $REGISTRY/$NAMESPACE/$IMAGE_NAME:latest |
| 103 | + |
| 104 | +# Cleanup |
| 105 | +echo "" |
| 106 | +echo "Cleaning up build directory..." |
| 107 | +rm -rf $BUILD_DIR |
| 108 | + |
| 109 | +# Apply deployment configuration if it doesn't exist |
| 110 | +echo "" |
| 111 | +if ! oc get deployment dashboard -n $NAMESPACE &>/dev/null; then |
| 112 | + echo "Dashboard deployment not found. Applying configuration..." |
| 113 | + oc apply -f "$SCRIPT_DIR/dashboard-deployment.yaml" |
| 114 | +else |
| 115 | + echo "Dashboard deployment already exists. Updating image..." |
| 116 | + oc set image deployment/dashboard dashboard=image-registry.openshift-image-registry.svc:5000/$NAMESPACE/$IMAGE_NAME:latest -n $NAMESPACE |
| 117 | +fi |
| 118 | + |
| 119 | +echo "" |
| 120 | +echo "Waiting for deployment to roll out..." |
| 121 | +oc rollout status deployment/dashboard -n $NAMESPACE --timeout=5m |
| 122 | + |
| 123 | +echo "" |
| 124 | +echo "==========================================" |
| 125 | +echo "Custom Dashboard Deployed Successfully!" |
| 126 | +echo "==========================================" |
| 127 | +echo "" |
| 128 | +echo "Access the dashboard at:" |
| 129 | +oc get route dashboard -n $NAMESPACE -o jsonpath='https://{.spec.host}' |
| 130 | +echo "" |
| 131 | +echo "" |
| 132 | +echo "Patches applied:" |
| 133 | +echo " - OpenWebUI proxy path fix (PlaygroundPage.tsx)" |
| 134 | +echo " - OpenWebUI static assets proxying (main.go)" |
| 135 | +echo " - Smart API routing for OpenWebUI (main.go)" |
| 136 | +echo " - Authorization header forwarding (main.go)" |
| 137 | +echo "" |
0 commit comments