Summary
The @lde/search-indexer image runs as the non-root node user (uid 1000), but writes PROVENANCE_FILE without ensuring the target directory is writable by that user. With a root-owned mount (the default for a fresh named volume or a bind-mounted host dir), the provenance file is silently never written, so skip-unchanged never engages and every run reprocesses the full dataset.
Symptom
Configured per the docs with a persisted provenance location:
volumes:
- provenance:/provenance
environment:
PROVENANCE_FILE: /provenance/provenance.json
The run completes successfully (exit 0) and indexes correctly, but a second, identical run does not skip – it re-imports and re-projects everything. Inspecting the volume afterwards:
$ docker run --rm -v search-indexer_provenance:/p alpine ls -la /p
drwxr-xr-x root root . # <- root-owned, mode 755
# (no provenance.json)
The directory is empty: node (uid 1000) cannot create provenance.json in a root:root 755 dir, and the failure is not surfaced.
Expected
Either:
- the pipeline/image ensures the
PROVENANCE_FILE parent directory is writable by the runtime user (e.g. chown/mkdir in the entrypoint, the way DATA_DIR is handled), or
- a failed provenance write is reported as an error rather than swallowed, so a misconfigured mount is caught instead of silently disabling skip-unchanged.
At minimum, document that PROVENANCE_FILE’s directory must be writable by uid 1000.
Impact
Skip-unchanged is a headline feature for cron-driven reindexing (avoid rebuilding QLever + re-projecting an unchanged dump every tick). As shipped it is silently inert on the most natural configuration. Indexing correctness is unaffected – re-runs are idempotent and produce identical counts – but the optimization never kicks in.
Notes
Runtime user confirmed:
$ docker run --rm --entrypoint sh ghcr.io/ldelements/search-indexer:latest -c 'id'
uid=1000(node) gid=1000(node) groups=1000(node)
Related: #652 (the indexer image), #634 (the file-backed ProvenanceStore this consumes).
Summary
The
@lde/search-indexerimage runs as the non-rootnodeuser (uid 1000), but writesPROVENANCE_FILEwithout ensuring the target directory is writable by that user. With a root-owned mount (the default for a fresh named volume or a bind-mounted host dir), the provenance file is silently never written, so skip-unchanged never engages and every run reprocesses the full dataset.Symptom
Configured per the docs with a persisted provenance location:
The run completes successfully (exit 0) and indexes correctly, but a second, identical run does not skip – it re-imports and re-projects everything. Inspecting the volume afterwards:
The directory is empty:
node(uid 1000) cannot createprovenance.jsonin aroot:root 755dir, and the failure is not surfaced.Expected
Either:
PROVENANCE_FILEparent directory is writable by the runtime user (e.g.chown/mkdirin the entrypoint, the wayDATA_DIRis handled), orAt minimum, document that
PROVENANCE_FILE’s directory must be writable by uid 1000.Impact
Skip-unchanged is a headline feature for cron-driven reindexing (avoid rebuilding QLever + re-projecting an unchanged dump every tick). As shipped it is silently inert on the most natural configuration. Indexing correctness is unaffected – re-runs are idempotent and produce identical counts – but the optimization never kicks in.
Notes
Runtime user confirmed:
Related: #652 (the indexer image), #634 (the file-backed ProvenanceStore this consumes).