This repository has been archived on 2026-10-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
2026-09-26 13:05:15 +02:00
2026-09-28 02:59:52 +02:00
2026-09-28 02:59:52 +02:00
2026-09-26 13:05:15 +02:00
2026-09-26 13:05:15 +02:00
2026-09-18 18:02:33 +02:00
2026-09-26 13:05:15 +02:00
2026-09-26 13:05:15 +02:00
2026-09-28 02:38:19 +02:00
2026-09-18 18:02:33 +02:00
2026-09-18 18:02:33 +02:00

recoll-modern

A modern, self-hosted web UI and MCP server on top of Recoll full-text search, with support for multiple independent collections.

Status: spec 001's authenticated search API and Docker deployment have completed acceptance and review checks. The web UI and MCP server are later specs.

Published Docker image

The image is gitea.lucaswinther.info/lucasw89/recoll-modern for linux/amd64. It currently contains the authenticated search API and Recoll; the web UI and MCP server are later specs. :main follows the main branch. A release tag such as :v1.2.3 pins a specific release; :latest follows the newest version tag. Use a version tag when you want a predictable update. The image records its source, revision and version in OCI labels (docker image inspect IMAGE).

Run the pulled image with Compose

Save compose.published.yaml alongside this guide, or download it from the repository after the publishing branch reaches main:

curl -fL -o compose.published.yaml \
  https://gitea.lucaswinther.info/lucasw89/recoll-modern/raw/branch/main/compose.published.yaml

If the package is private, log in to the Gitea registry first. Use your Gitea username and a personal access token with package Read permission as the Docker password:

docker login gitea.lucaswinther.info

Set an absolute host directory for documents and seed the first administrator. :main is available after a successful main-branch publish, even before the first version tag:

export RECOLL_MODERN_DOCUMENTS=/srv/documents
export RECOLL_MODERN_ADMIN_USERNAME=admin
export RECOLL_MODERN_ADMIN_PASSWORD='use-a-long-unique-password'
export RECOLL_MODERN_IMAGE=gitea.lucaswinther.info/lucasw89/recoll-modern:main
docker compose -f compose.published.yaml pull
docker compose -f compose.published.yaml up -d --no-build
docker compose -f compose.published.yaml ps
docker compose -f compose.published.yaml logs -f app

Once a version appears in Gitea Packages, set RECOLL_MODERN_IMAGE to its tag, such as gitea.lucaswinther.info/lucasw89/recoll-modern:v1.2.3, to pin that release. Omit RECOLL_MODERN_IMAGE to use :latest after the first version tag is published. The image is published only after the CI checks pass; a tag that has not been published cannot be pulled. To update, set the desired tag and run docker compose -f compose.published.yaml pull followed by docker compose -f compose.published.yaml up -d --no-build again. Keep the same Compose project directory so its named volumes are reused.

For a trusted local HTTP trial with docker run, use the same document and administrator variables:

export RECOLL_MODERN_IMAGE=${RECOLL_MODERN_IMAGE:-gitea.lucaswinther.info/lucasw89/recoll-modern:main}
docker pull "$RECOLL_MODERN_IMAGE"
docker run -d --name recoll-modern --restart unless-stopped -p 127.0.0.1:8000:8000 \
  -e RECOLL_MODERN_ADMIN_USERNAME -e RECOLL_MODERN_ADMIN_PASSWORD \
  -e RECOLL_MODERN_HOST=0.0.0.0 -e RECOLL_MODERN_PORT=8000 \
  -e RECOLL_MODERN_DEVELOPMENT_MODE=true \
  --mount "type=bind,src=$RECOLL_MODERN_DOCUMENTS,dst=/documents,readonly" \
  --mount type=volume,src=recoll-modern-service-state,dst=/var/lib/recoll-modern \
  --mount type=volume,src=recoll-modern-index,dst=/var/lib/recoll \
  "$RECOLL_MODERN_IMAGE"

Build locally

The original compose.yaml still builds from this repository:

export RECOLL_MODERN_DOCUMENTS=/srv/documents
export RECOLL_MODERN_ADMIN_USERNAME=admin
export RECOLL_MODERN_ADMIN_PASSWORD='use-a-long-unique-password'
docker compose up -d --build

The service listens on host port 8000 by default; set RECOLL_MODERN_PUBLISH_PORT to change it. The document directory is mounted read-only. SQLite, the membership map and generated Recoll configuration live in the service-state volume; the index lives in the separate recoll-index volume. Back up both volumes together and keep a separate copy of the documents. docker compose down preserves the volumes; never pass -v unless you intentionally want to delete the index and service state.

For the direct docker run example, the volumes are named recoll-modern-service-state and recoll-modern-index. Back up both together. Replacing a container does not delete these volumes.

On first boot, the API is available but /health may return 503 until a membership or reindex job has built the first Recoll index. Log in through POST /auth/login, create a collection, then add file or directory sources through POST /collections/{id}/memberships. Mutations return a durable job ID; inspect GET /jobs/{id} for completion or file errors. POST /jobs/reindex refreshes the index without deleting it. The login seed applies only when no administrator exists; changing the environment value later does not rotate an existing password. Protect and back up the service-state volume.

Production sessions use Secure cookies, so serve the API over HTTPS. For a trusted local HTTP trial, set RECOLL_MODERN_DEVELOPMENT_MODE=true; do not use that setting on a public endpoint. Set RECOLL_MODERN_ROOT_PATH=/recoll when hosting under a path prefix, and make the reverse proxy preserve that path. RECOLL_MODERN_TRUSTED_PROXIES accepts comma-separated IP networks; only forwarded host, scheme and prefix headers from those networks are honored. The health URL follows the prefix, for example /recoll/health.

To run the generated-corpus container checks, start Compose with a test document containing the unique word zebraplatypus, set RECOLL_MODERN_TEST_CORPUS_FILE to its path relative to the document root, and run RECOLL_MODERN_REQUIRE_DOCKER=1 uv run pytest tests/integration. Ordinary host test runs skip these checks when Compose is not running. Recoll commands run only inside the container.

Publishing from Gitea

Enable repository Actions and use a runner with the ubuntu-latest label, Python 3, uv setup support, and a working Docker CLI/daemon. In the repository's Actions secrets, set REGISTRY_USERNAME to the Gitea account that owns the publishing token and REGISTRY_TOKEN to a personal access token with package Read & Write permission. Gitea currently requires a PAT for Actions package publishing; the built-in job token does not publish OCI packages. The workflow checks pull requests without registry credentials and publishes only after checks pass on main or a full vX.Y.Z tag. No server deployment is performed by CI.

Working here (human or agent): read AGENTS.md. It is the single source of truth for commands, workflow, and boundaries. Deeper context lives in docs/.

S
Description
No description provided
Readme
673 KiB
Languages
Python 97.9%
C 1%
Dockerfile 0.6%
Shell 0.4%