How to Deploy MiniSearch Using Docker for Development and Production Environments

Deploy MiniSearch by building the multi-stage Dockerfile once, then use docker-compose.yml for development with live code mounting and hot-module replacement, or docker-compose.production.yml for immutable production containers.

The felladrin/minisearch repository provides a self-hosted AI search interface that bundles llama.cpp, SearXNG, and a Node.js front-end into a single deployable unit. Understanding how to deploy MiniSearch using Docker requires familiarity with its multi-stage build process and the environment-specific orchestration files included in the source code.

Understanding MiniSearch's Multi-Stage Docker Architecture

The Dockerfile at the repository root implements a multi-stage build that compiles native binaries and assembles the runtime environment. As implemented in felladrin/minisearch, the build process splits into two distinct stages to optimize layer caching and final image size.

The llama-builder Stage

The first stage uses a base image to compile llama.cpp from source. According to the source code, this stage clones the repository at https://github.com/ggerganov/llama.cpp.git and runs cmake to produce the llama-server binary along with required shared libraries (.so files). These artifacts are copied into the final stage, ensuring the runtime image contains only the compiled binaries without the build toolchain.

The Node.js Runtime Stage

The final stage uses node:lts as its base and performs three critical assembly steps:

  1. Installs Python 3 and sets up a virtual environment for SearXNG at /usr/local/searxng/
  2. Copies the compiled llama-server and libraries from the llama-builder stage
  3. Installs Node dependencies, builds static assets, and configures a HEALTHCHECK instruction

The resulting image exposes port 7860 by default and contains the complete stack needed to run the application.

Development Deployment with docker-compose.yml

For local development, the docker-compose.yml file mounts your source code directory into the container and enables hot-module replacement (HMR) on a separate port.

The development configuration synchronizes your local filesystem with /home/node/app/ inside the container, allowing edits to reflect immediately without rebuilding. It also exposes port 7861 for HMR alongside the main application port 7860.


# docker-compose.yml (development)

services:
  development-server:
    environment:
      - HOST=${HOST:-0.0.0.0}
      - PORT=${PORT:-7860}
      - BASIC_SSL=${BASIC_SSL:-false}
      - HMR_PORT=${HMR_PORT:-7861}
    ports:
      - "${PORT:-7860}:7860"
      - "${HMR_PORT:-7861}:7861"
    build:
      dockerfile: Dockerfile
      context: .
    volumes:
      - .:/home/node/app/
    command: [
      "(cd /usr/local/searxng/searxng-src && /usr/local/searxng/searxng-venv/bin/python -m searx.webapp > /tmp/searxng.log 2>&1) & (npm install && npm run dev)"
    ]

To start the development environment, run:

docker compose up

This command builds the image if necessary, starts SearXNG in the background, and launches the Node.js development server. Access the UI at http://localhost:7860 while the HMR dev server operates on port 7861.

Production Deployment with docker-compose.production.yml

The docker-compose.production.yml file provides an immutable deployment configuration suitable for production workloads. Unlike the development variant, this configuration does not mount local volumes or install dependencies at runtime.

The production image runs the pre-built Node.js server directly using the assets compiled during the Docker build stage. It exposes only the public application port ($PORT) and omits the HMR port entirely.


# docker-compose.production.yml (production)

services:
  production-server:
    environment:
      - HOST=${HOST:-0.0.0.0}
      - PORT=${PORT:-7860}
      - BASIC_SSL=${BASIC_SSL:-false}
    ports:
      - "${PORT:-7860}:7860"
    build:
      dockerfile: Dockerfile
      context: .

Deploy to production with:

docker compose -f docker-compose.production.yml up --build

This ensures the container starts the compiled application immediately without running npm install or development watches.

Environment Configuration and Customization

Both Docker Compose files respect environment variables for flexible deployment across different environments. You can override defaults by creating a .env file or exporting variables before running commands.

Customizing Ports and SSL

To run the development server on custom ports:

HOST=0.0.0.0 PORT=8080 HMR_PORT=8081 docker compose up

Set BASIC_SSL=true to enable basic SSL termination when deploying behind a reverse proxy.

Enabling Access Key Protection

To restrict access in either environment, define ACCESS_KEYS in your environment:

echo 'ACCESS_KEYS="my-secret-key-1,my-secret-key-2"' > .env
docker compose up --build

This injects authentication requirements into the running container as documented in docs/quick-start.md.

Summary

  • Multi-stage builds separate the llama.cpp compilation (in the llama-builder stage) from the Node.js runtime to create efficient production images.
  • Development deployment uses docker-compose.yml with volume mounts at .:/home/node/app/ and exposes port 7861 for hot-module replacement.
  • Production deployment uses docker-compose.production.yml with no volume mounts, running the pre-built application directly on port 7860.
  • Environment variables control HOST, PORT, HMR_PORT, BASIC_SSL, and ACCESS_KEYS across both configurations.

Frequently Asked Questions

How do I switch between development and production Docker configurations?

Use the -f flag to specify the production compose file when running docker compose commands. For development, run docker compose up from the repository root. For production, execute docker compose -f docker-compose.production.yml up --build to ensure the container starts without development tooling or volume mounts.

Why does MiniSearch require Python in the Docker image?

The container runs SearXNG, a self-hosted meta-search engine written in Python. The Dockerfile installs Python 3 and creates a virtual environment at /usr/local/searxng/ to isolate SearXNG's dependencies from the system Python packages, ensuring the search backend operates correctly alongside the Node.js front-end.

Can I modify the default port 7860 for MiniSearch?

Yes. Both docker-compose.yml and docker-compose.production.yml reference the PORT environment variable with a default of 7860. Override this by setting PORT=8080 (or your preferred port) in a .env file or directly in your shell before running docker compose commands.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →