# How SearxNG Is Bundled in Vane's Docker Deployment: Complete Technical Architecture

> Discover how SearxNG is bundled in Vane's Docker deployment. Learn about the technical architecture, virtual environment setup, and parallel startup process.

- Repository: [Kushagra Srivastava/Vane](https://github.com/ItzCrazyKns/Vane)
- Tags: architecture
- Published: 2026-03-11

---

**Vane embeds a fully functional SearxNG instance inside its Docker container by cloning the upstream source into a Python virtual environment and orchestrating parallel startup via a custom entrypoint script that exposes the metasearch engine on port 8080 while the Next.js UI serves on port 3000.**

Vane is an open-source search aggregator that delivers privacy-respecting results through an integrated metasearch backend. According to the ItzCrazyKns/Vane source code, the application eliminates external service dependencies by bundling SearxNG directly into its single-container architecture. This approach ensures every deployment ships with a self-contained search engine capable of querying multiple sources without requiring separate infrastructure management.

## Build-Time Architecture

Vane’s Docker image construction follows a multi-stage pattern that compiles the Node.js frontend while simultaneously preparing a complete Python runtime environment for SearxNG.

### Multi-Stage Builder Foundation

The `Dockerfile` initiates with a standard Node.js builder stage (lines 1‑17) that compiles the production-ready Next.js bundle and creates a writable `data` directory. The subsequent runtime stage—also based on `node:24.5.0-slim`—handles all SearxNG preparation, ensuring the final image contains both the web interface and the search backend.

### System Dependencies and Security Hardening

The runtime stage installs compilation tools and Python libraries required by SearxNG’s cryptographic and XML processing features. Lines 20‑25 of the `Dockerfile` execute:

```dockerfile
RUN apt-get update && apt-get install -y \
    python3-dev python3-babel python3-venv python-is-python3 \
    uwsgi uwsgi-plugin-python3 \
    git build-essential libxslt-dev zlib1g-dev libffi-dev libssl-dev \
    curl sudo \
    && rm -rf /var/lib/apt/lists/*

```

Following dependency installation, lines 37‑44 establish a **low-privilege system user** named `searxng` with a dedicated home directory at `/usr/local/searxng`. This security measure ensures the metasearch engine runs without root privileges.

### Configuration and Source Deployment

Default SearxNG configurations are baked into the image during build. Lines 46‑49 copy three critical files into `/etc/searxng`:

```dockerfile
COPY searxng/settings.yml /etc/searxng/settings.yml
COPY searxng/limiter.toml /etc/searxng/limiter.toml
COPY searxng/uwsgi.ini /etc/searxng/uwsgi.ini

```

The source code is then cloned directly from the official SearxNG repository. Executed as the `searxng` user in lines 53‑55, the build process downloads the latest source into `/usr/local/searxng/searxng-src`:

```dockerfile
USER searxng
RUN git clone "https://github.com/searxng/searxng" "/usr/local/searxng/searxng-src"

```

### Python Virtual Environment Installation

The final build steps establish an isolated Python environment and install SearxNG in editable mode. Lines 56‑57 create the virtual environment at `/usr/local/searxng/searx-pyenv` and upgrade core tooling:

```dockerfile
RUN python3 -m venv "/usr/local/searxng/searx-pyenv"
RUN "/usr/local/searxng/searx-pyenv/bin/pip" install --upgrade pip setuptools wheel pyyaml msgspec typing_extensions

```

Lines 58‑60 then install SearxNG itself using the `-e .` flag, which links the installation directly to the cloned source directory. This editable mode ensures the runtime uses the exact code version cloned during the build:

```dockerfile
RUN cd "/usr/local/searxng/searxng-src" && \
    "/usr/local/searxng/searx-pyenv/bin/pip" install --use-pep517 --no-build-isolation -e .

```

## Runtime Orchestration

Once the container launches, the [`entrypoint.sh`](https://github.com/ItzCrazyKns/Vane/blob/main/entrypoint.sh) script coordinates the startup sequence to ensure SearxNG initializes before the Vane web server accepts traffic.

### Entrypoint Script Coordination

The entrypoint script spawns SearxNG as a background process running under the dedicated `searxng` user. Lines 4‑7 of [`entrypoint.sh`](https://github.com/ItzCrazyKns/Vane/blob/main/entrypoint.sh) configure the environment and launch the Flask application:

```sh
#!/bin/sh
set -e

echo "Starting SearXNG..."
sudo -H -u searxng bash -c "cd /usr/local/searxng/searxng-src \
  && export SEARXNG_SETTINGS_PATH='/etc/searxng/settings.yml' \
  && export FLASK_APP=searx/webapp.py \
  && /usr/local/searxng/searx-pyenv/bin/python -m flask run \
     --host=0.0.0.0 --port=8080" &
SEARXNG_PID=$!

```

The script explicitly sets `SEARXNG_SETTINGS_PATH` to point at the baked-in configuration and binds the service to **port 8080** on all interfaces.

### Health Check Implementation

Before launching the Vane application, the entrypoint executes a blocking health-check loop (lines 12‑21) that polls `http://localhost:8080` for up to approximately 30 seconds. This verification ensures the metasearch backend is fully initialized and responsive before the Node.js server starts accepting user queries.

### Service Integration

After confirming SearxNG’s availability, the script transitions to the Vane application directory and executes the Node.js server. The `Dockerfile` (line 72) hardcodes the connection between services by setting `SEARXNG_API_URL=http://localhost:8080`, directing all search queries from the Next.js frontend to the bundled backend.

## Docker Compose Integration

The [`docker-compose.yaml`](https://github.com/ItzCrazyKns/Vane/blob/main/docker-compose.yaml) exposes only the Vane web interface to external traffic while keeping the SearxNG port internal. The service definition maps **port 3000** to the host and mounts a persistent volume for data storage:

```yaml
services:
  vane:
    image: itzcrazykns1337/vane:latest
    build:
      context: .
    ports:
      - '3000:3000'
    volumes:
      - data:/home/vane/data
    restart: unless-stopped

volumes:
  data:
    name: 'vane-data'

```

From a consumer perspective, Vane presents a unified endpoint on port 3000 that internally forwards requests to the embedded SearxNG instance on `localhost:8080`, creating a seamless, self-contained deployment.

## Summary

- **Single-container architecture**: Vane bundles both the Next.js frontend and SearxNG backend in one Docker image based on `node:24.5.0-slim`.
- **Isolated Python environment**: SearxNG runs under a dedicated `searxng` user with a virtual environment at `/usr/local/searxng/searx-pyenv` and source code at `/usr/local/searxng/searxng-src`.
- **Editable installation**: The metasearch engine is installed with `pip install -e .`, linking runtime execution directly to the cloned GitHub source.
- **Orchestrated startup**: The [`entrypoint.sh`](https://github.com/ItzCrazyKns/Vane/blob/main/entrypoint.sh) script manages service dependencies, ensuring SearxNG passes health checks on port 8080 before launching the Vane server on port 3000.
- **Zero external dependencies**: The default configuration requires no external SearxNG instances, as `SEARXNG_API_URL` points to the internal `localhost:8080` endpoint.

## Frequently Asked Questions

### Does Vane require a separate SearxNG installation?

No. Vane’s Docker image contains a fully embedded SearxNG instance cloned from the official repository during the build process. The [`entrypoint.sh`](https://github.com/ItzCrazyKns/Vane/blob/main/entrypoint.sh) script starts this internal service automatically, and the environment variable `SEARXNG_API_URL` is pre-configured to reference `http://localhost:8080`, eliminating the need for external search infrastructure.

### Which user account runs the embedded SearxNG process?

The SearxNG process executes under a low-privilege system user named **`searxng`** created in the `Dockerfile` (lines 37‑44). This user owns the `/usr/local/searxng` directory and the Python virtual environment, ensuring the metasearch engine operates without root privileges inside the container.

### How does Vane ensure SearxNG is ready before accepting web traffic?

The [`entrypoint.sh`](https://github.com/ItzCrazyKns/Vane/blob/main/entrypoint.sh) script implements a blocking health-check mechanism that executes a `curl` loop against `http://localhost:8080` for approximately 30 seconds. Only after confirming the SearxNG HTTP endpoint is responsive—or upon timeout—does the script proceed to launch the Node.js server, preventing race conditions between the frontend and backend initialization.

### Can I customize the SearxNG configuration when deploying Vane?

Yes. The build process copies default configuration files including [`settings.yml`](https://github.com/ItzCrazyKns/Vane/blob/main/settings.yml), [`limiter.toml`](https://github.com/ItzCrazyKns/Vane/blob/main/limiter.toml), and [`uwsgi.ini`](https://github.com/ItzCrazyKns/Vane/blob/main/uwsgi.ini) into `/etc/searxng` (lines 46‑49 of the `Dockerfile`). At runtime, the `SEARXNG_SETTINGS_PATH` environment variable points to [`/etc/searxng/settings.yml`](https://github.com/ItzCrazyKns/Vane/blob/main//etc/searxng/settings.yml). You can override these configurations by mounting custom files into the container at these specific paths or by modifying the source files in the repository before building the image.