Unraid already runs the kind of services NextSearch leans on — a lot of setups have Postgres and Redis up for other apps, and the extraction services (Meilisearch, Tika, Gotenberg) are the same ones Paperless-ngx uses, so they are well-trodden on Unraid. The point of this guide is to reuse what you already run and keep NextSearch's own footprint to two containers.
That is possible because the app image ships an all-in-one role: one container runs FrankenPHP, the queue worker and the scheduler together under a supervisor. So the NextSearch side is:
app— the all-in-one backend (serve+worker+scheduler)web— the Nuxt UI, the only container with a published port
The backing services — Postgres, Redis, Meilisearch, Tika and Gotenberg — you point at over the network: reuse an existing one where you have it, add the rest from Community Applications. Object storage is the exception worth calling out: the stack below runs a small MinIO alongside NextSearch that writes to Unraid storage, so previews and extracted text stay on your array and you don't need an external S3 at all. MinIO is the one extra sidecar; the NextSearch application itself is the two containers above.
Yes — all of them, on linux/amd64 (Unraid's architecture):
| Service | Image | On Unraid |
|---|---|---|
| Postgres | postgres:18-alpine |
Community Applications template; often already running |
| Redis | redis:8-alpine |
Community Applications template; often already running |
| Meilisearch | getmeili/meilisearch |
Community Applications template |
| Tika | apache/tika:3.3.1.0-full |
used by the official Unraid Paperless-ngx guide |
| Gotenberg | gotenberg/gotenberg:8 |
used by the official Unraid Paperless-ngx guide |
| S3 | minio/minio |
Community Applications template — or point at external S3 |
The apache/tika -full tag carries Tesseract and its language packs, so OCR
needs no separate container. Gotenberg is only used for previews of Office
files; if you turn those off (PREVIEW_OFFICE_ENABLED=false) you don't need it
at all.
The cleanest path is the Compose Manager plugin (Apps → search "Compose Manager"). It runs a compose stack straight on Unraid, which keeps the env wiring in one place instead of spread across a dozen container templates.
Create a new stack and paste the compose below. It runs only the two NextSearch containers; every backing service is external and reached through the environment. Fill in the hosts of the services you already run, and add the ones you don't (see the two sections after it).
name: nextsearch
services:
app:
image: mirkohaaser/nextsearch-app:0.2.4
# All-in-one: FrankenPHP + queue worker + scheduler in one 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
# Reuse your existing Unraid Postgres and Redis.
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
# Search, extraction and object storage (see below).
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
# Object storage: the bundled MinIO below, backed by 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
# S3-compatible object storage for previews and extracted text, writing to
# Unraid storage. NextSearch creates the bucket itself on first boot, so no
# setup is needed. Point the volume at any pool or share you like — appdata
# is fine, a dedicated share is tidier for a large archive.
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-stoppedA few notes on the values:
-
APP_KEYencrypts the stored Nextcloud credentials and must be a real key. Generate one on any machine with Docker:docker run --rm mirkohaaser/nextsearch-app:0.2.4 php artisan key:generate --showPaste the whole
base64:…string. Keep it stable — change it later and the saved Nextcloud passwords can no longer be decrypted. -
MEILI_MASTER_KEYmust be the same value you set on the Meilisearch container. -
Replace
192.168.1.10with the host each service actually runs on. If a backing service is a container on the same Unraid Docker network, its container name works instead of an IP. -
Only
webpublishes a port. Put NextSearch behind your reverse proxy (Nginx Proxy Manager, SWAG, Traefik) pointing at thewebcontainer on3000, and setAPP_URLto the external URL you use.
Pin the image tag to a released version (here 0.2.4) rather than latest, so
an Unraid "force update" can't move you to an unexpected build.
These three are NextSearch-specific for most people. Two ways to run them:
As their own Unraid containers (Apps → Community Applications):
- Meilisearch — install the template, set
MEILI_MASTER_KEY, and useMEILI_ENV=production. PointMEILISEARCH_HOSTathttp://<host>:7700. - Tika — add a container from
apache/tika:3.3.1.0-full, port9998. PointTIKA_URLathttp://<host>:9998. - Gotenberg — add a container from
gotenberg/gotenberg:8, port3000. PointGOTENBERG_URLathttp://<host>:3000. Skip it if Office previews are off.
If you already run Paperless-ngx, its Tika and Gotenberg containers work for NextSearch too — just point the two URLs at them.
Or bundle them into the same stack, if you'd rather not manage them
separately. Add these services to the compose above and point the app's URLs at
their service names (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-stoppedBundling them still keeps Postgres and Redis external — those are the ones most worth reusing.
NextSearch stores preview images and extracted text in S3-compatible storage. The stack above bundles MinIO for that, writing to Unraid storage — the default, and nothing to set up: NextSearch creates the bucket itself on first boot, so it just works.
- Where it lands. The MinIO volume is
…/appdata/nextsearch/minio:/data. For a large archive, point it at a dedicated share instead of appdata — the blobs grow with the index, and appdata usually lives on the cache pool. Only the path changes; nothing else moves. - Reuse an existing MinIO instead of the bundled one: drop the
minioservice and itsdepends_on, and pointAWS_ENDPOINTat your instance with its own key/secret and bucket. - External S3 (AWS, Backblaze B2, Wasabi): drop the
minioservice, set theAWS_*values, removeAWS_ENDPOINT, and setAWS_USE_PATH_STYLE_ENDPOINT=false. UseAWS_ROOTto keep NextSearch under a prefix inside a shared bucket. With a real provider the bucket must already exist — a restricted key often can't create one.
The MinIO root user/password and the app's AWS_ACCESS_KEY_ID /
AWS_SECRET_ACCESS_KEY are the same credentials; change them together.
- Start the stack. On first boot
appruns the migrations, creates the admin fromADMIN_EMAIL/ADMIN_PASSWORD, and sets up the Meilisearch index — watch the container log forstarting all-in-one. - Open
http://YOUR_UNRAID_IP:3000(or the reverse-proxy URL) and sign in. - Add a Nextcloud instance, run the connection test, pick a folder, and index. Progress shows on Admin → Status.
Bump the image tags in the stack to the new version and redeploy the stack
(Compose Manager → Update). The app container re-runs migrations on start.
Nothing in Postgres or your object storage is touched by an image swap; the
search index rebuilds itself if you ever clear it.
You can also add each container by hand (Docker tab → Add Container) using the
Community Applications templates for the backing services and two custom
containers for mirkohaaser/nextsearch-app (post arguments
app-entrypoint all) and mirkohaaser/nextsearch-web. The environment is
identical to the compose above. Compose Manager is less fiddly because the
wiring lives in one file — prefer it unless you have a reason not to.
The all role is meant for a single node. It migrates and bootstraps on start,
so run exactly one app container against a given database. For a
multi-node or scaled-out setup, use the standard split containers instead
(serve / worker / scheduler) as in the main docker-compose.yml — see
docs/hosting.md. For a home Unraid box, all-in-one is the simpler
choice.