Nextcloud Volltext-Index mit Docker und Elasticsearch

Nachdem meine Nextcloud (siehe Installationsanleitung hier) seit einiger Zeit gut läuft, landen mehr Dateien darauf und der Wunsch nach einem schnellen Nextcloud Volltext-Index wächst. Ich bildete mir zwar ein, das schonmal am Laufen gehabt zu haben, aber das tat es nicht (mehr). Daher hier, was ich dazu nun getan habe.

Full text search scheint die neuere Implementierung für Nextcloud Volltextsuche zu sein und mit der Zeit “Nextant” abzulösen. Daher habe ich mich dafür entschieden.

Die sehr gute Anleitung zur Installation ohne docker war mir dabei u.a. recht hilfreich.

1. Plugins installieren

  • “Full text search (BETA)” – Basis
  • “Full text search – Elasticsearch Platform (BETA) 0.8.0” – Elasticsearch als interne Suchplattform.
  • “Full text search – Bookmarks (BETA) 0.8.0” – Bookmarks als Datenquelle (nur bei Bedarf)
  • “Full text search – Files (BETA) 0.8.2” – Files als Datenqulle
  • “Full text search – Files – Tesseract OCR (BETA) 0.1.0” – OCR-Erweiterung für die File-Datenquelle (nur bei Bedarf)

2. docker-compose.yml erweitern um elasticsearch:

(vgl. hier.)

...
  elasticsearch:
    image: dsteinkopf/elasticsearch-ingest-attachment
    restart: always
    volumes:
      - /opt/dockervolumes/nextcloud/elasticsearch_data:/usr/share/elasticsearch/data
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    networks:
      - nextcloudnet
...

Ich habe dazu unter dsteinkopf/elasticsearch-ingest-attachment mein eigenes Image von Elasticsearch plus ingest-attachment erstellt. Dies kann natürlich jeder mitbenutzen oder selber eins erstellen. Das Dockerfile sieht bei mir (derzeit) so simpel aus:

FROM docker.elastic.co/elasticsearch/elasticsearch:6.2.4
RUN bin/elasticsearch-plugin install ingest-attachment

3. vm.max_map_count erhöhen

Damit Elasticsearch läuft, muss auf auf dem Docker Host folgende Einstellung vorgenommen werden:
sysctl -w vm.max_map_count=262144

Ich mache das per Ansible auf allen Docker Hosts:

  tasks:
    - name: set vm.max_map_count for elasticsearch etc.
      sysctl:
        name: vm.max_map_count
        value: 262144
        sysctl_file: /etc/sysctl.d/90-dstk-max_map_count.conf

4. Elasticsearch prüfen:

Nachdem das ganze nun mit docker-compose up -d gestartet werden kann, sollte man mal prüfen, ob Elasticsearch auch läuft. Sieht bei mir so aus:

# docker-compose exec nextcloud curl -XGET 'http://elasticsearch:9200/?pretty'

{
  "name" : "btVJNSs",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "qNRv59OJT_qeHqW-FzWRQy",
  "version" : {
    "number" : "6.2.4",
    "build_hash" : "ccec39f",
    "build_date" : "2018-04-14T07:37:28.497551Z",
    "build_snapshot" : false,
    "lucene_version" : "7.2.1",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

5. Einstellungen in der nextcloud-Oberfläche

In den Settings unter “Full text search” ist die wesentliche Einstellung die “Address of the Servlet”: http://elasticsearch:9200. Weiteres ist bei Bedarf hier nachzulesen.

6. PHP-Einstellung memory_limit

Außerdem muss die PHP INI-Einstellung memory_limit noch erhöht werden. Hierzu mein Hack:

Datei /opt/dockervolumes/nextcloud/memory-limit.ini anlegen mit: memory_limit=-1. (-1 entspricht unendlich. Ich halte das hier für ok, weil der Speicherverbrauch durch docker ohnehin nochmal unabhängig davon beschränkt wird bzw. werden kann.)

Im docker-compose.yml dann bei nextcloud unter volumes eintragen:

- /opt/dockervolumes/nextcloud/memory-limit.ini:/usr/local/etc/php/conf.d/memory-limit.ini:ro

Hier ein paar “Experimentierhilfen”:

docker-compose exec nextcloud php --ini
docker-compose exec nextcloud cat /usr/local/etc/php/conf.d/memory-limit.ini

P.S. Schöner wäre es eigentlich (wie hier) beschrieben, die ini-Datei per COPY in ein Docker-Image zu packen. Ich wollte aber nicht noch ein neues Docker-Image, daher dieser “Hack”.

7. Index erstellen

Nun kann endlich der Nextcloud Volltext-Index in “voller Pracht” erstellt werden:

docker exec --user www-data nextcloud_nextcloud_1 php occ fulltextsearch:index

Beim Experimentieren ggf. vorher nochmal ganz löschen:

docker exec --user www-data nextcloud_nextcloud_1 php occ fulltextsearch:reset

8. Index aktuell halten

Live-Index scheint erst ab Nexcloud 14 zu funktionieren, denn:

docker exec --user www-data nextcloud_nextcloud_1 php occ fulltextsearch:live
...
  [Exception]                                              
  This feature is only available on Nextcloud 14 or newer  
...

Daher aktualisiere ich das nächtlich via crontab-Eintrag:

15 5 * * *      docker exec --user www-data nextcloud_nextcloud_1 php occ fulltextsearch:index

-> Ist das wirklich nötig? Oder passiert das “von selber”?

PS. Fuzzy-Suche

Leider ist die Suche derzeit zwar Volltext, aber sie sucht immer exakt. Man kann sie zwar etwas steuern:

  • + vor einem Suchwort erhöht dessen “Wichtigkeit”,
  • - erniedrigt sie.
  • Anführungszeichen (") gruppieren Worte.

Aber die Suche ist immer exakt. Genaugenommen wird im Content nur nach Prefixen gesucht und nur in den Dateinamen auch innerhalb der Strings.

Daher habe ich mich mal an einem kleinen Patch versucht, der für mich schon genug Fuzziness bringt, aber so sicher noch nicht in der Code integrierbar ist: make search fuzzy

PPS. OCR mit Tesseract

…kommt noch 🙂

Anhang: Links

10 thoughts on “Nextcloud Volltext-Index mit Docker und Elasticsearch

  1. Hallo Dirk,

    erst einmal vielen herzlichen Dank für dein Tutorial. Ich bastel an dem Thema auch schon eine weile herum und konnte meine Probleme jetzt endlich durch dein HowTo lösen!

    Eine Kleinigkeit ist mir aber noch aufgefallen:
    In Punkt 8 (“Index aktuell halten”) muss der Befehl “docker exec –user www-data nextcloud_nextcloud_1 php occ fulltextsearch:live” und nicht “:reset” heißen. 😉

    Viele Grüße, Andy

  2. Hallo Dirk,
    Vielen Dank für die Tolle Anleitung. Woran scheitert OCR mit Tesseract gerade? Soll tesseract in einem extra container laufen?`

    Ich hatte die Fulltextsearch mal auf einem test System laufen und war von der Darstellung der Ergebnisse als einfache Liste enttäuscht. Aus meiner Sicht war nicht ersichtlich nach welchem System die Auflistung der Ergebnisse erfolgt. Auch eine Vorschau wäre sicherlich nützlich gewesen.

    1. OCR mit Tesseract “scheitert” nicht – ich muss nur mal damit anfangen. Vielleicht, wenn der Bedarf bei mir größer wird… (Wie) hast du es am Laufen?

  3. Hi.

    Fulltextsearch ist nun kompatibel mit es 7. Hab das dockerfile geändert auf es 7.1.0. Hab Via docker-compose up und docker-compose up -d neu gestartet, läuft aber immer noch auf 6.5.3. Was mache ich falsch?

  4. Moin Dirk,

    ich bin auf Dein Tutorial gestoßen, nachdem ich schweren Herzens OMV auf Version 5 geupdatet habe. In der Folge habe ich dann auch Nextcloud als Docker Image installiert.

    Nunmehr würde ich gerne die aktuelle Version von Elasticsearch mit Tesseract installieren, da ich diese Funktionen zum Verwalten einer großen Sammlung von Textdateien (mehr als 300.000 (Doc, Docx, PDF, etc.)) benötige.

    Es wäre super, wenn Du Dein Tutorial aktualisieren und erweitern könntest.

    Viele Grüße

    Christian

    1. Oh ja, das stimmt. Ich sollte sowohl meine Installation als auch das Tutorial mal diesbezüglich durchgehen und aktualisieren. Bin mir aber nicht sicher, wann ich da wohl mal Zeit finde… Falls Du konkrete Hinweise hast, lass es mich gerne wissen 🙂

  5. Moin Dirk,

    vielen Dank für Dein schnelles Feedback. Alsoooo, wenn Du mal die Zeit finden würdest, wäre ich über ein Docker Image dankbar welche Folgendes enthalten würde:

    Elasticsearch Vers. 7.6.2
    Tesseract Ver. >= Vers. 4, Sprache Deu, Eng, Fra
    aktuelles elasticsearch-plugin install ingest-attachment

    Mir ist schon bewusst, dass dieses einen erheblichen Zeitaufwand bedeuten würde. Habe mich auch nur getraut zu antworten, weil Du mich ja aufgefordert hast……

    Viele Grüße

    Christian

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert