|
1 |
| -# Copyright (C) 2024 Intel Corporation |
| 1 | +# Copyright (C) 2025 Intel Corporation |
2 | 2 | # SPDX-License-Identifier: Apache-2.0
|
3 | 3 |
|
4 |
| -#FROM python:3.11-slim |
5 |
| -FROM node:22.9.0 |
| 4 | +# syntax=docker/dockerfile:1 |
| 5 | +# Initialize device type args |
| 6 | +# use build args in the docker build command with --build-arg="BUILDARG=true" |
| 7 | +ARG USE_CUDA=false |
| 8 | +ARG USE_OLLAMA=false |
| 9 | +# Tested with cu117 for CUDA 11 and cu121 for CUDA 12 (default) |
| 10 | +ARG USE_CUDA_VER=cu121 |
| 11 | +# any sentence transformer model; models to use can be found at https://huggingface.co/models?library=sentence-transformers |
| 12 | +# Leaderboard: https://huggingface.co/spaces/mteb/leaderboard |
| 13 | +# for better performance and multilangauge support use "intfloat/multilingual-e5-large" (~2.5GB) or "intfloat/multilingual-e5-base" (~1.5GB) |
| 14 | +# 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. |
| 15 | +ARG USE_EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2 |
| 16 | +ARG USE_RERANKING_MODEL="" |
6 | 17 |
|
7 |
| -ENV LANG=C.UTF-8 |
8 |
| -ARG ARCH=cpu |
| 18 | +# Tiktoken encoding name; models to use can be found at https://huggingface.co/models?library=tiktoken |
| 19 | +ARG USE_TIKTOKEN_ENCODING_NAME="cl100k_base" |
9 | 20 |
|
10 |
| -RUN apt-get update -y && apt-get install -y --no-install-recommends --fix-missing \ |
11 |
| - build-essential \ |
12 |
| - libgl1-mesa-glx \ |
13 |
| - libjemalloc-dev \ |
14 |
| - git \ |
15 |
| - python3-venv |
| 21 | +ARG BUILD_HASH=dev-build |
| 22 | +# Override at your own risk - non-root configurations are untested |
| 23 | +ARG UID=0 |
| 24 | +ARG GID=0 |
16 | 25 |
|
| 26 | +######## WebUI frontend ######## |
| 27 | +FROM --platform=$BUILDPLATFORM node:22-alpine3.20 AS build |
| 28 | +ARG BUILD_HASH |
17 | 29 |
|
18 |
| -WORKDIR /root/ |
| 30 | +WORKDIR /app |
19 | 31 |
|
20 |
| -ENV HOME=/root |
21 |
| -ENV VIRTUAL_ENV=$HOME/.env/open-webui |
| 32 | +COPY open_webui_patches /app/patches |
| 33 | +ARG WEBUI_VERSION=v0.5.20 |
| 34 | +RUN apk add --no-cache git |
| 35 | + |
| 36 | +# Clone code and use patch |
| 37 | +RUN git config --global user.name "opea" && \ |
| 38 | + git config --global user.email "" && \ |
| 39 | + git clone https://github.com/open-webui/open-webui.git |
| 40 | + |
| 41 | +WORKDIR /app/open-webui |
| 42 | + |
| 43 | +RUN git checkout ${WEBUI_VERSION} && \ |
| 44 | + if [ -d patches ] && [ "$(ls -A patches)" ]; then git am /app/patches/*.patch; fi |
| 45 | + |
| 46 | +WORKDIR /app |
| 47 | + |
| 48 | +RUN mv open-webui/* . && rm -fr open-webui && ls -lrth /app/backend/ |
22 | 49 |
|
23 |
| -COPY open_webui_patches /root/patches |
| 50 | +RUN npm install onnxruntime-node --onnxruntime-node-install-cuda=skip |
| 51 | +RUN apk update && \ |
| 52 | + apk add --no-cache wget && \ |
| 53 | + wget https://github.com/microsoft/onnxruntime/releases/download/v1.20.1/onnxruntime-linux-x64-gpu-1.20.1.tgz |
24 | 54 |
|
25 |
| -RUN git clone https://github.com/open-webui/open-webui.git && \ |
26 |
| - git config --global user.name "opea" && git config --global user.email "" && \ |
27 |
| - mkdir -p $HOME/.env && python3 -m venv $VIRTUAL_ENV && \ |
28 |
| - $VIRTUAL_ENV/bin/python -m pip install --no-cache-dir --upgrade pip && \ |
29 |
| - $VIRTUAL_ENV/bin/python -m pip install --no-cache-dir build |
| 55 | +ENV APP_BUILD_HASH=${BUILD_HASH} |
| 56 | +RUN npm run build |
30 | 57 |
|
31 |
| -WORKDIR /root/open-webui |
| 58 | +######## WebUI backend ######## |
| 59 | +FROM python:3.11-slim-bookworm AS base |
32 | 60 |
|
33 |
| -ENV PATH="$VIRTUAL_ENV/bin:$PATH" |
| 61 | +# Use args |
| 62 | +ARG USE_CUDA |
| 63 | +ARG USE_OLLAMA |
| 64 | +ARG USE_CUDA_VER |
| 65 | +ARG USE_EMBEDDING_MODEL |
| 66 | +ARG USE_RERANKING_MODEL |
| 67 | +ARG UID |
| 68 | +ARG GID |
34 | 69 |
|
35 |
| -RUN git checkout v0.5.20 && \ |
36 |
| - git am ../patches/*.patch && \ |
37 |
| - python -m build && \ |
38 |
| - pip install --no-cache-dir dist/open_webui-0.5.20-py3-none-any.whl |
| 70 | +## Basis ## |
| 71 | +ENV ENV=prod \ |
| 72 | + PORT=8080 \ |
| 73 | + # pass build args to the build |
| 74 | + USE_OLLAMA_DOCKER=${USE_OLLAMA} \ |
| 75 | + USE_CUDA_DOCKER=${USE_CUDA} \ |
| 76 | + USE_CUDA_DOCKER_VER=${USE_CUDA_VER} \ |
| 77 | + USE_EMBEDDING_MODEL_DOCKER=${USE_EMBEDDING_MODEL} \ |
| 78 | + USE_RERANKING_MODEL_DOCKER=${USE_RERANKING_MODEL} |
39 | 79 |
|
40 |
| -ENV LANG=en_US.UTF-8 |
| 80 | +## Basis URL Config ## |
| 81 | +ENV OLLAMA_BASE_URL="/ollama" \ |
| 82 | + OPENAI_API_BASE_URL="" |
41 | 83 |
|
42 |
| -WORKDIR /root/ |
| 84 | +## API Key and Security Config ## |
| 85 | +ENV OPENAI_API_KEY="" \ |
| 86 | + WEBUI_SECRET_KEY="" \ |
| 87 | + SCARF_NO_ANALYTICS=true \ |
| 88 | + DO_NOT_TRACK=true \ |
| 89 | + ANONYMIZED_TELEMETRY=false |
43 | 90 |
|
44 |
| -RUN rm -fr /root/open-webui && rm -fr /root/patches |
| 91 | +#### Other models ######################################################### |
| 92 | +## whisper TTS model settings ## |
| 93 | +ENV WHISPER_MODEL="base" \ |
| 94 | + WHISPER_MODEL_DIR="/app/backend/data/cache/whisper/models" |
45 | 95 |
|
46 |
| -# CMD ["/bin/bash"] |
47 |
| -ENTRYPOINT ["open-webui", "serve"] |
| 96 | +## RAG Embedding model settings ## |
| 97 | +ENV RAG_EMBEDDING_MODEL="$USE_EMBEDDING_MODEL_DOCKER" \ |
| 98 | + RAG_RERANKING_MODEL="$USE_RERANKING_MODEL_DOCKER" \ |
| 99 | + SENTENCE_TRANSFORMERS_HOME="/app/backend/data/cache/embedding/models" |
48 | 100 |
|
| 101 | +## Tiktoken model settings ## |
| 102 | +ENV TIKTOKEN_ENCODING_NAME="cl100k_base" \ |
| 103 | + TIKTOKEN_CACHE_DIR="/app/backend/data/cache/tiktoken" |
| 104 | + |
| 105 | +## Hugging Face download cache ## |
| 106 | +ENV HF_HOME="/app/backend/data/cache/embedding/models" |
49 | 107 |
|
| 108 | +## Torch Extensions ## |
| 109 | +# ENV TORCH_EXTENSIONS_DIR="/.cache/torch_extensions" |
| 110 | + |
| 111 | +#### Other models ########################################################## |
| 112 | + |
| 113 | +COPY --from=build /app/backend /app/backend |
| 114 | + |
| 115 | +WORKDIR /app/backend |
| 116 | + |
| 117 | + |
| 118 | +ENV HOME=/root |
| 119 | +# Create user and group if not root |
| 120 | +RUN if [ $UID -ne 0 ]; then \ |
| 121 | + if [ $GID -ne 0 ]; then \ |
| 122 | + addgroup --gid $GID app; \ |
| 123 | + fi; \ |
| 124 | + adduser --uid $UID --gid $GID --home $HOME --disabled-password --no-create-home app; \ |
| 125 | + fi |
| 126 | + |
| 127 | +RUN mkdir -p $HOME/.cache/chroma |
| 128 | +RUN printf 00000000-0000-0000-0000-000000000000 > $HOME/.cache/chroma/telemetry_user_id |
| 129 | + |
| 130 | +# Make sure the user has access to the app and root directory |
| 131 | +RUN chown -R $UID:$GID /app $HOME |
| 132 | + |
| 133 | +SHELL ["/bin/bash", "-o", "pipefail", "-c"] |
| 134 | + |
| 135 | +RUN if [ "$USE_OLLAMA" = "true" ]; then \ |
| 136 | + apt-get update && \ |
| 137 | + # Install pandoc and netcat |
| 138 | + apt-get install -y --no-install-recommends git build-essential pandoc netcat-openbsd curl && \ |
| 139 | + apt-get install -y --no-install-recommends gcc python3-dev && \ |
| 140 | + # for RAG OCR |
| 141 | + apt-get install -y --no-install-recommends ffmpeg libsm6 libxext6 && \ |
| 142 | + # install helper tools |
| 143 | + apt-get install -y --no-install-recommends curl jq && \ |
| 144 | + # install ollama |
| 145 | + curl -fsSL https://ollama.com/install.sh | sh && \ |
| 146 | + # cleanup |
| 147 | + rm -rf /var/lib/apt/lists/*; \ |
| 148 | + else \ |
| 149 | + apt-get update && \ |
| 150 | + # Install pandoc, netcat and gcc |
| 151 | + apt-get install -y --no-install-recommends git build-essential pandoc gcc netcat-openbsd curl jq && \ |
| 152 | + apt-get install -y --no-install-recommends gcc python3-dev && \ |
| 153 | + # for RAG OCR |
| 154 | + apt-get install -y --no-install-recommends ffmpeg libsm6 libxext6 && \ |
| 155 | + # cleanup |
| 156 | + rm -rf /var/lib/apt/lists/*; \ |
| 157 | + fi |
| 158 | + |
| 159 | +# install python dependencies |
| 160 | +# COPY --chown=$UID:$GID ./backend/requirements.txt ./requirements.txt |
| 161 | +# RUN cp /app/backend/requirements.txt ./requirements.txt |
| 162 | + |
| 163 | +RUN pip3 install --no-cache-dir uv && \ |
| 164 | + if [ "$USE_CUDA" = "true" ]; then \ |
| 165 | + # If you use CUDA the whisper and embedding model will be downloaded on first use |
| 166 | + pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/$USE_CUDA_DOCKER_VER --no-cache-dir && \ |
| 167 | + uv pip install --system -r requirements.txt --no-cache-dir && \ |
| 168 | + python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \ |
| 169 | + 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'])"; \ |
| 170 | + python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \ |
| 171 | + else \ |
| 172 | + pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu --no-cache-dir && \ |
| 173 | + uv pip install --system -r requirements.txt --no-cache-dir && \ |
| 174 | + python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \ |
| 175 | + 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'])"; \ |
| 176 | + python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \ |
| 177 | + fi; \ |
| 178 | + chown -R $UID:$GID /app/backend/data/ |
| 179 | + |
| 180 | + |
| 181 | + |
| 182 | +# copy embedding weight from build |
| 183 | +# RUN mkdir -p /root/.cache/chroma/onnx_models/all-MiniLM-L6-v2 |
| 184 | +# COPY --from=build /app/onnx /root/.cache/chroma/onnx_models/all-MiniLM-L6-v2/onnx |
| 185 | + |
| 186 | +# copy built frontend files |
| 187 | +COPY --chown=$UID:$GID --from=build /app/build /app/build |
| 188 | +COPY --chown=$UID:$GID --from=build /app/CHANGELOG.md /app/CHANGELOG.md |
| 189 | +COPY --chown=$UID:$GID --from=build /app/package.json /app/package.json |
| 190 | + |
| 191 | +# copy backend files |
| 192 | +# COPY --chown=$UID:$GID ./backend . |
| 193 | + |
| 194 | +EXPOSE 8080 |
| 195 | + |
| 196 | +HEALTHCHECK CMD curl --silent --fail http://localhost:${PORT:-8080}/health | jq -ne 'input.status == true' || exit 1 |
| 197 | + |
| 198 | +USER $UID:$GID |
| 199 | + |
| 200 | +ARG BUILD_HASH |
| 201 | +ENV WEBUI_BUILD_VERSION=${BUILD_HASH} |
| 202 | +ENV DOCKER=true |
| 203 | + |
| 204 | +CMD [ "bash", "start.sh"] |
0 commit comments