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

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:

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:

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:

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:

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:

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 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 configure the environment and launch the Flask application:

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

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 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 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 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, limiter.toml, and 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. 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.

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 →