* fix(docker): make Real-ESRGAN installable on the Python 3.14 image
realesrgan's deps basicsr/gfpgan/facexlib (unmaintained since 2022) read
their version in setup.py via `exec(...); locals()['__version__']`, which
raises KeyError on Python 3.13+ — PEP 667 made locals() in a function an
independent snapshot that exec() can no longer mutate. That fails the
Cookbook "install realesrgan" sdist build on the python:3.14 base.
Add a `realesrgan-wheels` builder stage that fetches the pinned sdists,
patches get_version() to exec into an explicit namespace dict, and builds
wheels; the final stage installs them --no-deps so a later
`pip install realesrgan` resolves from wheels instead of rebuilding the
broken sdists. torch stays a runtime pull to keep the base image lean.
Also add the runtime libs opencv-python (cv2) needs — libgl1,
libglib2.0-0t64, libxcb1 — which the slim base omits; without them the
install succeeds but `import cv2` dies with
`libxcb.so.1: cannot open shared object file`.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(cookbook): don't let a package's sys.exit() on import hang the deps panel
The local optional-dependency probe imports each package in-process and
catches ImportError / Exception. But a package can call sys.exit() at
import time — e.g. rembg does `sys.exit(1)` when no onnxruntime backend
loads. SystemExit is a BaseException, not Exception, so it escaped the
probe, propagated out of the list_packages endpoint, and hung the whole
Dependencies panel / worker (the UI loads forever).
Catch (Exception, SystemExit) so one broken optional package is reported
as not-usable instead of taking down the panel.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Cookbook now needs to docker-exec into ollama-rocm (and any other sibling
container holding a model server) from inside its own container, so:
- Dockerfile installs the Docker CLI from the static binary tarball
(the Debian docker.io package ships dockerd but not the client on slim)
- docker-compose.yml bind-mounts /var/run/docker.sock and adds group_add
for the host docker group (default GID 963)
- entrypoint.sh detects the socket GID, creates a local group with that
GID, and runs usermod -aG before gosu-dropping to the app user so the
supplementary group propagates through (gosu strips by default)
Default image installs requirements.txt only. Set INSTALL_OPTIONAL=true
at build time to add requirements-optional.txt (PyMuPDF, markitdown, etc.)
without baking AGPL into the standard distributed image.
Co-authored-by: Cursor <cursoragent@cursor.com>