diff --git a/Dockerfile b/Dockerfile index 2711478673..2256680762 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,6 +27,8 @@ ARG GID=0 FROM --platform=$BUILDPLATFORM node:22-alpine3.20 AS build ARG BUILD_HASH 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" @@ -44,6 +46,12 @@ ENV APP_BUILD_HASH=${BUILD_HASH} 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.11-slim-bookworm AS base @@ -132,10 +140,12 @@ RUN if [ "$USE_SLIM" = "true" ] && { [ "$USE_CUDA" = "true" ] || [ "$USE_OLLAMA" # Keep the slim runtime free of local document/audio processing tools. RUN apt-get update && \ apt-get install -y --no-install-recommends \ - git curl jq ca-certificates zstd \ + git curl jq ca-certificates \ && if [ "$USE_SLIM" != "true" ]; then \ apt-get install -y --no-install-recommends \ 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 @@ -193,19 +203,8 @@ 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 . - -# The backend rewrites its bundled static assets (favicons, splash, manifest, -# loader.js, ...) under open_webui/static at startup. Make that directory -# writable by an arbitrary UID -- which under OpenShift's restricted SCC is -# always a member of GID 0 -- so those writes don't fail with EACCES and crash -# the boot log with "[Errno 13] Permission denied". `chmod -R g=u` mirrors the -# owner bits onto the group (the Red Hat arbitrary-UID idiom). This is applied -# unconditionally because it targets a directory the app writes on every start; -# the broader, opt-in USE_PERMISSION_HARDENING below covers the rest of /app. -RUN chgrp -R 0 /app/backend/open_webui/static && \ - chmod -R g=u /app/backend/open_webui/static +# copy backend files with the ownership and static permissions prepared above +COPY --from=build /app/backend . EXPOSE 8080 diff --git a/backend/requirements-slim.txt b/backend/requirements-slim.txt index 31c7f78689..37f1213fa9 100644 --- a/backend/requirements-slim.txt +++ b/backend/requirements-slim.txt @@ -39,7 +39,6 @@ pycrdt==0.13.1 redis==8.0.1 hiredis==3.4.0 -APScheduler==3.11.2 python-dateutil==2.9.0.post0 pytz==2026.2 diff --git a/backend/requirements.txt b/backend/requirements.txt index ded3b1d24d..9e7f798360 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -46,7 +46,6 @@ mcp==1.27.2 openai==2.29.0 anthropic==0.86.0 -google-genai==1.66.0 langchain-community==0.4.2 langchain-classic==1.0.7 diff --git a/pyproject.toml b/pyproject.toml index f1c6f4c283..02f72633af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,6 @@ dependencies = [ "openai==2.29.0", "anthropic==0.86.0", - "google-genai==1.66.0", "langchain-community==0.4.2", "langchain-classic==1.0.7", diff --git a/uv.lock b/uv.lock index 0cf032981f..dde37e4f73 100644 --- a/uv.lock +++ b/uv.lock @@ -1392,11 +1392,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/44/71/c0321dc6d63d99946da45f7c06299b934e4f7f7da5c4f14d101bcb39adf1/google_auth-2.55.0-py3-none-any.whl", hash = "sha256:a17cef9dedf98c4ebae2fb0c48c8f75952c877cbc2efe09f329ef16c2783d88a", size = 252400, upload-time = "2026-06-15T22:33:14.992Z" }, ] -[package.optional-dependencies] -requests = [ - { name = "requests" }, -] - [[package]] name = "google-cloud-core" version = "2.6.0" @@ -1447,27 +1442,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9c/97/7d75fe37a7a6ed171a2cf17117177e7aab7e6e0d115858741b41e9dd4254/google_crc32c-1.8.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f639065ea2042d5c034bf258a9f085eaa7af0cd250667c0635a3118e8f92c69c", size = 28800, upload-time = "2025-12-16T00:40:30.322Z" }, ] -[[package]] -name = "google-genai" -version = "1.66.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "distro" }, - { name = "google-auth", extra = ["requests"] }, - { name = "httpx" }, - { name = "pydantic" }, - { name = "requests" }, - { name = "sniffio" }, - { name = "tenacity" }, - { name = "typing-extensions" }, - { name = "websockets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/9b/ba/0b343b0770d4710ad2979fd9301d7caa56c940174d5361ed4a7cc4979241/google_genai-1.66.0.tar.gz", hash = "sha256:ffc01647b65046bca6387320057aa51db0ad64bcc72c8e3e914062acfa5f7c49", size = 504386, upload-time = "2026-03-04T22:15:28.156Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/dd/403949d922d4e261b08b64aaa132af4e456c3b15c8e2a2d9e6ef693f66e2/google_genai-1.66.0-py3-none-any.whl", hash = "sha256:7f127a39cf695277104ce4091bb26e417c59bb46e952ff3699c3a982d9c474ee", size = 732174, upload-time = "2026-03-04T22:15:26.63Z" }, -] - [[package]] name = "google-resumable-media" version = "2.10.0" @@ -2804,7 +2778,6 @@ dependencies = [ { name = "faster-whisper" }, { name = "ftfy" }, { name = "google-cloud-storage" }, - { name = "google-genai" }, { name = "googleapis-common-protos" }, { name = "hiredis" }, { name = "httpx", extra = ["brotli", "cli", "http2", "socks", "zstd"] }, @@ -2931,7 +2904,6 @@ requires-dist = [ { name = "faster-whisper", specifier = "==1.2.1" }, { name = "ftfy", specifier = "==6.3.1" }, { name = "google-cloud-storage", specifier = "==3.9.0" }, - { name = "google-genai", specifier = "==1.66.0" }, { name = "googleapis-common-protos", specifier = "==1.75.0" }, { name = "hiredis", specifier = "==3.4.0" }, { name = "httpx", extras = ["brotli", "cli", "http2", "socks", "zstd"], specifier = "==0.28.1" },