SSD Nodes Learn 8GB RAM — $66/jaar
Gidsen Matt ConnorDoor Matt Connor · Bijgewerkt 2026-08-02

SearXNG zelf hosten met Docker Compose

Bouw een privézoekmachine op uw eigen VPS met SearXNG, Docker Compose, settings.yml, limiter, nginx met TLS en een JSON-API voor uw scripts.

Wat u bouwt

Met self-hosting van SearXNG krijgt u een privézoekmachine die op uw eigen server draait. SearXNG is een metazoekmachine: deze neemt uw zoekopdracht aan, bevraagt andere zoekmachines zoals Google, Bing, DuckDuckGo en Wikipedia en voegt de resultaten samen tot één resultatenpagina. Er wordt geen profiel opgebouwd en er wordt geen trackingcookie ingesteld, omdat uw eigen machine de enige machine is die uw zoekopdracht bewaart.

De stack is klein. Twee containers, één instellingenbestand en één reverse proxy. De belangrijkste beslissing is of de instantie privé is, wat betekent dat alleen u en uw eigen scripts er toegang toe hebben, of openbaar, wat betekent dat iedereen op internet zoekopdrachten kan uitvoeren. Die keuze bepaalt de beveiligingsinstellingen. Maak deze keuze voordat u iets invoert. Het standaardantwoord is privé.

Er is nog een reden om een instantie te gebruiken. Een SearXNG-instantie biedt JSON, zodat elk script of elke AI-agent die u schrijft toegang krijgt tot een zoek-API die u beheert, zonder sleutel, kosten per zoekopdracht of quotameldingen.

SearXNG installeren met Docker Compose

Het project publiceert een containerimage en een Compose-bestand. Haal beide naar een nieuwe Ubuntu 24.04-server waarop Docker Engine en de Compose-plugin al zijn geïnstalleerd. Als Docker nieuw voor u is, begint u met De basis van Docker Compose op een VPS en komt u daarna terug.

sudo install -d -o "$USER" -g "$USER" -m 750 /opt/searxng
cd /opt/searxng
mkdir -p core-config
curl -fsSL \
  -O https://raw.githubusercontent.com/searxng/searxng/master/container/docker-compose.yml \
  -O https://raw.githubusercontent.com/searxng/searxng/master/container/.env.example
cp -i .env.example .env

Het Compose-bestand definieert twee services. core is SearXNG zelf en valkey is een in-memory gegevensopslag die wordt gebruikt voor snelheidsbeperking en tijdelijke statusgegevens. Het koppelt ./core-config/ aan /etc/searxng/ in de container. Daardoor staat alle configuratie die u instelt in die ene map op de host.

Bewerk nu .env. Elke regel in het meegeleverde voorbeeld is van commentaar voorzien. Daarom start de container op poort 8080 op elk adres. Hef het commentaar op bij deze drie regels en stel ze in.

SEARXNG_VERSION=latest
SEARXNG_HOST=127.0.0.1
SEARXNG_PORT=8080

SEARXNG_HOST=127.0.0.1 is de belangrijkste instelling. Hiermee wordt de gepubliceerde poort 127.0.0.1:8080:8080 in plaats van [::]:8080:8080. Daardoor reageert de container alleen op het loopback-adres en kan internetverkeer er niet rechtstreeks bij. Als u dit overslaat, is de container direct na het starten blootgesteld. Een gepubliceerde Docker-poort wordt namelijk vóór uw firewallregels ingevoegd. Lees deze valkuil volledig door: gepubliceerde Docker-poorten omzeilen ufw.

SEARXNG_VERSION=latest is geschikt zolang u aan het leren bent. Zet in een server die u serieus gebruikt de tag vast. Vanaf juli 2026 zijn de releasetags op een datum gebaseerd en zien ze eruit als 2026.3.25-541c6c3cb. Een vastgezette deployment wordt dan bijgewerkt wanneer u dat beslist, niet wanneer de registry zonder uw tussenkomst verandert.

settings.yml: de belangrijke onderdelen

Maak core-config/settings.yml aan vóór de eerste start. Met use_default_settings: true laadt SearXNG eerst de meegeleverde standaardinstellingen en past het daarna alleen de sleutels toe die u hebt opgegeven. Zo blijft uw bestand kort en blijft het werken na upgrades die nieuwe opties toevoegen.

Genereer eerst het geheim, omdat de waarde rechtstreeks in het bestand wordt geplaatst.

openssl rand -hex 32
use_default_settings: true

general:
  instance_name: "search.example.com"

server:
  base_url: "https://search.example.com/"
  secret_key: "paste-the-openssl-output-here"
  limiter: false
  public_instance: false
  image_proxy: true

valkey:
  url: valkey://valkey:6379/0

search:
  safe_search: 0
  autocomplete: "duckduckgo"
  formats:
    - html
    - json

secret_key ondertekent sessie- en tokengegevens. De meegeleverde standaardwaarde is de letterlijke tekenreeks ultrasecretkey. Als u deze laat staan, kan iedereen die deze standaardwaarde kent die tokens vervalsen. Vervang de waarde eenmalig en laat deze daarna ongewijzigd. Als u de waarde later wijzigt, gaan alle opgeslagen voorkeuren verloren.

base_url moet het openbare HTTPS-adres met de afsluitende slash zijn. SearXNG gebruikt dit adres in de links die het genereert. Als u dit op localhost laat staan, verwijst de link naar de "volgende pagina" in een externe browser naar de computer van de gebruiker zelf en werkt deze niet.

formats bepaalt welke uitvoertypen het webendpoint produceert. json staat niet in de standaardlijst. Een JSON-verzoek retourneert daarom 403 totdat u dit toevoegt. image_proxy: true stuurt miniaturen van resultaten via uw server. De sites waarop deze afbeeldingen staan, zien daardoor de adressen van uw bezoekers niet.

De valkey.url gebruikt de hostnaam valkey, omdat dit de servicenaam in het Compose-bestand is. Compose plaatst beide containers op één netwerk waarop servicenamen worden vertaald. Als u dit naar localhost laat verwijzen, werkt de limiter niet. Binnen de container core verwijst localhost namelijk naar die container.

Het geheim staat in een gewoon bestand. Beveilig daarom de bovenliggende directory en niet alleen het bestand zelf. chmod 750 /opt/searxng voorkomt dat andere gebruikers op de host toegang krijgen. Stel core-config/settings.yml niet strenger in op modus 600. De container draait als een eigen gebruiker zonder verhoogde rechten. Als die gebruiker het bestand niet kan lezen, start SearXNG helemaal niet.

Start de stack en controleer deze.

cd /opt/searxng
docker compose up -d
docker compose ps
curl -I http://127.0.0.1:8080/

docker compose ps moet beide containers tonen met de status running. De curl moet antwoorden met HTTP/1.1 200 OK. Als er geen antwoord komt, bekijkt u docker compose logs core. Een YAML-fout in settings.yml verschijnt daar als een parsefout met het betreffende regelnummer.

Plaats het achter nginx met TLS

De container luistert alleen op de loopbackinterface. nginx maakt de service bereikbaar en voegt ook transportlaagbeveiliging (TLS) toe. Schrijf /etc/nginx/sites-available/searxng.

server {
    listen 80;
    server_name search.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
sudo ln -s /etc/nginx/sites-available/searxng /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d search.example.com

nginx -t geeft syntax is ok en test is successful weer voordat u nginx opnieuw laadt. Certbot herschrijft hetzelfde bestand zodat het op 443 luistert met een certificaat en voegt een omleiding vanaf poort 80 toe. Het DNS-record voor search.example.com moet al naar deze server verwijzen, omdat de certificaatautoriteit het eigendom controleert door via HTTP een bestand op te vragen. De volledige handleiding, inclusief vernieuwing, staat in de Certbot- en nginx-handleiding voor Ubuntu 24.04.

De twee headers voor doorsturen zijn niet overbodig. Zonder X-Forwarded-For en X-Real-IP bevat elk verzoek dat bij SearXNG aankomt het proxyadres. Daardoor ziet de snelheidsbegrenzer één client die al het verkeer genereert en kan deze de bezoekers niet van elkaar onderscheiden.

Waarom scripts en agents een JSON-zoek-API nodig hebben

Met json in formats retourneert hetzelfde endpoint dat de pagina weergeeft gestructureerde gegevens.

curl -s 'http://127.0.0.1:8080/search?q=wireguard+mtu&format=json' \
  | jq -r '.results[0:5][] | .url'

U ontvangt een object met een results-array. Elke entry bevat url, title, content en de engine die deze heeft geleverd, naast answers, infoboxes en suggestions. Dat is voldoende om gegevens door te geven aan een samenvattingsprogramma, een linkchecker of een onderzoeksproces.

Dit is relevant voor alles wat agentfunctionaliteit bevat. Een taalmodel heeft een trainingsafsluitdatum. Daarom heeft het live zoeken nodig om vragen over het heden te beantwoorden. Commerciële zoek-API's brengen kosten per query in rekening en hanteren strikte snelheidslimieten. Een lokale instantie gebruikt één container op een server waarvoor u al betaalt. De queries verlaten die server nooit. Als u tools aan een model koppelt, geldt dezelfde redenatie voor MCP-servers op een VPS uitvoeren. Een zoektool is daarbij meestal de eerste tool die mensen toevoegen.

Voor API-gebruik gelden twee regels. Houd de instantie privé. Bind de API-kant daarom aan het loopbackadres of aan een privénetwerk. Geef alleen uw eigen hosts toegang. Voer daarna queries met mate uit. SearXNG stuurt uw verzoek door naar echte zoekmachines. Een script dat honderd queries per seconde uitvoert, vraagt Google dus om uw server te blokkeren.

De limiter en wat er verandert voor een openbare instantie

De limiter is de botbeveiliging van SearXNG. Deze controleert requestheaders, adressen en requestfrequenties en laat verkeer vallen dat geautomatiseerd lijkt. Hiervoor is Valkey nodig om die status op te slaan. Daarom bevat het Compose-bestand Valkey.

Laat op een privé-instantie limiter: false ingeschakeld. Uw eigen scripts zijn per definitie geautomatiseerd verkeer. De limiter zou dus precies de JSON-aanroepen blokkeren waarvoor u de instantie hebt ingericht. Toegangsbeheer hoort daarentegen bij de reverse proxy: een combinatie van allow en deny in de nginx location, HTTP-basisauthenticatie of een firewall die alleen uw andere servers toegang geeft.

Als u de instantie wel voor andere gebruikers beschikbaar stelt, schakelt u beide opties in.

server:
  limiter: true
  public_instance: true

Voor fijnmaziger beheer gebruikt u core-config/limiter.toml. De container leest dit bestand op /etc/searxng/limiter.toml. U definieert alleen de sleutels die u wilt wijzigen. Achter een proxy moet u de proxy declareren. Anders ziet de limiter uw nginx-adres als de enige misbruikende client.

[botdetection]
trusted_proxies = [
  '127.0.0.0/8',
  '::1',
]

[botdetection.ip_limit]
link_token = true

Met link_token = true laat u SearXNG een token uitgeven dat alleen een echte browsersessie ophaalt. Dit stopt de meeste eenvoudige scrapers. Verwacht dat een openbare instantie binnen enkele dagen scrapers aantrekt. Houd ook rekening met enginefouten. Hoe meer verkeer u doorstuurt, hoe sneller upstream-engines CAPTCHA's naar uw serveradres gaan terugsturen. Een openbare SearXNG-instantie vereist doorlopend beheer. Dat geldt niet voor een privé-instantie. Daarom staat die op de meeste korte lijsten van zaken die in 2026 de moeite waard zijn om zelf te hosten.

Waarom zoekopdrachten niets opleveren

Open /stats op uw instantie. Dit bestand vermeldt elke engine met het foutpercentage en de responstijd. Dit is de eerste plaats waar u kijkt als de resultaten beperkt lijken.

Een engine met fouten als "Access denied" of "CAPTCHA" blokkeert het adres van uw server. Dit komt vaak voor bij adressen uit datacenterranges, omdat zoekmachines ervan uitgaan dat deze van scrapers zijn. SearXNG schakelt de engine met fouten vervolgens tijdelijk uit in plaats van deze opnieuw te proberen. Daardoor valt een geblokkeerde engine ongemerkt uit uw resultaten. Schakel de engine uit in settings.yml of accepteer het verlies. De overige engines blijven antwoorden.

Als alle engines tegelijk fouten geven, werkt er in de container geen uitgaande naamresolutie of is er geen route naar internet. Test dit vanuit de container.

docker compose exec core wget -qO- https://duckduckgo.com > /dev/null && echo ok

FAQ

Maakt SearXNG mijn zoekopdrachten anoniem?

Het verbergt uw identiteit voor de zoekmachines die het raadpleegt, omdat deze uw server de aanvraag zien doen in plaats van uw browser. Het verbergt de zoekopdracht niet voor uw server en het verbergt uw server niet voor de zoekmachines. Op een instantie voor één gebruiker is al het verkeer vanaf dat adres van u. Het adres wordt daardoor zelf de identificatie. Het verkeer tussen uw browser en uw instantie wordt beveiligd met het TLS-certificaat.

Waarom retourneert een JSON-aanvraag 403 Forbidden?

Er zijn twee oorzaken. Beide houden verband met de configuratie. Ofwel ontbreekt json in de lijst formats onder search: in settings.yml, wat de standaardinstelling is, ofwel is de limiter ingeschakeld en heeft deze uw script als bot geclassificeerd. Voeg eerst de indeling toe en start opnieuw met docker compose restart core. Probeer het daarna opnieuw. Als het nog steeds mislukt, stelt u limiter: false in en regelt u de toegang in de reverse proxy.

Heb ik de Valkey-container nodig als ik de limiter uitgeschakeld laat?

Laat deze actief. SearXNG werkt zonder deze container, maar de limiter kan later niet zonder de container worden ingeschakeld. De container bevat ook andere kortlevende statusgegevens. De container is klein en slaat alleen gegevens in de cache op. Verwijderen levert daarom weinig besparing op en u verliest de mogelijkheid om deze later te gebruiken.

Hoe werk ik SearXNG bij?

Voer docker compose pull en daarna docker compose up -d uit in /opt/searxng. Compose maakt elke container opnieuw aan waarvan de image is gewijzigd en laat uw map core-config/ ongemoeid. Daardoor blijft settings.yml behouden. Omdat use_default_settings: true uw sleutels samenvoegt met de meegeleverde standaardwaarden, krijgen opties die upstream zijn toegevoegd verstandige waarden. Het bestand raakt daardoor niet defect.

Kunnen meerdere mensen één instantie delen?

Ja. In dat geval schakelt u de limiter in en stelt u public_instance: true in. Voorkeuren worden opgeslagen in de eigen browser van elke bezoeker. U hoeft daarom geen accounts te beheren. Controleer /stats een week lang nadat u de instantie beschikbaar hebt gemaakt. Upstream-zoekmachines beginnen uw server namelijk al af te wijzen voordat u merkt dat er resultaten ontbreken.

#searxng#search#privacy#self-hosting#docker