diff --git a/o/open-webui/Dockerfiles/v0.7.2_ubi_9/Dockerfile b/o/open-webui/Dockerfiles/v0.7.2_ubi_9/Dockerfile new file mode 100644 index 0000000000..3cebe81d77 --- /dev/null +++ b/o/open-webui/Dockerfiles/v0.7.2_ubi_9/Dockerfile @@ -0,0 +1,254 @@ +# syntax=docker/dockerfile:1 +# Initialize device type args +# use build args in the docker build command with --build-arg="BUILDARG=true" +# Arguments +ARG USE_CUDA=false +ARG USE_OLLAMA=false +ARG USE_SLIM=false +ARG USE_PERMISSION_HARDENING=false +# Tested with cu117 for CUDA 11 and cu121 for CUDA 12 (default) +ARG USE_CUDA_VER=cu128 +# any sentence transformer model; models to use can be found at https://huggingface.co/models?library=sentence-transformers +# Leaderboard: https://huggingface.co/spaces/mteb/leaderboard +# for better performance and multilangauge support use "intfloat/multilingual-e5-large" (~2.5GB) or "intfloat/multilingual-e5-base" (~1.5GB) +# IMPORTANT: If you change the embedding model (sentence-transformers/all-MiniLM-L6-v2) and vice versa, you aren't able to use RAG Chat with your previous documents loaded in the WebUI! You need to re-embed them. +ARG USE_EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2 +ARG USE_RERANKING_MODEL="" +ARG USE_AUXILIARY_EMBEDDING_MODEL=TaylorAI/bge-micro-v2 + +# Tiktoken encoding name; models to use can be found at https://huggingface.co/models?library=tiktoken +ARG USE_TIKTOKEN_ENCODING_NAME="cl100k_base" + +ARG BUILD_HASH=dev-build +# Override at your own risk - non-root configurations are untested +ARG UID=0 +ARG GID=0 + +######## STAGE 1 : WebUI frontend ######## +FROM --platform=$BUILDPLATFORM node:22 AS build +ARG BUILD_HASH + +# Set Node.js options (heap limit Allocation failed - JavaScript heap out of memory) +# ENV NODE_OPTIONS="--max-old-space-size=4096" + +WORKDIR /app + +#Node.js Dependencies and Build +# to store git revision in build +RUN apt update && apt install git wget -y +COPY package.json package-lock.json ./ +RUN rm -rf package-lock.json && npm install --force + + +RUN apt update && apt install -y git + +# Clone repo +ARG REPO_URL=https://github.com/open-webui/open-webui.git +ARG REPO_BRANCH=v0.7.2 +RUN git clone --branch ${REPO_BRANCH} ${REPO_URL} . + +# Get patch file from build context +RUN wget https://raw.githubusercontent.com/ppc64le/build-scripts/master/o/open-webui/open-webui_v0.7.2.patch + +# Apply patch +RUN git apply open-webui_v0.7.2.patch + +#Copy Source and Build +COPY . . +ENV APP_BUILD_HASH=${BUILD_HASH} +RUN npm run build + +####### STAGE 2 : Install dependencies ####### +FROM python:3.11.14-slim-trixie AS deps +#Use args for conditional installs +ARG USE_CUDA +ARG USE_CUDA_VER +ARG USE_SLIM +ARG USE_EMBEDDING_MODEL + +WORKDIR /app/backend + +#Install common system dependencies needed for building Python Packages +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + git build-essential pandoc gcc python3-dev netcat-openbsd curl jq \ + ffmpeg libsm6 libxext6 \ + && rm -rf /var/lib/apt/lists/* + +#Python Packages setup +RUN pip3 install --no-cache-dir uv + +#Copy only requirements files +COPY ./backend/requirements.txt ./requirements.txt + +#Dependency install and Model pre-download (if not slim) +ENV RAG_EMBEDDING_MODEL=$USE_EMBEDDING_MODEL \ + WHISPER_MODEL="base" \ + WHISPER_MODEL_DIR="/app/backend/data/cache/whisper/models" \ + TICKTOKEN_ENCODING_NAME="cl100k_base" + +RUN if [ "$USE_CUDA" = "true" ]; then \ +#CUDA build : Install PyTorch with CUDA support +#Predownload models on CUDA build +pip3 install uvicorn --no-cache-dir && \ + pip3 install fastapi typer pydantic sqlalchemy aiocache aiohttp anyio requests redis starlette_compress itsdangerous fastapi starsessions loguru opentelemetry-api cryptography markdown bs4 asgiref jwt bcrypt pytz --no-cache-dir && \ + pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/$USE_CUDA_VER --no-cache-dir && \ + uv pip install --system -r requirements.txt --no-cache-dir && \ + python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \ + python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])"; \ + python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \ + else \ + pip3 install torch torchvision torchaudio --no-cache-dir && \ + python -m pip install -r requirements.txt --no-cache-dir && \ + if [ "$USE_SLIM" != "true" ]; then \ + python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \ + python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])"; \ + python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \ + fi; \ + fi; \ + mkdir -p /app/backend/data && chown -R $UID:$GID /app/backend/data/ && \ + rm -rf /var/lib/apt/lists/*; + +######## STAGE 3 : WebUI backend ######## +FROM python:3.11.14-slim-trixie AS base + +ENV UV_EXTRA_INDEX_URL=https://repo.fury.io/mgiessing +ENV PIP_EXTRA_INDEX_URL=https://repo.fury.io/mgiessing + +# Use args +ARG USE_CUDA +ARG USE_OLLAMA +ARG USE_CUDA_VER +ARG USE_SLIM +ARG USE_PERMISSION_HARDENING +ARG USE_EMBEDDING_MODEL +ARG USE_RERANKING_MODEL +ARG USE_AUXILIARY_EMBEDDING_MODEL +ARG UID +ARG GID + +# Python settings +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app/backend +ENV HOME=/root + +## Environment Variables for Runtime Configuration Basis ## +ENV ENV=prod \ + PORT=8080 \ + DOCKER=true \ + WEBUI_BUILD_VERSION=${BUILD_HASH} \ + # pass build args to the build + USE_OLLAMA_DOCKER=${USE_OLLAMA} \ + USE_CUDA_DOCKER=${USE_CUDA} \ + USE_SLIM_DOCKER=${USE_SLIM} \ + USE_CUDA_DOCKER_VER=${USE_CUDA_VER} \ + USE_EMBEDDING_MODEL_DOCKER=${USE_EMBEDDING_MODEL} \ + USE_RERANKING_MODEL_DOCKER=${USE_RERANKING_MODEL} \ + USE_AUXILIARY_EMBEDDING_MODEL_DOCKER=${USE_AUXILIARY_EMBEDDING_MODEL} + +## Basis URL Config ## +ENV OLLAMA_BASE_URL="/ollama" \ + OPENAI_API_BASE_URL="" + +## API Key and Security Config ## +ENV OPENAI_API_KEY="" \ + WEBUI_SECRET_KEY="" \ + SCARF_NO_ANALYTICS=true \ + DO_NOT_TRACK=true \ + ANONYMIZED_TELEMETRY=false + +#### Other models ######################################################### +## whisper TTS model settings ## +ENV WHISPER_MODEL="base" \ + WHISPER_MODEL_DIR="/app/backend/data/cache/whisper/models" + +## RAG Embedding model settings ## +ENV RAG_EMBEDDING_MODEL="$USE_EMBEDDING_MODEL_DOCKER" \ + RAG_RERANKING_MODEL="$USE_RERANKING_MODEL_DOCKER" \ + AUXILIARY_EMBEDDING_MODEL="$USE_AUXILIARY_EMBEDDING_MODEL_DOCKER" \ + SENTENCE_TRANSFORMERS_HOME="/app/backend/data/cache/embedding/models" + +## Tiktoken model settings ## +ENV TIKTOKEN_ENCODING_NAME="cl100k_base" \ + TIKTOKEN_CACHE_DIR="/app/backend/data/cache/tiktoken" + +## Hugging Face download cache ## +ENV HF_HOME="/app/backend/data/cache/embedding/models" + +## Torch Extensions ## +# ENV TORCH_EXTENSIONS_DIR="/.cache/torch_extensions" + + +# Install common system dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + git build-essential pandoc gcc netcat-openbsd curl jq \ + python3-dev \ + ffmpeg libsm6 libxext6 \ + && rm -rf /var/lib/apt/lists/* + +# User Setup and Permissions +# Create non-root user/group +RUN if [ $UID -ne 0 ]; then \ + if [ $GID -ne 0 ]; then \ + addgroup --gid $GID app; \ + fi; \ + adduser --uid $UID --gid $GID --home $HOME --disabled-password --no-create-home app; \ + fi + +#Copy only requirements files +COPY ./backend/requirements.txt ./requirements.txt +RUN python -m pip install --no-cache-dir -r requirements.txt + +RUN mkdir -p $HOME/.cache/chroma +RUN echo -n 00000000-0000-0000-0000-000000000000 > $HOME/.cache/chroma/telemetry_user_id +# Make sure the user has access to the app and root directory +RUN chown -R $UID:$GID /app $HOME + +# Install Ollama if requested +RUN if [ "$USE_OLLAMA" = "true" ]; then \ + date +%s > /tmp/ollama_build_hash && \ + echo "Cache broken at timestamp: `cat /tmp/ollama_build_hash`" && \ + curl -fsSL https://ollama.com/install.sh | sh && \ + rm -rf /var/lib/apt/lists/*; \ + fi + +## Copy artifacts from build stages +# copy Python environment from 'deps' stages +COPY --from=deps /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages +#COPY --from=deps /usr/local/lib/uv /usr/local/lib/uv +COPY --chown=$UID:$GID --from=deps /app/backend/data /app/backend/data + + +# copy embedding weight from build +# RUN mkdir -p /root/.cache/chroma/onnx_models/all-MiniLM-L6-v2 +# COPY --from=build /app/onnx /root/.cache/chroma/onnx_models/all-MiniLM-L6-v2/onnx + +# copy built frontend files +COPY --chown=$UID:$GID --from=build /app/build /app/build +COPY --chown=$UID:$GID --from=build /app/CHANGELOG.md /app/CHANGELOG.md +COPY --chown=$UID:$GID --from=build /app/package.json /app/package.json + +# copy backend files +COPY --chown=$UID:$GID ./backend . + +EXPOSE 8080 + +#Healthcheck and Final Permissisons +HEALTHCHECK CMD curl --silent --fail http://localhost:${PORT:-8080}/health | jq -ne 'input.status == true' || exit 1 + +# Minimal, atomic permission hardening for OpenShift (arbitrary UID): +# - Group 0 owns /app and /root +# - Directories are group-writable and have SGID so new files inherit GID 0 +RUN if [ "$USE_PERMISSION_HARDENING" = "true" ]; then \ + set -eux; \ + chgrp -R 0 /app /root || true; \ + chmod -R g+rwX /app /root || true; \ + find /app -type d -exec chmod g+s {} + || true; \ + find /root -type d -exec chmod g+s {} + || true; \ + fi + +USER $UID:$GID + +CMD [ "bash", "start.sh"] \ No newline at end of file diff --git a/o/open-webui/LICENSE b/o/open-webui/LICENSE new file mode 100644 index 0000000000..5c304d1a4a --- /dev/null +++ b/o/open-webui/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/o/open-webui/build_info.json b/o/open-webui/build_info.json new file mode 100644 index 0000000000..a8108e16d1 --- /dev/null +++ b/o/open-webui/build_info.json @@ -0,0 +1,20 @@ +{ + "maintainer": "Simran-Sirsat", + "package_name": "open-webui", + "github_url": "https://github.com/open-webui/open-webui", + "version": "v0.7.2", + "wheel_build": false, + "package_dir": "o/open-webui", + "default_branch": "main", + "build_script": "", + "docker_build": true, + "validate_build_script": false, + "docker_cmd": "docker build -t ${package_name}-ppc64le:$PACKAGE_VERSION ${dir}", + "use_non_root_user": false, + "v0.7.2": { + "dir": "v0.7.2_ubi_9", + "base_docker_image": "python:3.11.14-slim-trixie", + "base_docker_variant": "python" + } +} + diff --git a/o/open-webui/open-webui_v0.7.2.patch b/o/open-webui/open-webui_v0.7.2.patch new file mode 100644 index 0000000000..26b6baf826 --- /dev/null +++ b/o/open-webui/open-webui_v0.7.2.patch @@ -0,0 +1,256 @@ +diff --git a/Dockerfile b/Dockerfile +index ac81a3943..5c8f64cb0 100644 +--- a/Dockerfile ++++ b/Dockerfile +@@ -1,6 +1,7 @@ + # syntax=docker/dockerfile:1 + # Initialize device type args + # use build args in the docker build command with --build-arg="BUILDARG=true" ++# Arguments + ARG USE_CUDA=false + ARG USE_OLLAMA=false + ARG USE_SLIM=false +@@ -23,8 +24,8 @@ ARG BUILD_HASH=dev-build + ARG UID=0 + ARG GID=0 + +-######## WebUI frontend ######## +-FROM --platform=$BUILDPLATFORM node:22-alpine3.20 AS build ++######## STAGE 1 : WebUI frontend ######## ++FROM --platform=$BUILDPLATFORM node:22 AS build + ARG BUILD_HASH + + # Set Node.js options (heap limit Allocation failed - JavaScript heap out of memory) +@@ -32,19 +33,80 @@ ARG BUILD_HASH + + WORKDIR /app + ++#Node.js Dependencies and Build + # to store git revision in build +-RUN apk add --no-cache git +- ++RUN apt update && apt install git -y + COPY package.json package-lock.json ./ +-RUN npm ci --force ++RUN rm -rf package-lock.json && npm install --force + ++#Copy Source and Build + COPY . . + ENV APP_BUILD_HASH=${BUILD_HASH} + RUN npm run build + +-######## WebUI backend ######## ++####### STAGE 2 : Install dependencies ####### ++FROM python:3.11.14-slim-bookworm AS deps ++#Use args for conditional installs ++ARG USE_CUDA ++ARG USE_CUDA_VER ++ARG USE_SLIM ++ARG USE_EMBEDDING_MODEL ++ ++WORKDIR /app/backend ++ ++#Install common system dependencies needed for building Python Packages ++RUN apt-get update && \ ++ apt-get install -y --no-install-recommends \ ++ git build-essential pandoc gcc python3-dev netcat-openbsd curl jq \ ++ ffmpeg libsm6 libxext6 \ ++ && rm -rf /var/lib/apt/lists/* ++ ++#Python Packages setup ++RUN pip3 install --no-cache-dir uv ++ ++#Copy only requirements files ++COPY ./backend/requirements.txt ./requirements.txt ++ ++#RUN python -m pip install --no-cache-dir -r requirements.txt ++ ++ ++#COPY ./backend/requirements.txt ./requirements.txt ++#RUN python -m pip install --no-cache-dir -r requirements.txt ++ ++#Dependency install and Model pre-download (if not slim) ++ENV RAG_EMBEDDING_MODEL=$USE_EMBEDDING_MODEL \ ++ WHISPER_MODEL="base" \ ++ WHISPER_MODEL_DIR="/app/backend/data/cache/whisper/models" \ ++ TICKTOKEN_ENCODING_NAME="cl100k_base" ++ ++RUN if [ "$USE_CUDA" = "true" ]; then \ ++#CUDA build : Install PyTorch with CUDA support ++#Predownload models on CUDA build ++pip3 install uvicorn --no-cache-dir && \ ++ pip3 install fastapi typer pydantic sqlalchemy aiocache aiohttp anyio requests redis starlette_compress itsdangerous fastapi starsessions loguru opentelemetry-api cryptography markdown bs4 asgiref jwt bcrypt pytz --no-cache-dir && \ ++ pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/$USE_CUDA_VER --no-cache-dir && \ ++ uv pip install --system -r requirements.txt --no-cache-dir && \ ++ python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \ ++ python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])"; \ ++ python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \ ++ else \ ++ pip3 install torch torchvision torchaudio --no-cache-dir && \ ++ python -m pip install -r requirements.txt --no-cache-dir && \ ++ if [ "$USE_SLIM" != "true" ]; then \ ++ python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \ ++ python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])"; \ ++ python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \ ++ fi; \ ++ fi; \ ++ mkdir -p /app/backend/data && chown -R $UID:$GID /app/backend/data/ && \ ++ rm -rf /var/lib/apt/lists/*; ++ ++######## STAGE 3 : WebUI backend ######## + FROM python:3.11.14-slim-bookworm AS base + ++ENV UV_EXTRA_INDEX_URL=https://repo.fury.io/mgiessing ++ENV PIP_EXTRA_INDEX_URL=https://repo.fury.io/mgiessing ++ + # Use args + ARG USE_CUDA + ARG USE_OLLAMA +@@ -60,9 +122,14 @@ ARG GID + # Python settings + ENV PYTHONUNBUFFERED=1 + +-## Basis ## ++WORKDIR /app/backend ++ENV HOME=/root ++ ++## Environment Variables for Runtime Configuration Basis ## + ENV ENV=prod \ + PORT=8080 \ ++ DOCKER=true \ ++ WEBUI_BUILD_VERSION=${BUILD_HASH} \ + # pass build args to the build + USE_OLLAMA_DOCKER=${USE_OLLAMA} \ + USE_CUDA_DOCKER=${USE_CUDA} \ +@@ -104,12 +171,17 @@ ENV HF_HOME="/app/backend/data/cache/embedding/models" + ## Torch Extensions ## + # ENV TORCH_EXTENSIONS_DIR="/.cache/torch_extensions" + +-#### Other models ########################################################## + +-WORKDIR /app/backend ++# Install common system dependencies ++RUN apt-get update && \ ++ apt-get install -y --no-install-recommends \ ++ git build-essential pandoc gcc netcat-openbsd curl jq \ ++ python3-dev \ ++ ffmpeg libsm6 libxext6 \ ++ && rm -rf /var/lib/apt/lists/* + +-ENV HOME=/root +-# Create user and group if not root ++# User Setup and Permissions ++# Create non-root user/group + RUN if [ $UID -ne 0 ]; then \ + if [ $GID -ne 0 ]; then \ + addgroup --gid $GID app; \ +@@ -117,45 +189,15 @@ RUN if [ $UID -ne 0 ]; then \ + adduser --uid $UID --gid $GID --home $HOME --disabled-password --no-create-home app; \ + fi + ++#Copy only requirements files ++COPY ./backend/requirements.txt ./requirements.txt ++RUN python -m pip install --no-cache-dir -r requirements.txt ++ + RUN mkdir -p $HOME/.cache/chroma + RUN echo -n 00000000-0000-0000-0000-000000000000 > $HOME/.cache/chroma/telemetry_user_id +- + # Make sure the user has access to the app and root directory + RUN chown -R $UID:$GID /app $HOME + +-# Install common system dependencies +-RUN apt-get update && \ +- apt-get install -y --no-install-recommends \ +- git build-essential pandoc gcc netcat-openbsd curl jq \ +- python3-dev \ +- ffmpeg libsm6 libxext6 \ +- && rm -rf /var/lib/apt/lists/* +- +-# install python dependencies +-COPY --chown=$UID:$GID ./backend/requirements.txt ./requirements.txt +- +-RUN pip3 install --no-cache-dir uv && \ +- if [ "$USE_CUDA" = "true" ]; then \ +- # If you use CUDA the whisper and embedding model will be downloaded on first use +- pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/$USE_CUDA_DOCKER_VER --no-cache-dir && \ +- uv pip install --system -r requirements.txt --no-cache-dir && \ +- python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \ +- python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ.get('AUXILIARY_EMBEDDING_MODEL', 'TaylorAI/bge-micro-v2'), device='cpu')" && \ +- python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])"; \ +- python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \ +- else \ +- pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu --no-cache-dir && \ +- uv pip install --system -r requirements.txt --no-cache-dir && \ +- if [ "$USE_SLIM" != "true" ]; then \ +- python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \ +- python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ.get('AUXILIARY_EMBEDDING_MODEL', 'TaylorAI/bge-micro-v2'), device='cpu')" && \ +- python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])"; \ +- python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \ +- fi; \ +- fi; \ +- mkdir -p /app/backend/data && chown -R $UID:$GID /app/backend/data/ && \ +- rm -rf /var/lib/apt/lists/*; +- + # Install Ollama if requested + RUN if [ "$USE_OLLAMA" = "true" ]; then \ + date +%s > /tmp/ollama_build_hash && \ +@@ -164,6 +206,13 @@ RUN if [ "$USE_OLLAMA" = "true" ]; then \ + rm -rf /var/lib/apt/lists/*; \ + fi + ++## Copy artifacts from build stages ++# copy Python environment from 'deps' stages ++COPY --from=deps /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages ++#COPY --from=deps /usr/local/lib/uv /usr/local/lib/uv ++COPY --chown=$UID:$GID --from=deps /app/backend/data /app/backend/data ++ ++ + # copy embedding weight from build + # RUN mkdir -p /root/.cache/chroma/onnx_models/all-MiniLM-L6-v2 + # COPY --from=build /app/onnx /root/.cache/chroma/onnx_models/all-MiniLM-L6-v2/onnx +@@ -178,6 +227,7 @@ COPY --chown=$UID:$GID ./backend . + + EXPOSE 8080 + ++#Healthcheck and Final Permissisons + HEALTHCHECK CMD curl --silent --fail http://localhost:${PORT:-8080}/health | jq -ne 'input.status == true' || exit 1 + + # Minimal, atomic permission hardening for OpenShift (arbitrary UID): +@@ -193,8 +243,4 @@ RUN if [ "$USE_PERMISSION_HARDENING" = "true" ]; then \ + + USER $UID:$GID + +-ARG BUILD_HASH +-ENV WEBUI_BUILD_VERSION=${BUILD_HASH} +-ENV DOCKER=true +- + CMD [ "bash", "start.sh"] +diff --git a/backend/requirements.txt b/backend/requirements.txt +index 51f0a8a1a..0a1ffe568 100644 +--- a/backend/requirements.txt ++++ b/backend/requirements.txt +@@ -119,7 +119,7 @@ boto3==1.42.21 + + pymilvus==2.6.6 + qdrant-client==1.16.2 +-playwright==1.57.0 # Caution: version must match docker-compose.playwright.yaml - Update the docker-compose.yaml if necessary ++#playwright==1.57.0 # Caution: version must match docker-compose.playwright.yaml - Update the docker-compose.yaml if necessary + elasticsearch==9.2.1 + pinecone==6.0.2 + oracledb==3.4.1 +diff --git a/package.json b/package.json +index bc71db855..25cd76b38 100644 +--- a/package.json ++++ b/package.json +@@ -150,5 +150,10 @@ + "engines": { + "node": ">=18.13.0 <=22.x.x", + "npm": ">=6.0.0" +- } ++ }, ++ "overrides": { ++ "@parcel/watcher": "npm:@parcel/watcher-wasm", ++ "lightningcss": "npm:lightningcss-wasm", ++ "@tailwindcss/oxide": "https://npm.fury.io/mgiessing/~/up/ver_1hoo34/%40tailwindcss%2Foxide-4.1.13.tgz" ++ } + }