# How to Deploy MiniSearch Using Docker for Development and Production Environments

> Deploy MiniSearch with Docker. Follow steps for development and production environments using docker-compose for efficient container management and rapid iteration.

- Repository: [Victor Nogueira/minisearch](https://github.com/felladrin/minisearch)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Deploy MiniSearch by building the multi-stage Dockerfile once, then use [`docker-compose.yml`](https://github.com/felladrin/minisearch/blob/main/docker-compose.yml) for development with live code mounting and hot-module replacement, or [`docker-compose.production.yml`](https://github.com/felladrin/minisearch/blob/main/docker-compose.production.yml) for immutable production containers.**

The [felladrin/minisearch](https://github.com/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`](https://github.com/felladrin/minisearch/blob/main/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`](https://github.com/felladrin/minisearch/blob/main/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`.

```yaml

# 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:

```bash
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`](https://github.com/felladrin/minisearch/blob/main/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.

```yaml

# 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:

```bash
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:

```bash
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:

```bash
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`](https://github.com/felladrin/minisearch/blob/main/docs/quick-start.md).

## Summary

- **Multi-stage builds** separate the [`llama.cpp`](https://github.com/felladrin/minisearch/blob/main/llama.cpp) compilation (in the `llama-builder` stage) from the Node.js runtime to create efficient production images.
- **Development deployment** uses [`docker-compose.yml`](https://github.com/felladrin/minisearch/blob/main/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`](https://github.com/felladrin/minisearch/blob/main/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`](https://github.com/felladrin/minisearch/blob/main/docker-compose.yml) and [`docker-compose.production.yml`](https://github.com/felladrin/minisearch/blob/main/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.