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

4 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

Schreibe einen Kommentar

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