Can You Run SearXNG on Windows?
Yes, through Docker Desktop and WSL2. Install the SearXNG container, bind it to localhost, set a secret key, and learn where a Windows PC stops being enough.
Can you run SearXNG on Windows?
Yes, you can run SearXNG on Windows, but not as a native Windows program. The SearXNG docs list three install methods: a container, an install script, and a manual step-by-step install. None of them targets Windows. The container method still works, because Docker Desktop runs Linux containers inside WSL2 (Windows Subsystem for Linux, version 2), which is a real Linux kernel that ships with Windows.
The answer has two parts. On a Windows PC, SearXNG works well as a private search page for that one machine. As a search engine for your phone and every other device you own, a PC that sleeps is a poor home, and a small VPS (virtual private server) does that job better.
SearXNG is a metasearch engine. It sends your query to engines such as Google and Bing, merges the results, and removes tracking before you see them. If you are still deciding whether you need one at all, compare SearXNG with Startpage and DuckDuckGo first.
Why there is no native Windows install
SearXNG is a Python web application. Its install script and its step-by-step guide assume a Linux server: they create a searxng system user, write the config to /etc/searxng/settings.yml, and run the app as a Linux service. Windows has none of those pieces. You could try to force the Python app onto Windows by hand, but no documented path exists, so you would have to debug every problem alone.
The SearXNG image is a Linux image, so Windows needs a Linux kernel to run it. WSL2 provides that kernel. You can use it in two ways:
- Docker Desktop with the WSL2 backend. Docker Desktop runs the Docker engine inside WSL2. It makes the
dockercommand available in your WSL distro, and it publishes container ports on Windowslocalhost. This is the easier route. - Docker Engine installed directly inside a WSL distro. There is no Docker Desktop. You install Docker from Ubuntu's own packages and manage the engine yourself.
Docker Desktop has license terms. As of October 2026 it is free for personal use and for small businesses, and larger companies need a paid plan. The guide on whether Docker is free, and how Docker Engine differs from Docker Desktop covers the exact limits.
This guide uses Docker Desktop, then shows the Docker Engine variant in one short section. In both cases you run every SearXNG command in an Ubuntu terminal inside WSL.
Step 1: Install WSL2 and Ubuntu
Open PowerShell as administrator and run:
wsl --install -d Ubuntu-24.04Restart Windows when it asks. After the restart, Ubuntu opens and asks you to create a Linux username and password. This account is separate from your Windows login.
If the install stops with error 0x80370102 and a message asking you to enable the Virtual Machine Platform feature and virtualization in the BIOS, the CPU's hardware virtualization is switched off. WSL2 runs a small virtual machine, so it cannot start without it. Turn on Intel VT-x or AMD-V in the firmware settings and run the command again.
Then check the WSL version from PowerShell:
wsl -l -vThe VERSION column should show 2 for Ubuntu-24.04. A 1 means the distro runs under WSL1, which translates Linux system calls and has no real Linux kernel, so Docker cannot run there. Convert it with wsl --set-version Ubuntu-24.04 2.
Step 2: Install Docker Desktop and connect it to Ubuntu
Download Docker Desktop from docker.com and install it. During setup, keep the option to use WSL 2 instead of Hyper-V selected. After Docker Desktop starts, open Settings > General and confirm that Use the WSL 2 based engine is on. Then open Settings > Resources > WSL integration and switch on integration for Ubuntu-24.04.
Now open the Ubuntu terminal and check that Docker answers:
docker version
docker compose versionBoth commands should print a version, and docker version should show a Server section. Two errors are common here, and each has one cause:
The command 'docker' could not be found in this WSL 2 distromeans the WSL integration switch for this distro is off. Turn it on, then open a new Ubuntu terminal.Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?means Docker Desktop itself is not running. Start it from the Start menu and wait until it reports that the engine is running.
If Compose is new to you, the guide to Docker Compose basics explains services, volumes and docker compose up -d. Everything in it applies inside WSL.
Step 3: Download the SearXNG compose files
Work in your Linux home directory, not under /mnt/c. Files under /mnt/c live on the Windows drive and reach Linux through a translation layer, which makes file access slower. Docker's own WSL guidance says to keep bind-mounted project files in the Linux file system for this reason.
Older guides clone a separate searxng-docker repository. The current SearXNG docs download the compose file from the container/ directory of the main repository instead, and this guide follows the current docs:
mkdir -p ~/searxng/core-config/
cd ~/searxng/
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
ls -als -a should list .env, .env.example, core-config and docker-compose.yml.
The compose file defines two services. core is SearXNG itself. valkey is a small key-value store that SearXNG can use for its rate limiter. The core service reads its environment from .env and mounts ./core-config/ at /etc/searxng/ inside the container. Its port line is the one to understand:
ports:
- ${SEARXNG_HOST:+${SEARXNG_HOST}:}${SEARXNG_PORT:-8080}:${SEARXNG_PORT:-8080}When SEARXNG_HOST is empty, this expands to 8080:8080. Docker then publishes the port on every address the PC has, not only on localhost. When SEARXNG_HOST is set, it expands to 127.0.0.1:8080:8080 (or whatever address you set), and the port exists only on that address.
Step 4: Bind SearXNG to 127.0.0.1 and set the secret key
Two lines in .env matter for a private instance. Run:
cd ~/searxng/
echo "SEARXNG_HOST=127.0.0.1" >> .env
echo "SEARXNG_SECRET=$(openssl rand -hex 32)" >> .env
chmod 600 .env
grep '^SEARXNG' .envgrep should print exactly two lines: the host and a 64-character hex secret.
Why bind to 127.0.0.1. The address 127.0.0.1 is loopback. Only programs on this PC can connect to it. Without that line, whether another device can reach your search page depends on Windows Defender Firewall rules, including any firewall prompt you clicked months ago. Binding to loopback removes that question.
Why set the secret. SearXNG uses server.secret_key to sign values such as image proxy links, and the container's settings template turns the image proxy on. The SEARXNG_SECRET variable overrides whatever key is in settings.yml. On first start, the container entrypoint copies a template to core-config/settings.yml and replaces the placeholder ultrasecretkey with a random string, so you would get a random key without this line too. Setting it yourself makes the key one you created, and it survives if you ever delete core-config/ to start over.
The placeholder matters for one reason. If you copy a settings.yml from an old guide that still says ultrasecretkey, SearXNG refuses to start. It logs this line and exits:
server.secret_key is not changed. Please use something else instead of ultrasecretkey.Step 5: Start SearXNG and check it
cd ~/searxng/
docker compose up -d
docker compose ps
docker compose port core 8080
curl -sI http://127.0.0.1:8080 | head -n 1docker compose ps should list searxng-core and searxng-valkey with a status of Up. docker compose port core 8080 should print 127.0.0.1:8080. If it prints 0.0.0.0:8080 instead, the SEARXNG_HOST line did not reach Compose. Check its spelling in .env, then run docker compose up -d again. The curl line should print a status line containing 200.
If up -d fails with Bind for 127.0.0.1:8080 failed: port is already allocated, another program on the PC already holds port 8080. Add SEARXNG_PORT=8888 to .env and start again. The compose file uses that variable on both sides of the port mapping, and the container passes it to its web server, so SearXNG then answers on 8888.
To read the logs, run docker compose logs -f core and press Ctrl+C to stop following. On the first start you will see the entrypoint report that /etc/searxng/settings.yml does not exist and that it is creating it from the template. After that, core-config/settings.yml exists in your folder, and you edit SearXNG's settings there.
Now open http://localhost:8080 in a Windows browser. Docker Desktop forwards the published port from WSL to Windows, so the browser reaches it like any local page. To make it your default search engine, add a custom search engine in the browser settings with this URL:
http://localhost:8080/search?q=%sDocker Engine inside WSL, without Docker Desktop
If you do not want Docker Desktop, install Docker Engine inside Ubuntu instead. Pick one route per distro, because Docker Desktop's integration and Ubuntu's Docker packages both provide a docker command.
Docker Engine needs systemd running as the init process in WSL. Check it:
ps -p 1 -o comm=The output should be systemd. If it prints init, add these two lines to /etc/wsl.conf, run wsl --shutdown from PowerShell, and reopen Ubuntu:
[boot]
systemd=trueThen install Docker from Ubuntu's archive and add your user to the docker group:
sudo apt update
sudo apt install -y docker.io docker-compose-v2
sudo usermod -aG docker $USERGroup changes apply at the next login, so run wsl --shutdown in PowerShell again and reopen Ubuntu. docker version should now show a Server section. Steps 3 to 5 are then identical. Windows still reaches the page at http://localhost:8080, because WSL forwards ports that are bound to localhost inside the WSL virtual machine to Windows localhost. That forwarding is on by default.
What a Windows PC cannot do for SearXNG
It exists only while the PC is on. The restart: always line in the compose file restarts the containers whenever the Docker engine starts. The engine starts only when Docker Desktop starts, so turn on Start Docker Desktop when you sign in to your computer in Settings > General. Even then, a PC that is asleep or shut down answers nothing, and searches from other devices fail.
Your phone cannot reach it. The 127.0.0.1 binding is the reason. Loopback means this PC only, by design. To use the instance from a phone on the same Wi-Fi, you must publish it on the local network and open the Windows firewall for it. To use it from outside your home, you need a tunnel or a VPN as well.
Opening it to the local network needs care. With Docker Desktop, change the host line and restart the stack:
cd ~/searxng/
sed -i 's/^SEARXNG_HOST=.*/SEARXNG_HOST=0.0.0.0/' .env
docker compose up -dThen, in an administrator PowerShell, allow the port from your own subnet on private networks only:
New-NetFirewallRule -DisplayName "SearXNG LAN" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow -Profile Private -RemoteAddress LocalSubnet-Profile Private means the rule does nothing on a network Windows has marked Public, such as a café's Wi-Fi. -RemoteAddress LocalSubnet limits it to devices on the same subnet. If Windows shows a firewall prompt for a Docker process, allow it on private networks only. The page is still plain HTTP with no login, so anyone on your Wi-Fi can use it. This applies to Docker Desktop. With Docker Engine inside WSL in the default NAT network mode, other devices cannot reach WSL ports directly, and you would need extra Windows port-proxy rules.
Do not forward the port on your home router. A public SearXNG instance needs TLS (transport layer security) and the rate limiter with its bot protection. The compose file starts a Valkey container, but the settings template does not point SearXNG at it, and the limiter is off by default. That is fine on loopback and wrong on the internet. The guides on configuring limiter.toml and Valkey and on hardening a public SearXNG instance cover what a public instance needs.
Engines see your home IP address. SearXNG removes cookies and tracking parameters, but it sends each query to the upstream engines from the machine it runs on. On a PC, that machine is your home connection, and you are its only user. The article on whether SearXNG is safe and what it hides explains what an instance does and does not protect.
When a small VPS is the better home for SearXNG
A Windows install is a good way to try SearXNG for a week, and a good test bed for settings. You can use it to work out which engines to enable and disable, then copy settings.yml anywhere else.
A VPS is the better home when you want the instance on every device, all day. It stays on when your PC sleeps. It has a public IP address, so you can give it a domain name and a real TLS certificate, and your phone uses it from any network with no tunnel. One instance can serve a household, and tools such as Open WebUI can call it, as the guide to the SearXNG JSON API for Open WebUI shows. The same docker-compose.yml and .env work on a Linux VPS without changes, so nothing you did here is wasted.
A VPS brings one problem of its own. Some engines answer datacenter IP addresses with CAPTCHAs more often than home connections, and the guide on fixing SearXNG engine CAPTCHA errors covers that. For the full server setup with a reverse proxy and TLS, follow the main guide to self-hosting SearXNG on a VPS. If you are weighing the same choice for your whole development setup, the comparison of WSL and a VPS for development goes through the trade-offs in more detail.
FAQ
Can SearXNG run on Windows without Docker or WSL?
Not by any documented method. The SearXNG docs offer three install methods (container, install script, manual install), and all of them assume Linux. The install script and the manual install create a Linux system user and write to /etc/searxng. The supported way to run SearXNG on a Windows PC is the container under Docker Desktop with the WSL2 backend, or under Docker Engine inside a WSL distro.
Why does SearXNG exit with "secret_key is not changed"?
SearXNG compares server.secret_key with the template placeholder ultrasecretkey at startup. If they match, it logs server.secret_key is not changed. Please use something else instead of ultrasecretkey. and exits. This usually happens after copying a settings.yml from an old guide. Put a random value in .env with echo "SEARXNG_SECRET=$(openssl rand -hex 32)" >> .env, which overrides the file, then run docker compose up -d.
Why can my phone not open my SearXNG instance on Windows?
The instance is bound to 127.0.0.1, which is the loopback address, so only programs on the PC itself can connect. To reach it from a phone on the same Wi-Fi, set SEARXNG_HOST=0.0.0.0 in .env, restart the stack, and add a Windows Defender Firewall rule for TCP 8080 limited to the Private profile and the local subnet. From outside your home it also needs a tunnel or VPN, which is the point where a small VPS is usually simpler.
Is Docker Desktop free for running SearXNG at home?
As of October 2026, Docker Desktop is free for personal use and for small businesses, and larger companies need a paid subscription. A home SearXNG instance falls under personal use. If the license is a problem, install Docker Engine inside the WSL Ubuntu distro with sudo apt install -y docker.io docker-compose-v2 instead, and the same compose files work unchanged.