build(docker): appuser-owned data directories; note uv's index strategy for the docling file

A named volume mounted on /app/inputs, /app/indexes or /app/vectors inherits
the ownership of the image directory, so the image creates them as appuser;
before this the volume came up root-owned and every upload failed with a
permission error unless the container ran as root. docker-compose-standalone.yaml
still runs backend and worker as root, like docker-compose-hub.yaml, so it
also works with image tags that predate these directories.

requirements-docling.txt adds the PyTorch CPU index, which uv resolves only
with UV_INDEX_STRATEGY=unsafe-best-match (pip is unaffected); the file header
and the docs say so and point uv users at uv sync --extra docling.
This commit is contained in:
Alex committed 2026-09-05 16:02:58 +01:00
1 parent aecb596e99
commit b502f216b7
6 files changed
+23 -1

No files matched your search

+2
View File
@@ -33,6 +33,8 @@ uv pip install -r application/requirements.txt # or: pip install -r application
# uv pip install -r application/requirements-docling.txt # docling parser engine (OCR backend, structured output)
# uv pip install -r application/requirements-milvus.txt # VECTOR_STORE=milvus
# With uv alone: `uv sync --extra docling` (pyproject.toml + uv.lock are the source of truth).
# `uv pip install -r application/requirements-docling.txt` needs UV_INDEX_STRATEGY=unsafe-best-match
# (the file adds the PyTorch CPU index; prefer `uv sync --extra docling`).
```
Dependencies are declared in `pyproject.toml` and locked in `uv.lock`; the
+4 -1
View File
@@ -136,7 +136,10 @@ RUN if python -c "import docling" 2>/dev/null; then \
COPY --chown=appuser:appuser . /app/application
RUN mkdir -p /app/application/inputs/local
# Runtime data directories, owned by the process user so a named volume
# mounted on them (docker-compose-standalone.yaml) inherits that ownership
# and uploads work without running the container as root.
RUN mkdir -p /app/application/inputs/local /app/inputs /app/indexes /app/vectors
ENV FLASK_APP=app.py
+4
View File
@@ -8,6 +8,10 @@
# through application/parser/file/ocr_parser.py.
# On Linux torch comes from the CPU-only PyTorch index (no CUDA stack); a GPU
# deployment can reinstall torch from PyPI on top.
# pip resolves the extra index as expected. uv only takes a package from the
# first index that lists it, and the PyTorch index carries stale copies of
# common packages, so with uv either run 'uv sync --extra docling' (the lock
# pins the index per package) or set UV_INDEX_STRATEGY=unsafe-best-match.
# Docker: --build-arg EXTRAS=docling
--extra-index-url https://download.pytorch.org/whl/cpu
@@ -32,6 +32,10 @@ services:
backend:
image: arc53/docsgpt:${DOCSGPT_IMAGE_TAG:-latest}${DOCSGPT_IMAGE_VARIANT:-}
# Same as docker-compose-hub.yaml: the data volumes are written by root so
# any image tag works, including releases that predate the appuser-owned
# /app/inputs, /app/indexes and /app/vectors directories.
user: root
env_file:
- path: .env
required: false
@@ -55,6 +59,7 @@ services:
worker:
image: arc53/docsgpt:${DOCSGPT_IMAGE_TAG:-latest}${DOCSGPT_IMAGE_VARIANT:-}
user: root
# Consumes the default queue plus `parsing` (read_document) and `embeddings`
# (query embedding); without the latter every search times out.
command: celery -A application.app.celery worker -l INFO -B -Q docsgpt,parsing,embeddings
@@ -108,6 +108,10 @@ To run the DocsGPT backend locally, you'll need to set up a Python environment a
# or with uv: uv sync --extra docling --extra milvus
```
The docling file adds the PyTorch CPU index; pip handles that as-is, while
`uv pip install -r` needs `UV_INDEX_STRATEGY=unsafe-best-match` (or use
`uv sync --extra docling`, which reads the lock).
A feature whose extra is missing fails with the exact command to run.
After changing `pyproject.toml`, run `uv lock` and
`bash scripts/export_requirements.sh` so the exported files stay in sync
+4
View File
@@ -54,6 +54,10 @@ OCR_ENABLED=true with the tesseract binary (or a DeepSeek-OCR endpoint) runs
through application/parser/file/ocr_parser.py.
On Linux torch comes from the CPU-only PyTorch index (no CUDA stack); a GPU
deployment can reinstall torch from PyPI on top.
pip resolves the extra index as expected. uv only takes a package from the
first index that lists it, and the PyTorch index carries stale copies of
common packages, so with uv either run 'uv sync --extra docling' (the lock
pins the index per package) or set UV_INDEX_STRATEGY=unsafe-best-match.
Docker: --build-arg EXTRAS=docling" \
--extra docling