Compare commits

..
Author SHA1 Message Date
dependabot[bot] 38498a1e10 chore(deps): bump the python group across 1 directory with 7 updates
Updates the requirements on [rapidocr](https://github.com/RapidAI/RapidOCR), [onnxruntime](https://github.com/microsoft/onnxruntime), [markitdown](https://github.com/microsoft/markitdown), [httpcore](https://github.com/encode/httpcore), [pydantic](https://github.com/pydantic/pydantic), [pydantic-settings](https://github.com/pydantic/pydantic-settings) and [mcp](https://github.com/modelcontextprotocol/python-sdk) to permit the latest version.

Updates `rapidocr` from 3.9.2 to 3.10.0
- [Release notes](https://github.com/RapidAI/RapidOCR/releases)
- [Commits](https://github.com/RapidAI/RapidOCR/compare/v3.9.2...v3.10.0)

Updates `onnxruntime` to 1.31.0
- [Release notes](https://github.com/microsoft/onnxruntime/releases)
- [Changelog](https://github.com/microsoft/onnxruntime/blob/main/docs/ReleaseNotesWorkflow.md)
- [Commits](https://github.com/microsoft/onnxruntime/compare/v1.20.0...v1.31.0)

Updates `markitdown` from 0.1.6 to 0.1.9
- [Release notes](https://github.com/microsoft/markitdown/releases)
- [Commits](https://github.com/microsoft/markitdown/compare/v0.1.6...v0.1.9)

Updates `httpcore` to 1.0.9
- [Release notes](https://github.com/encode/httpcore/releases)
- [Changelog](https://github.com/encode/httpcore/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/httpcore/compare/1.0.0...1.0.9)

Updates `pydantic` to 2.14.1
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.13.4...v2.14.1)

Updates `pydantic-settings` to 2.16.1
- [Release notes](https://github.com/pydantic/pydantic-settings/releases)
- [Commits](https://github.com/pydantic/pydantic-settings/compare/v2.14.1...v2.16.1)

Updates `mcp` to 2.3.0
- [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases)
- [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md)
- [Commits](https://github.com/modelcontextprotocol/python-sdk/compare/v0.2.0...v2.3.0)

---
updated-dependencies:
- dependency-name: httpcore
  dependency-version: 1.0.9
  dependency-type: direct:production
  dependency-group: python
- dependency-name: markitdown
  dependency-version: 0.1.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: python
- dependency-name: mcp
  dependency-version: 2.3.0
  dependency-type: direct:production
  dependency-group: python
- dependency-name: onnxruntime
  dependency-version: 1.31.0
  dependency-type: direct:production
  dependency-group: python
- dependency-name: pydantic
  dependency-version: 2.14.1
  dependency-type: direct:production
  dependency-group: python
- dependency-name: pydantic-settings
  dependency-version: 2.15.0
  dependency-type: direct:production
  dependency-group: python
- dependency-name: rapidocr
  dependency-version: 3.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: python
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-25 12:50:12 +00:00
RaresKeY 9d0d3720f4 fix(deps): require Pillow 13 with compatible FastEmbed (#6845) 2026-10-25 13:45:49 +01:00
Tim FandLéo a0c93f38ef chore: harden and update supporting services (#6788)
* chore: harden and update supporting services

* chore(compose): pin ChromaDB and ntfy images by tag and digest

chromadb/chroma:latest and a bare binwiederhier/ntfy change underneath
an existing install on the next pull, so two hosts on the same commit
can run different sidecar builds. SearXNG is already pinned this way.

Pin chroma 1.5.9 and ntfy v2.32.0 to the multi-arch index digests that
:latest currently resolves to, so nothing changes at runtime today. The
standalone GPU files carry the same references, as
test_gpu_compose_standalone.py requires. Add a test that every sidecar
image has a release tag and a digest.

---------

Co-authored-by: Léo <leograndcontact@gmail.com>
2026-10-24 17:44:07 +02:00
16 changed files with 75 additions and 40 deletions
+5 -5
View File
@@ -76,7 +76,7 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.11"
# Byte-compile sources — catches syntax errors without installing deps.
@@ -91,7 +91,7 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22.23.4"
- run: npm ci --ignore-scripts --no-audit --no-fund
@@ -151,7 +151,7 @@ jobs:
echo "docs_only=false" >> "$GITHUB_OUTPUT"
fi
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
if: steps.docs-check.outputs.docs_only != 'true'
with:
python-version: "3.11"
@@ -168,7 +168,7 @@ jobs:
# uv resolves the same versions as pip but installs ~5x faster, and its
# cache keeps each shard from re-downloading the whole requirement set.
- uses: astral-sh/setup-uv@18d369b23da25a81e9458561248e1aafff6a70fa # v10.3.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
if: steps.docs-check.outputs.docs_only != 'true'
with:
version: "0.13.5"
@@ -180,7 +180,7 @@ jobs:
python scripts/check_ca_trust.py --python
uv pip install --system -r requirements.txt
if: steps.docs-check.outputs.docs_only != 'true'
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
if: steps.docs-check.outputs.docs_only != 'true'
with:
node-version: "22.23.4"
+2 -2
View File
@@ -31,11 +31,11 @@ jobs:
with:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
languages: ${{ matrix.language }}
build-mode: none
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
category: "/language:${{ matrix.language }}"
+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
persist-credentials: false
- name: Lint Dockerfile
uses: hadolint/hadolint-action@06be81baf89a55ffd0e24b8f04a4185738dd3387 # v3.5.0
uses: hadolint/hadolint-action@2a66e89f53d0771bb131a7fa31f3136336094aa6 # v3.4.0
with:
dockerfile: Dockerfile
# DL3008: pinning apt package versions is impractical on a -slim base
+5 -5
View File
@@ -61,14 +61,14 @@ jobs:
persist-credentials: false
- name: Set up Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
with:
driver: docker
# Build without pushing so a broken Dockerfile is caught here, and the
# exact image we ship is what gets scanned.
- name: Build image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
push: false
@@ -107,12 +107,12 @@ jobs:
persist-credentials: false
- name: Set up Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
with:
driver: docker
- name: Build image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
push: false
@@ -133,7 +133,7 @@ jobs:
TRIVY_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-db:2
- name: Upload Trivy results
uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
sarif_file: trivy-results.sarif
category: trivy-image
+1 -1
View File
@@ -63,7 +63,7 @@ jobs:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'
+1 -1
View File
@@ -47,4 +47,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
+5 -5
View File
@@ -55,7 +55,7 @@ jobs:
shell: bash
run: echo "IMAGE_NAME=${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV"
- name: Set up Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
- name: Log in to GHCR
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
@@ -64,7 +64,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push by digest
id: build
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
pull: true
@@ -78,7 +78,7 @@ jobs:
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: digest-${{ matrix.arch }}
path: /tmp/digests/*
@@ -107,13 +107,13 @@ jobs:
echo "version=$v" >> "$GITHUB_OUTPUT"
echo "short=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
- name: Download digests
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: /tmp/digests
pattern: digest-*
merge-multiple: true
- name: Set up Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
- name: Log in to GHCR
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
+2 -2
View File
@@ -62,9 +62,9 @@ jobs:
env:
SEARXNG_TEST_IMAGE: ${{ steps.image.outputs.image }}
run: docker pull "$SEARXNG_TEST_IMAGE"
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
- name: Check unmodified upstream trust and actual entrypoint offline
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
file: docker/searxng/Dockerfile
+1 -1
View File
@@ -66,7 +66,7 @@ jobs:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'
+2 -2
View File
@@ -48,8 +48,8 @@ just composed.
| Service | Image | Purpose | License |
|---|---|---|---|
| [SearXNG](https://github.com/searxng/searxng) | `searxng/searxng:2026.9.25-12f8b6515` (pinned tag; see compose) | Default metasearch backend | AGPL-3.0 |
| [ChromaDB](https://github.com/chroma-core/chroma) | `chromadb/chroma:latest` | Vector store for memory / RAG | Apache-2.0 |
| [ntfy](https://github.com/binwiederhier/ntfy) | `binwiederhier/ntfy` | Push notifications (self-hosted reminders) | Apache-2.0 / GPL-2.0 |
| [ChromaDB](https://github.com/chroma-core/chroma) | `chromadb/chroma:1.5.9` (pinned digest; see compose) | Vector store for memory / RAG | Apache-2.0 |
| [ntfy](https://github.com/binwiederhier/ntfy) | `binwiederhier/ntfy:v2.32.0` (pinned digest; see compose) | Push notifications (self-hosted reminders) | Apache-2.0 / GPL-2.0 |
## Bundled front-end libraries
+2 -2
View File
@@ -127,7 +127,7 @@ services:
- ${RENDER_GID:-render}
chromadb:
image: docker.io/chromadb/chroma:latest
image: docker.io/chromadb/chroma:1.5.9@sha256:1e0b73a187a28757c572acba508c46f48c9e8b0acaf5c20e6d95cdedce1acdf6
ports:
- "${CHROMADB_BIND:-127.0.0.1}:8100:8000"
volumes:
@@ -196,7 +196,7 @@ services:
restart: unless-stopped
ntfy:
image: docker.io/binwiederhier/ntfy
image: docker.io/binwiederhier/ntfy:v2.32.0@sha256:59250e1d8be2ee2186c4560322f625faef22ace380331f05b63f8842dbd62602
command: serve
ports:
- "${NTFY_BIND:-127.0.0.1}:8091:80"
+2 -2
View File
@@ -130,7 +130,7 @@ services:
capabilities: [gpu]
chromadb:
image: docker.io/chromadb/chroma:latest
image: docker.io/chromadb/chroma:1.5.9@sha256:1e0b73a187a28757c572acba508c46f48c9e8b0acaf5c20e6d95cdedce1acdf6
ports:
- "${CHROMADB_BIND:-127.0.0.1}:8100:8000"
volumes:
@@ -199,7 +199,7 @@ services:
restart: unless-stopped
ntfy:
image: docker.io/binwiederhier/ntfy
image: docker.io/binwiederhier/ntfy:v2.32.0@sha256:59250e1d8be2ee2186c4560322f625faef22ace380331f05b63f8842dbd62602
command: serve
ports:
- "${NTFY_BIND:-127.0.0.1}:8091:80"
+2 -2
View File
@@ -108,7 +108,7 @@ services:
restart: unless-stopped
chromadb:
image: docker.io/chromadb/chroma:latest
image: docker.io/chromadb/chroma:1.5.9@sha256:1e0b73a187a28757c572acba508c46f48c9e8b0acaf5c20e6d95cdedce1acdf6
ports:
- "${CHROMADB_BIND:-127.0.0.1}:8100:8000"
volumes:
@@ -177,7 +177,7 @@ services:
restart: unless-stopped
ntfy:
image: docker.io/binwiederhier/ntfy
image: docker.io/binwiederhier/ntfy:v2.32.0@sha256:59250e1d8be2ee2186c4560322f625faef22ace380331f05b63f8842dbd62602
command: serve
ports:
- "${NTFY_BIND:-127.0.0.1}:8091:80"
+3 -3
View File
@@ -1,7 +1,7 @@
# Optional dependencies — install only if you use the corresponding feature.
# Local OCR for screenshots, scans, labels, and coordinate-grounded text extraction.
rapidocr==3.9.2
onnxruntime>=1.20,<2
rapidocr==3.10.0
onnxruntime>=1.31.0,<2
# The app handles their absence gracefully (clear error message on first use).
#
# Note: chromadb-client + fastembed moved to requirements.txt — RAG, semantic
@@ -46,7 +46,7 @@ PyMuPDF
# magika (onnxruntime), already a core dep via fastembed. We avoid the
# [all]/Azure/audio extras (cloud + heavy). Pinned to a release >30 days old per
# the dependency-age discussion in issue #485.
markitdown[docx,pptx,xlsx,xls]==0.1.6
markitdown[docx,pptx,xlsx,xls]==0.1.9
# Photoshop PSD opening / flattened previews / layer inspection.
psd-tools
+7 -6
View File
@@ -5,13 +5,14 @@ python-dotenv
httpx
# HTTPS clients using certifi must distrust the compromised eMudhra CA paths.
certifi>=2026.10.23
httpcore>=1.0,<2.0
pydantic>=2.13.4
pydantic-settings>=2.14.1
httpcore>=1.0.9,<2.0
pydantic>=2.14.1
pydantic-settings>=2.16.1
SQLAlchemy
pypdf
pypdfium2
Pillow
# Pillow 13 fixes known image-processing advisories; keep local embeddings compatible.
Pillow>=13.0.0
faster-whisper
pdfplumber
beautifulsoup4
@@ -25,7 +26,7 @@ numpy
chromadb-client
# gRPC vendors independent roots; 1.84.1 removes the incident trust anchors.
grpcio>=1.84.1
fastembed
fastembed>=0.9.1
youtube-transcript-api
yt-dlp
# Markdown rendering for research reports (src/visual_report.py).
@@ -50,7 +51,7 @@ bcrypt
# Built-in servers use the v1 low-level Server decorator API. MCP SDK v2 is a
# breaking rewrite, so keep fresh installs on the maintained v1 line until the
# servers are migrated together.
mcp<2
mcp<3
pyotp
qrcode[pil]
croniter
+34
View File
@@ -0,0 +1,34 @@
"""Sidecar images must be pinned to a versioned tag and an immutable digest.
A bare or ``:latest`` reference changes underneath an existing install on the
next ``docker compose pull``/``up``, so two hosts on the same commit can run
different ChromaDB or ntfy builds. The ``odysseus`` service is excluded: it is
the project's own image, selected through ``ODYSSEUS_IMAGE``. The standalone
GPU files are held equal to these services by test_gpu_compose_standalone.py.
"""
import re
from pathlib import Path
import pytest
import yaml
COMPOSE = Path(__file__).resolve().parents[1] / "docker-compose.yml"
PINNED = re.compile(r"^[\w.\-/]+:(?P<tag>[\w.\-]+)@sha256:[0-9a-f]{64}$")
def _sidecars():
services = yaml.safe_load(COMPOSE.read_text(encoding="utf-8"))["services"]
return {name: svc["image"] for name, svc in services.items() if name != "odysseus"}
def test_expected_sidecars_present():
assert {"chromadb", "searxng", "ntfy"} <= set(_sidecars())
@pytest.mark.parametrize("name", sorted(_sidecars()))
def test_sidecar_image_has_version_tag_and_digest(name):
image = _sidecars()[name]
match = PINNED.match(image)
assert match, f"{name}: expected <repo>:<tag>@sha256:<digest>, got {image!r}"
assert match.group("tag") != "latest", f"{name}: pin a release tag, not latest"