cancel
Showing results for 
Search instead for 
Did you mean: 
angelborroy
Community Manager Community Manager
Community Manager

A community fork of Alfresco Search Services, maintained by Jeci — the team behind Pristy.

Status: beta. This is an independent community fork, not affiliated with Hyland and not supported on Alfresco Enterprise. Don't put it in production yet. Do try it, break it, and tell us what's missing.

Why this fork exists

If you run Alfresco Community Edition, your search tier is probably still riding on an Alfresco-patched Apache Solr 6, a release line whose upstream Lucene 6 reached end of life years ago. The patched build ties you to an old Java, an old logging stack (Log4j 1.x), and a Solr you can't simply swap for a current Apache release.

 

  Before (upstream Community) Jeci Fork
Solr / Lucene 6.6.5 patched / Lucene 6 9.10.1 vanilla Apache / Lucene 9.12.3
Java 11 17
Logging Log4j 1.x / reload4j Log4j 2
Indexing trackers inside the Solr webapp standalone Spring Boot service
Enterprise modules Insight Engine, Zeppelin bundled removed (Community-focused)

The headline is "Solr 9," but the structural change matters just as much: the indexing trackers now run as their own service. Solr only serves queries and stores the index; a separate alfresco-indexing-trackers process reads from the repository and feeds Solr. You can restart, scale, monitor, and re-tune indexing without touching query serving and re-tune a running stack with environment variables, no image rebuild.

What stays exactly the same

This is the part that makes adoption low-risk. Your queries don't change.

  • The AFTS query language and the public Search API are unchanged.
  • ACL permission filtering behaves identically, denied documents stay hidden.
  • Faceting, highlighting, ancestor-path (APATH) drill-down all work as before.
  • The default cores are still alfresco and archive.

A query that worked against the upstream Community search engine returns the same results here. What changed is the engine underneath and the deployment shape — not the contract.

Want to just try it? Jump to Try it in one command below: the community alfresco-docker-installer now has a --searchType=jeci option that stands up a full Alfresco 26.1 + Solr 9 stack and indexes your content with no manual setup.

What you give up

  • Insight Engine is gone: the SQL/JDBC connector (/sql), Zeppelin notebooks, and the Enterprise analytics. If you depend on those, this fork is not for you yet.
  • A full re-index is mandatory. Lucene 9 cannot read a Lucene 6 index. You start with empty cores and let the trackers rebuild from the repository. Plan a re-indexing window proportional to your repository size.

The architecture in one diagram

                 +--------------------------+
                 |   Alfresco Repository    |
                 |   (Community Edition)    |
                 +-----------+--------------+
        tracking API (pull)  |            ^  search API
        + shared secret      |            |  (AFTS / CMIS)
                             v            |
        +------------------------+   +----+-------------------+
        | alfresco-indexing-     |   |       Solr 9           |
        | trackers (Spring Boot) |-->|  (query + index store) |
        |  Metadata / Content /  |   |  cores: alfresco,      |
        |  Acl / Commit / Cascade|   |         archive        |
        |  / Model / Repair      |   +------------------------+
        |  :8085 actuator+admin  |
        +------------------------+
  1. MetadataTracker indexes properties, paths, and aspects: a document is findable by name and metadata within a few seconds. If it has content, it's flagged "content outdated."
  2. ContentTracker runs on a slower schedule, pulls the outdated docs, fetches extracted text from the repository (via the transform service), and indexes it: now findable by full text.
  3. CommitTracker commits and reopens the searcher: what actually makes new docs visible.

So full-text search lags metadata search. The dominant lever is the content cron, and every tracker setting is an ALFRESCO_TRACKER_* environment variable you can change live.

Try it in one command

The fastest way to kick the tyres is the community installer, alfresco-docker-installer: the Yeoman generator (yo alfresco-docker-installer) that produces a Docker Compose stack for Alfresco Community. It now has first-class support for this fork: pick the Jeci search engine and it wires up the two-service layout (Solr 9 + standalone trackers) for you.

Interactive

npm install -g yo generator-alfresco-docker-installer
yo alfresco-docker-installer

When prompted "Which search engine would you like to use?", choose:

  Alfresco Search Services (stock, Solr 6)
> Jeci community fork (vanilla Solr 9 / Java 17, standalone trackers)

Pick ACS 26.1 (the version this option targets today). The installer forces shared-secret comms automatically: it's the mode this fork supports end to end.

Then just bring it up

docker compose up --build -d
docker compose logs -f trackers   # watch indexing cycles

The first up --build clones and compiles the fork (Solr 9 distribution + the trackers JAR) inside Docker — that takes a while the first time; subsequent builds are cached. The generated stack runs postgres, alfresco, transform-core-aio, share, content-app, a proxy, and the two search services solr6 (query + index) and trackers (indexing), all pre-wired with a shared secret.

Note on scope. The --searchType=jeci option currently targets ACS 26.1. Extending it to 23.x / 25.x is straightforward and on the backlog — a friendly contribution if you want one.

Deployment guide

Most people should use the one-command installer above. This section is the manual path, useful if you want to understand the moving parts, run a different ACS version, or build the images yourself.

Heads-up on images. The fork's CI currently publishes images to a private registry, so there is no public docker pull yet. So here you build the two images from source. It's three commands.

0. Prerequisites

  • Docker + Docker Compose
  • Java 17 (Temurin) and Maven 3.9+ — or just mise, which pins both for you (mise install)

1. Build the distribution and the two images

git clone https://github.com/jecicorp/AlfrescoSearchServices.git
cd AlfrescoSearchServices

# Build the Solr distribution ZIP + the trackers Spring Boot JAR
mise run install          # or: mvn clean install -DskipTests -pl \
                          #   search-services/alfresco-solrclient-lib,search-services/alfresco-search,search-services/packaging -am
mise run trackers:build   # or: cd search-services && mvn package -pl alfresco-indexing-trackers -am -DskipTests

# Build the Solr image
docker build -t alfresco/alfresco-search-services:local \
  search-services/packaging/target/docker-resources/

# Build the trackers image
docker build -t alfresco/alfresco-indexing-trackers:local \
  -f search-services/packaging/src/docker/Dockerfile.trackers \
  search-services/alfresco-indexing-trackers/target/

2. The Compose file

This is a minimal Alfresco Community 23.x stack using shared-secret auth between the repository and the search tier (the simplest secure-by-default option). It mirrors the project's own working docker-compose.dev.yml, trimmed to the essentials.

# compose.yml
services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_DB: alfresco
      POSTGRES_USER: alfresco
      POSTGRES_PASSWORD: alfresco
    command: postgres -c max_connections=200
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "alfresco"]
      interval: 10s
      retries: 5

  activemq:
    image: alfresco/alfresco-activemq:5.17.1-jre17-rockylinux8
    ports: ["8161:8161", "61616:61616", "5672:5672"]

  transform-core-aio:
    image: alfresco/alfresco-transform-core-aio:5.1.2
    environment:
      JAVA_OPTS: "-XX:MinRAMPercentage=50 -XX:MaxRAMPercentage=80"

  alfresco:
    image: alfresco/alfresco-content-repository-community:23.4.1
    mem_limit: 3g
    healthcheck:
      test: ["CMD", "curl", "--fail",
        "http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/probes/-ready-"]
      interval: 10s
      retries: 10
      start_period: 60s
    environment:
      JAVA_TOOL_OPTIONS: >-
        -Ddb.driver=org.postgresql.Driver
        -Ddb.username=alfresco
        -Ddb.password=alfresco
        -Ddb.url=jdbc:postgresql://postgres:5432/alfresco
        -Dindex.subsystem.name=solr6
        -Dsolr.secureComms=secret
        -Dsolr.sharedSecret=please-change-me
        -Dsolr.host=solr
        -Dsolr.port=8983
        -Dmessaging.broker.url="failover:(nio://activemq:61616)?timeout=3000&jms.useCompression=true"
        -Dtransform.service.enabled=true
        -Dlocal.transform.service.enabled=true
        -DlocalTransform.core-aio.url=http://transform-core-aio:8090/
        -Dcsrf.filter.enabled=false
    depends_on:
      postgres: { condition: service_healthy }

  solr:
    image: alfresco/alfresco-search-services:local   # built in step 1
    mem_limit: 2g
    # solr-init-core.sh creates the alfresco + archive cores from the rerank template on first boot
    entrypoint: ["/opt/alfresco-search-services/solr-init-core.sh"]
    environment:
      SOLR_ALFRESCO_HOST: alfresco
      SOLR_ALFRESCO_PORT: "8080"
      SOLR_SOLR_HOST: solr
      SOLR_SOLR_PORT: "8983"
      SOLR_CREATE_ALFRESCO_DEFAULTS: alfresco,archive
      ALFRESCO_SECURE_COMMS: secret
      JAVA_TOOL_OPTIONS: "-Dalfresco.secureComms.secret=please-change-me"
    ports: ["8983:8983"]
    depends_on:
      alfresco: { condition: service_healthy }
    volumes:
      - solr-data:/opt/alfresco-search-services/data

  trackers:
    image: alfresco/alfresco-indexing-trackers:local  # built in step 1
    mem_limit: 512m
    environment:
      ALFRESCO_TRACKER_SOLR_URL: http://solr:8983/solr
      ALFRESCO_TRACKER_SOLR_COLLECTIONS: alfresco,archive
      ALFRESCO_TRACKER_REPOSITORY_URL: http://alfresco:8080/alfresco
      ALFRESCO_TRACKER_REPOSITORY_SECURECOMMS: secret
      ALFRESCO_TRACKER_REPOSITORY_SHAREDSECRET: please-change-me
      # Optional: make full-text appear faster on a low-volume / demo stack
      # ALFRESCO_TRACKER_CRON_CONTENT: "0/5 * * * * ?"
      # ALFRESCO_TRACKER_NEW_SEARCHER_INTERVAL: "1500"
    ports: ["8085:8085"]
    depends_on:
      alfresco: { condition: service_healthy }

volumes:
  solr-data:
docker compose -f compose.yml up -d
docker compose -f compose.yml logs -f trackers   # watch the indexing cycles

3. Verify it works

  1. Solr answers: curl http://localhost:8983/solr/ (the admin UI requires the secret header).
  2. Trackers are healthy: curl http://localhost:8085/actuator/health : {"status":"UP"}.
  3. Upload a document in Alfresco. Within a few seconds it's findable by name; within 25–30 s (default cadence) it's findable by its content.
  4. Watch progress: the trackers expose a Solr-compatible report at curl "http://localhost:8085/solr/admin/cores?action=SUMMARY&wt=json".

Reaching the Solr admin UI. Solr 9 + shared-secret means every request needs an X-Alfresco-Search-Secret header. Either use a browser extension like ModHeader, or front Solr with a tiny reverse proxy that injects it, the repo ships a Caddyfile that does exactly this on port 8984.

4. Tuning

Every tracker knob is an environment variable on the trackers service.

Variable Default Effect
ALFRESCO_TRACKER_CRON_CONTENT 0/20 * * * * ? Full-text freshness. Lower → text searchable sooner, more transform load.
ALFRESCO_TRACKER_CRON_METADATA 0/5 * * * * ? Metadata freshness.
ALFRESCO_TRACKER_CRON_ACL 0/5 * * * * ? How fast permission changes apply to search.
ALFRESCO_TRACKER_BATCH_COUNT 5000 Nodes per tracking call; higher → faster bulk indexing, more memory.
ALFRESCO_TRACKER_NEW_SEARCHER_INTERVAL 3000 (ms) Delay before new docs become visible.

Full reference: tracker-configuration.md.

How you can help

This is a community project and it grows with the community. Concrete ways to contribute, roughly easiest-first:

  • Run it and report back. Stand up the one-command installer stack against your real custom content models and tell us what indexes correctly and what doesn't. Bug reports with a reproducible model are gold.
  • Extend the installer. The --searchType=jeci option covers ACS 26.1 today, extending it to 23.x / 25.x is a well-scoped, friendly PR.
  • Documentation. The search-services/README.md still carries stale Solr 6 / Insight Engine content, leaning it up is a friendly first PR.
  • Packaging & distribution. Help us publish public images and tagged releases so adoption doesn't even need a first-build compile.
  • Code. Pick something from the backlog: mTLS for the trackerto Solr leg, SolrCloud support, observability dashboards, a Helm chart...

See CONTRIBUTING.md for the branch model and PR conventions, and the issues backlog for ready-to-pick tasks.

Project home: https://github.com/jecicorp/AlfrescoSearchServices
Commercial support on Alfresco Community & this module: Jeci

Further reading

License: LGPL-3.0. Alfresco and the Alfresco logo are trademarks of Hyland; this project is an independent community fork and is not affiliated with or endorsed by Hyland.