mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-22 03:14:54 -05:00
The Docker image now runs Python 3.12 on Debian 13 (trixie) instead of Python 3.11 on Debian 12, and the pip install docs recommend 3.12. Image size stays about the same: the slim image is 1 MB smaller and the standard image is about 50 MB larger, mostly from the newer ffmpeg and pandoc that Debian 13 ships. Admins should know that custom functions, tools and anything installed with pip inside the container now run on Python 3.12, so a package that only has builds for 3.11 needs a newer version. Installing with pip still works on both Python 3.11 and 3.12.
235 lines
9.5 KiB
Docker
235 lines
9.5 KiB
Docker
# 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
|
|
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
|
|
ARG BUILD_CHANNEL=unknown
|
|
# 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
|
|
ARG BUILD_CHANNEL
|
|
ARG USE_SLIM
|
|
ARG UID
|
|
ARG GID
|
|
|
|
# Set Node.js options (heap limit Allocation failed - JavaScript heap out of memory)
|
|
# ENV NODE_OPTIONS="--max-old-space-size=4096"
|
|
|
|
WORKDIR /app
|
|
|
|
# to store git revision in build
|
|
RUN apk add --no-cache git
|
|
|
|
COPY package.json package-lock.json ./
|
|
RUN npm ci --force
|
|
|
|
COPY . .
|
|
ENV APP_BUILD_HASH=${BUILD_HASH}
|
|
ENV APP_BUILD_CHANNEL=${BUILD_CHANNEL}
|
|
RUN npm run build && \
|
|
if [ "$USE_SLIM" = "true" ]; then find build -type f -name '*.map' -delete; fi
|
|
|
|
# Prepare backend ownership before the final copy so static assets occupy one layer.
|
|
# Group 0 write access lets arbitrary OpenShift UIDs update these assets at startup.
|
|
RUN chown -R $UID:$GID /app/backend && \
|
|
chgrp -R 0 /app/backend/open_webui/static && \
|
|
chmod -R g=u /app/backend/open_webui/static
|
|
|
|
######## WebUI backend ########
|
|
FROM python:3.12-slim-trixie AS base
|
|
|
|
# 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
|
|
|
|
## Basis ##
|
|
ENV ENV=prod \
|
|
PORT=8080 \
|
|
# 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"
|
|
|
|
#### Other models ##########################################################
|
|
|
|
WORKDIR /app/backend
|
|
|
|
ENV HOME=/root
|
|
# 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
|
|
|
|
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
|
|
|
|
# Slim cannot bundle a local model server or GPU runtime.
|
|
RUN if [ "$USE_SLIM" = "true" ] && { [ "$USE_CUDA" = "true" ] || [ "$USE_OLLAMA" = "true" ]; }; then \
|
|
echo "USE_SLIM cannot be combined with USE_CUDA or USE_OLLAMA" >&2; exit 1; fi
|
|
|
|
# Keep the slim runtime free of local document/audio processing tools.
|
|
# Git-based tool requirements require the standard image.
|
|
RUN apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
curl jq ca-certificates \
|
|
&& if [ "$USE_SLIM" != "true" ]; then \
|
|
apt-get install -y --no-install-recommends \
|
|
git build-essential pandoc gcc libmariadb-dev ffmpeg libsm6 libxext6; \
|
|
fi && if [ "$USE_OLLAMA" = "true" ]; then \
|
|
apt-get install -y --no-install-recommends zstd; \
|
|
fi && rm -rf /var/lib/apt/lists/*
|
|
|
|
# install python dependencies
|
|
COPY --chown=$UID:$GID ./backend/requirements*.txt ./
|
|
|
|
# Set UV_LINK_MODE to copy to prevent 0-byte file corruption in QEMU arm64 cross-builds
|
|
ENV UV_LINK_MODE=copy
|
|
|
|
RUN --mount=from=ghcr.io/astral-sh/uv:0.12.10,source=/uv,target=/bin/uv \
|
|
set -e; \
|
|
if [ "$USE_SLIM" = "true" ]; then \
|
|
uv pip install --system -r requirements-slim.txt --no-cache-dir; \
|
|
elif [ "$USE_CUDA" = "true" ]; then \
|
|
# If you use CUDA the whisper and embedding model will be downloaded on first use
|
|
# fix: pin torch<=2.9.1 - torch 2.10.0 aarch64 wheels cause SIGILL on ARM devices (RPi 4 Cortex-A72) #21349
|
|
pip3 install 'torch<=2.9.1' 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<=2.9.1' 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/; \
|
|
if [ -d /app/backend/data/cache ]; then chmod -R a+rX /app/backend/data/cache; fi; \
|
|
rm -rf /var/lib/apt/lists/*;
|
|
|
|
# Optional: PPTX parsing through unstructured may need spaCy's English model.
|
|
# Keep this out of the default image to avoid the extra image bloat; deployments
|
|
# with read-only site-packages can uncomment it and bake the model in.
|
|
# RUN python -m spacy download en_core_web_sm
|
|
|
|
# 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 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 with the ownership and static permissions prepared above
|
|
COPY --from=build /app/backend .
|
|
|
|
EXPOSE 8080
|
|
|
|
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
|
|
|
|
ARG BUILD_HASH
|
|
ENV WEBUI_BUILD_HASH=${BUILD_HASH}
|
|
ENV DOCKER=true
|
|
|
|
CMD [ "bash", "start.sh"]
|