NextSearch braucht auf Unraid zwei eigene Container. Der Rest steht bei den meisten schon.
Im ersten Teil ging es darum, was NextSearch macht: den Inhalt bestehender Nextcloud-Ordner durchsuchbar, strikt lesend, ohne Cluster daneben. Hier geht es um die andere Hälfte — wie das Ding auf einem Unraid-Server landet, ohne dass daraus ein Nachmittag wird.
Unraid ist dafür ein dankbarer Untergrund. Postgres und Redis laufen auf vielen Boxen längst für andere Anwendungen mit. Meilisearch, Tika und Gotenberg sind dieselben Dienste, die Paperless-ngx nutzt — auf Unraid also gut ausgetreten. Der Plan ist entsprechend: benutzen, was da ist, und den eigenen Fußabdruck klein halten.
Die vollständige Anleitung im Repository
docs/unraid.md enthält den kompletten Stack zum Kopieren, samt der Varianten für externes S3 und für den Weg ohne Compose Manager.
Warum es bei zwei Containern bleibt
Das App-Image bringt eine All-in-one-Rolle mit: FrankenPHP, Queue-Worker und Scheduler laufen unter einem Supervisor im selben Container. Damit besteht NextSearch selbst nur noch aus:
app— das Backend mitserve,workerundschedulerin einemweb— die Nuxt-Oberfläche, der einzige Container mit veröffentlichtem Port
Alles Weitere sind Dienste, auf die man über das Netz zeigt. Die gibt es auf Unraid durchgängig für linux/amd64:
| Dienst | Image | Auf Unraid |
|---|---|---|
| Postgres | postgres:18-alpine | Community-Applications-Template, oft schon in Betrieb |
| Redis | redis:8-alpine | Community-Applications-Template, oft schon in Betrieb |
| Meilisearch | getmeili/meilisearch | Community-Applications-Template |
| Tika | apache/tika:3.3.1.0-full | aus der offiziellen Unraid-Anleitung zu Paperless-ngx bekannt |
| Gotenberg | gotenberg/gotenberg:8 | dito |
| S3 | minio/minio | Community-Applications-Template — oder externes S3 |
Das -full-Tag von Tika bringt Tesseract samt Sprachpaketen mit, OCR braucht also keinen eigenen Container. Gotenberg wird ausschließlich für Vorschaubilder von Office-Dateien verwendet; wer die per PREVIEW_OFFICE_ENABLED=false abschaltet, braucht es gar nicht.
Eine Ausnahme von der Wiederverwenden-Regel ist der Objektspeicher. Der Stack unten fährt ein kleines MinIO mit, das auf Unraid-Storage schreibt — Vorschaubilder und extrahierter Text bleiben damit auf dem Array, und externes S3 wird nirgends gebraucht.
Der Stack
Am wenigsten fummelig ist das Compose-Manager-Plugin (Apps → nach „Compose Manager" suchen). Es fährt einen Compose-Stack direkt auf Unraid, und die ganze Verdrahtung steht in einer Datei statt verteilt über ein Dutzend Container-Templates.
Neuen Stack anlegen, das Folgende hineinkopieren, Hosts eintragen:
name: nextsearch
services:
app:
image: mirkohaaser/nextsearch-app:0.2.4
# All-in-one: FrankenPHP + Queue-Worker + Scheduler in einem Container.
command: ["app-entrypoint", "all"]
environment:
APP_KEY: base64:PASTE_A_GENERATED_KEY_HERE
APP_URL: http://YOUR_UNRAID_IP:3000
ADMIN_EMAIL: admin@example.com
ADMIN_PASSWORD: change-me-please
# Vorhandene Unraid-Postgres und -Redis mitbenutzen.
DB_HOST: 192.168.1.10
DB_PORT: "5432"
DB_DATABASE: nextsearch
DB_USERNAME: nextsearch
DB_PASSWORD: your-postgres-password
REDIS_HOST: 192.168.1.10
REDIS_PORT: "6379"
REDIS_PASSWORD: your-redis-password-or-remove-this-line
# Suche und Extraktion.
MEILISEARCH_HOST: http://192.168.1.10:7700
MEILI_MASTER_KEY: your-meili-master-key
TIKA_URL: http://192.168.1.10:9998
GOTENBERG_URL: http://192.168.1.10:3000
# Objektspeicher: das mitgelieferte MinIO auf Unraid-Storage.
FILESYSTEM_DISK: s3
AWS_ENDPOINT: http://minio:9000
AWS_ACCESS_KEY_ID: nextsearch
AWS_SECRET_ACCESS_KEY: nextsearch-secret
AWS_BUCKET: nextsearch
AWS_USE_PATH_STYLE_ENDPOINT: "true"
volumes:
- /mnt/user/appdata/nextsearch/storage:/app/storage
depends_on:
minio:
condition: service_healthy
restart: unless-stopped
minio:
image: minio/minio:RELEASE.2025-09-07T16-13-09Z
command: ["server", "/data", "--console-address", ":9001"]
environment:
MINIO_ROOT_USER: nextsearch
MINIO_ROOT_PASSWORD: nextsearch-secret
volumes:
- /mnt/user/appdata/nextsearch/minio:/data
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 10s
timeout: 5s
retries: 20
restart: unless-stopped
web:
image: mirkohaaser/nextsearch-web:0.2.4
environment:
NUXT_BACKEND_URL: http://app:8080
NITRO_PORT: "3000"
NITRO_HOST: 0.0.0.0
ports:
- "3000:3000"
depends_on:
- app
restart: unless-stopped
Vier Werte lohnen einen zweiten Blick:
APP_KEY verschlüsselt die hinterlegten Nextcloud-Zugangsdaten und muss ein echter Schlüssel sein. Auf einer beliebigen Maschine mit Docker erzeugen:
docker run --rm mirkohaaser/nextsearch-app:0.2.4 php artisan key:generate --show
Die komplette base64:…-Zeichenkette einsetzen — und stehen lassen. Wird sie später getauscht, lassen sich die gespeicherten Nextcloud-Passwörter nicht mehr entschlüsseln.
MEILI_MASTER_KEY muss derselbe Wert sein, der am Meilisearch-Container gesetzt ist.
Die Hosts. 192.168.1.10 durch die Adresse ersetzen, unter der der jeweilige Dienst tatsächlich läuft. Liegt ein Dienst als Container im selben Unraid-Docker-Netz, tut es auch sein Containername.
Das Image-Tag auf eine veröffentlichte Version festnageln — hier 0.2.4 statt latest. Sonst schiebt ein „force update" in Unraid den Stack auf einen Build, den niemand bestellt hat.
Nur web veröffentlicht einen Port. Hinter einem Reverse-Proxy (Nginx Proxy Manager, SWAG, Traefik) zeigt man auf den web-Container auf 3000 und setzt APP_URL auf die externe Adresse.
Suche, Extraktion, Objektspeicher
Meilisearch, Tika und Gotenberg sind die drei Dienste, die für die meisten neu dazukommen. Zwei Wege stehen offen.
Als eigene Unraid-Container über die Community Applications: Meilisearch mit gesetztem MEILI_MASTER_KEY und MEILI_ENV=production auf Port 7700, Tika aus apache/tika:3.3.1.0-full auf 9998, Gotenberg aus gotenberg/gotenberg:8 auf 3000. Dann zeigen MEILISEARCH_HOST, TIKA_URL und GOTENBERG_URL jeweils dorthin. Wer Paperless-ngx betreibt, kann dessen Tika und Gotenberg direkt mitbenutzen — zwei URLs, fertig.
Ein Stolperstein am Rande: Gotenberg lauscht selbst auf 3000, und dieser Host-Port ist durch den web-Container schon belegt. Beim eigenen Gotenberg-Container also einen anderen Host-Port wählen.
Oder mit in denselben Stack, wenn man sie nicht getrennt pflegen will. Dann kommen die drei Dienste unten dazu und die URLs oben zeigen auf die Servicenamen (http://meilisearch:7700, http://tika:9998, http://gotenberg:3000):
meilisearch:
image: getmeili/meilisearch:v1.50.0
environment:
MEILI_MASTER_KEY: your-meili-master-key
MEILI_ENV: production
MEILI_NO_ANALYTICS: "true"
volumes:
- /mnt/user/appdata/nextsearch/meili:/meili_data
restart: unless-stopped
tika:
image: apache/tika:3.3.1.0-full
restart: unless-stopped
gotenberg:
image: gotenberg/gotenberg:8.34
command:
- gotenberg
- --api-timeout=120s
- --chromium-disable-javascript=true
- --chromium-allow-list=file:///tmp/.*
restart: unless-stopped
Postgres und Redis bleiben auch dann außerhalb — das sind die beiden, bei denen sich Wiederverwenden am ehesten lohnt.
Beim Objektspeicher ist nichts einzurichten: NextSearch legt den Bucket beim ersten Start selbst an. Das MinIO-Volume steht auf …/appdata/nextsearch/minio. Bei einem großen Archiv gehört es auf eine eigene Freigabe statt in appdata — die Blobs wachsen mit dem Index, und appdata liegt üblicherweise auf dem Cache-Pool. Es ändert sich nur der Pfad.
Wer schon ein MinIO betreibt, wirft den minio-Dienst samt depends_on heraus und zeigt mit AWS_ENDPOINT auf die vorhandene Instanz. Für echtes S3 (AWS, Backblaze B2, Wasabi) fällt zusätzlich AWS_ENDPOINT weg und AWS_USE_PATH_STYLE_ENDPOINT auf false; der Bucket muss dort vorher existieren, weil ein eingeschränkter Schlüssel meist keinen anlegen darf.
Erster Start, spätere Updates
Beim ersten Hochfahren erledigt app die Migrationen, legt den Administrator aus ADMIN_EMAIL und ADMIN_PASSWORD an und richtet den Meilisearch-Index ein. Im Container-Log steht dann starting all-in-one. Danach http://YOUR_UNRAID_IP:3000 öffnen, anmelden, eine Nextcloud-Instanz hinterlegen, Verbindungstest laufen lassen, einen Ordner auswählen. Der Fortschritt steht unter Admin → Status.
Für ein Update genügt es, die Image-Tags im Stack hochzuziehen und neu zu deployen (Compose Manager → Update). Der app-Container fährt die Migrationen beim Start erneut. Postgres und Objektspeicher rührt ein Image-Tausch nicht an, und der Suchindex baut sich ohnehin selbst wieder auf, falls man ihn einmal leert.
Ein Hinweis zur All-in-one-Rolle: Sie ist für einen einzelnen Knoten gedacht und bootstrappt beim Start. Gegen eine Datenbank darf deshalb genau ein app-Container laufen. Wer verteilt fahren will, nimmt die getrennten Rollen serve, worker und scheduler aus der regulären docker-compose.yml. Für eine Unraid-Kiste zu Hause ist All-in-one der kürzere Weg.
Fazit
Der Aufwand liegt bei diesem Setup nicht im Aufsetzen von NextSearch, sondern im Eintragen der Hosts, die schon laufen. Zwei Container, ein Compose-Stack, ein Schlüssel, der stehen bleiben muss — danach indexiert der Scheduler von allein.
Call to Action
Der Stack zum Kopieren steht in docs/unraid.md, NextSearch selbst unter https://github.com/McGo/NextSearch.
Wer das für ein Team oder eine ganze Organisation aufsetzen will — mit eigenem S3, hinter einem Reverse-Proxy, angebunden an mehrere Instanzen — kann sich gerne melden.
