diff --git a/.github/workflows/scripts/codeScan/hadolint.sh b/.github/workflows/scripts/codeScan/hadolint.sh index e698d3634..a9a41f865 100644 --- a/.github/workflows/scripts/codeScan/hadolint.sh +++ b/.github/workflows/scripts/codeScan/hadolint.sh @@ -7,7 +7,7 @@ source /GenAIExamples/.github/workflows/scripts/change_color log_dir=/GenAIExamples/.github/workflows/scripts/codeScan ERROR_WARN=false -find . -type f \( -name "Dockerfile*" \) -print -exec hadolint --ignore DL3006 --ignore DL3007 --ignore DL3008 --ignore DL3013 {} \; > ${log_dir}/hadolint.log +find . -type f \( -name "Dockerfile*" \) -print -exec hadolint --ignore DL3006 --ignore DL3007 --ignore DL3008 --ignore DL3013 --ignore DL3018 --ignore DL3016 {} \; > ${log_dir}/hadolint.log if [[ $(grep -c "error" ${log_dir}/hadolint.log) != 0 ]]; then $BOLD_RED && echo "Error!! Please Click on the artifact button to download and check error details." && $RESET diff --git a/AgentQnA/ui/docker/Dockerfile b/AgentQnA/ui/docker/Dockerfile index 8cd279898..1f5605a15 100644 --- a/AgentQnA/ui/docker/Dockerfile +++ b/AgentQnA/ui/docker/Dockerfile @@ -1,49 +1,204 @@ -# Copyright (C) 2024 Intel Corporation +# Copyright (C) 2025 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -#FROM python:3.11-slim -FROM node:22.9.0 +# syntax=docker/dockerfile:1 +# Initialize device type args +# use build args in the docker build command with --build-arg="BUILDARG=true" +ARG USE_CUDA=false +ARG USE_OLLAMA=false +# Tested with cu117 for CUDA 11 and cu121 for CUDA 12 (default) +ARG USE_CUDA_VER=cu121 +# 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="" -ENV LANG=C.UTF-8 -ARG ARCH=cpu +# Tiktoken encoding name; models to use can be found at https://huggingface.co/models?library=tiktoken +ARG USE_TIKTOKEN_ENCODING_NAME="cl100k_base" -RUN apt-get update -y && apt-get install -y --no-install-recommends --fix-missing \ - build-essential \ - libgl1-mesa-glx \ - libjemalloc-dev \ - git \ - python3-venv +ARG BUILD_HASH=dev-build +# Override at your own risk - non-root configurations are untested +ARG UID=0 +ARG GID=0 +######## WebUI frontend ######## +FROM --platform=$BUILDPLATFORM node:22-alpine3.20 AS build +ARG BUILD_HASH + +WORKDIR /app + +COPY open_webui_patches /app/patches +ARG WEBUI_VERSION=v0.5.20 +RUN apk add --no-cache git + +# Clone code and use patch +RUN git config --global user.name "opea" && \ + git config --global user.email "" && \ + git clone https://github.com/open-webui/open-webui.git + +WORKDIR /app/open-webui + +RUN git checkout ${WEBUI_VERSION} && \ + if [ -d patches ] && [ "$(ls -A patches)" ]; then git am /app/patches/*.patch; fi + +WORKDIR /app + +RUN mv open-webui/* . && rm -fr open-webui && ls -lrth /app/backend/ + +RUN npm install onnxruntime-node --onnxruntime-node-install-cuda=skip +RUN apk update && \ + apk add --no-cache wget && \ + wget https://github.com/microsoft/onnxruntime/releases/download/v1.20.1/onnxruntime-linux-x64-gpu-1.20.1.tgz + +ENV APP_BUILD_HASH=${BUILD_HASH} +RUN npm run build + +######## WebUI backend ######## +FROM python:3.11-slim-bookworm AS base + +# Use args +ARG USE_CUDA +ARG USE_OLLAMA +ARG USE_CUDA_VER +ARG USE_EMBEDDING_MODEL +ARG USE_RERANKING_MODEL +ARG UID +ARG GID + +## Basis ## +ENV ENV=prod \ + PORT=8080 \ + # pass build args to the build + USE_OLLAMA_DOCKER=${USE_OLLAMA} \ + USE_CUDA_DOCKER=${USE_CUDA} \ + USE_CUDA_DOCKER_VER=${USE_CUDA_VER} \ + USE_EMBEDDING_MODEL_DOCKER=${USE_EMBEDDING_MODEL} \ + USE_RERANKING_MODEL_DOCKER=${USE_RERANKING_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" \ + 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" + +#### Other models ########################################################## + +COPY --from=build /app/backend /app/backend + +WORKDIR /app/backend -WORKDIR /root/ ENV HOME=/root -ENV VIRTUAL_ENV=$HOME/.env/open-webui +# Create user and group if not root +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 open_webui_patches /root/patches +RUN mkdir -p $HOME/.cache/chroma +RUN printf 00000000-0000-0000-0000-000000000000 > $HOME/.cache/chroma/telemetry_user_id -RUN git clone https://github.com/open-webui/open-webui.git && \ - git config --global user.name "opea" && git config --global user.email "" && \ - mkdir -p $HOME/.env && python3 -m venv $VIRTUAL_ENV && \ - $VIRTUAL_ENV/bin/python -m pip install --no-cache-dir --upgrade pip && \ - $VIRTUAL_ENV/bin/python -m pip install --no-cache-dir build +# Make sure the user has access to the app and root directory +RUN chown -R $UID:$GID /app $HOME -WORKDIR /root/open-webui +SHELL ["/bin/bash", "-o", "pipefail", "-c"] -ENV PATH="$VIRTUAL_ENV/bin:$PATH" +RUN if [ "$USE_OLLAMA" = "true" ]; then \ + apt-get update && \ + # Install pandoc and netcat + apt-get install -y --no-install-recommends git build-essential pandoc netcat-openbsd curl && \ + apt-get install -y --no-install-recommends gcc python3-dev && \ + # for RAG OCR + apt-get install -y --no-install-recommends ffmpeg libsm6 libxext6 && \ + # install helper tools + apt-get install -y --no-install-recommends curl jq && \ + # install ollama + curl -fsSL https://ollama.com/install.sh | sh && \ + # cleanup + rm -rf /var/lib/apt/lists/*; \ + else \ + apt-get update && \ + # Install pandoc, netcat and gcc + apt-get install -y --no-install-recommends git build-essential pandoc gcc netcat-openbsd curl jq && \ + apt-get install -y --no-install-recommends gcc python3-dev && \ + # for RAG OCR + apt-get install -y --no-install-recommends ffmpeg libsm6 libxext6 && \ + # cleanup + rm -rf /var/lib/apt/lists/*; \ + fi -RUN git checkout v0.5.20 && \ - git am ../patches/*.patch && \ - python -m build && \ - pip install --no-cache-dir dist/open_webui-0.5.20-py3-none-any.whl +# install python dependencies +# COPY --chown=$UID:$GID ./backend/requirements.txt ./requirements.txt +# RUN cp /app/backend/requirements.txt ./requirements.txt -ENV LANG=en_US.UTF-8 - -WORKDIR /root/ - -RUN rm -fr /root/open-webui && rm -fr /root/patches - -# CMD ["/bin/bash"] -ENTRYPOINT ["open-webui", "serve"] +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 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 && \ + 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; \ + chown -R $UID:$GID /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 CMD curl --silent --fail http://localhost:${PORT:-8080}/health | jq -ne 'input.status == true' || exit 1 + +USER $UID:$GID + +ARG BUILD_HASH +ENV WEBUI_BUILD_VERSION=${BUILD_HASH} +ENV DOCKER=true + +CMD [ "bash", "start.sh"]