SearXNG
Overview
SearXNG is a free, open source, privacy-respecting metasearch engine. It forwards your query to 70 plus upstream engines (Google, Bing, DuckDuckGo, Brave, Startpage, Wikipedia and many more) and aggregates and de-duplicates the results. It does not store your search history, set tracking cookies or build an advertising profile.
The SecureAnyCloud image installs SearXNG at a pinned upstream commit into a dedicated Python virtualenv. It runs as a hardened, non-root searxng systemd service bound to loopback. An nginx reverse proxy on port 80 adds a per-VM HTTP Basic Auth gate, so the instance is never left open as a public search proxy.
A unique Basic Auth password and a fresh SearXNG secret key are generated on the first boot of every VM. The configuration and secret live on a dedicated Azure data disk.
What you get:
- SearXNG (pinned upstream commit) served by the granian WSGI application server as the
searxngsystemd service, bound to loopback127.0.0.1:8080 - An nginx reverse proxy on
:80adding a per-VM HTTP Basic Auth gate (useradmin) with a unique password generated on first boot - A fresh, random SearXNG
secret_keygenerated per VM on first boot, never the shipped default - The JSON search API enabled (
format=json) alongside the HTML interface for scripting and integrations - The rate limiter disabled for this single-tenant, password-gated instance, so no external Valkey or Redis is required
- A dedicated Azure data disk at
/var/lib/searxngholding the settings, the per-VM secret and the Basic Auth file searxng.serviceandnginx.serviceas systemd units, enabled and active- An unauthenticated
/healthzendpoint for Azure Load Balancer health probes - 24/7 SecureAnyCloud support
SearXNG is licensed under the GNU Affero General Public License v3 (AGPL-3.0). If you modify SearXNG and offer the modified version to users over a network, the AGPL requires you to make your modified source available to those users. Running the unmodified SecureAnyCloud image places no source-distribution obligation on you.
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region.
Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting point, because SearXNG is light on resources.
In the network security group (NSG), allow these inbound ports:
22/tcpfrom your management network80/tcpfor the web interface443/tcpif you add TLS
SearXNG serves plain HTTP on port 80. For production use, terminate TLS in front of it with your own domain (see Maintenance).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure portal, choose Create a resource, search the Marketplace for SearXNG by SecureAnyCloud, and select Create.
- On Basics, pick your subscription, resource group, region and size.
- Under Administrator account, choose SSH public key and paste your key.
- Under Inbound port rules, allow SSH (22) and HTTP (80).
- On the Disks tab, review the dedicated data disk.
- Choose Review + create, then Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:searxng-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name searxng \
--image sac1647283583153:searxng-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name searxng --port 80 --priority 1010Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
systemctl is-active searxng.service nginx.serviceBoth services report active.
SearXNG runs under the granian WSGI server as the dedicated searxng user, bound to the loopback connector 127.0.0.1:8080. nginx fronts it on port 80, adds the per-VM HTTP Basic Auth gate and exposes an unauthenticated /healthz.
SearXNG's settings, its per-VM secret key and the Basic Auth file all live on the dedicated Azure data disk mounted at /var/lib/searxng.
Step 5 - Retrieve your password
nginx protects SearXNG with HTTP Basic Auth. The username is admin. A unique password is generated on the first boot of your VM and written to a root-only file:
sudo cat /root/searxng-credentials.txtThe file contains SEARXNG_USERNAME, SEARXNG_PASSWORD and the SEARXNG_URL to open in a browser.
The password is stored on disk only as a bcrypt hash in /var/lib/searxng/.htpasswd, so no plaintext password ships in the image. The SearXNG secret_key is rotated to a fresh random value on first boot rather than the shipped default. Store the password somewhere safe.
Step 6 - Confirm the health endpoint
nginx serves an unauthenticated health endpoint for load balancers and probes. Request it:
curl -s http://localhost/healthzThe endpoint returns ok. It never requires authentication, so it is safe to use as an Azure Load Balancer health probe.
Step 7 - Confirm authentication and the JSON search API
A password is set on first boot, so an unauthenticated request returns HTTP 401 and nobody reaches your instance without the password.
The following commands read the per-VM password from the credentials file and test three cases: an unauthenticated request is rejected, the correct password authenticates, and an authenticated JSON search returns aggregated results:
PW=$(sudo grep '^SEARXNG_PASSWORD=' /root/searxng-credentials.txt | cut -d= -f2-)
echo "unauth : $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/)"
echo "authed : $(curl -s -o /dev/null -w '%{http_code}' -u admin:$PW http://127.0.0.1/)" curl -s -u admin:$PW 'http://127.0.0.1/search?q=privacy&format=json' \
| python3 -c 'import sys,json; d=json.load(sys.stdin); print("results:", len(d.get("results", [])))'The output shows unauth : 401, then authed : 200, then a non-zero result count.
The format=json endpoint is enabled on this image so you can drive SearXNG from scripts and integrations. The same query without format=json returns the HTML results page.
Step 8 - Sign in and open the search page
Browse to http://<vm-public-ip>/. When your browser prompts for credentials, enter admin and the password from Step 5.
SearXNG opens on a clean search home: a single search box with no ads, no tracking and no cookies set until you choose to save preferences. The About and Preferences links sit in the top corner, and the footer shows the running version.
Step 9 - Run a private search
Type a query and press Enter. SearXNG queries the upstream engines in parallel, aggregates and de-duplicates the results, and groups them by category: General, Images, Videos, News, Map, Music, IT, Science, Files and Social Media.
Each result lists which engines returned it and offers a cached link. The right-hand column shows the response time and suggestions. Your query is never logged or tied to a profile.
Step 10 - Tune engines and preferences
Open Preferences to tailor the instance. You can set the default categories and search language, choose an autocomplete backend and toggle SafeSearch. On the Engines tab, you can enable or disable any of the 70 plus upstream engines and see their reliability.
Preferences are stored in your browser (or an opt-in cookie), so different users of the same instance can keep their own settings.
Step 11 - Review the engine stats
Open the Engine stats page from the footer. It reports a result count, median response time and reliability score for every enabled engine.
Use these figures to see which engines are healthy, and to drop any that a network or upstream block is slowing down.
Step 12 - Review the configuration and data disk
SearXNG's settings.yml, the per-VM secret key (searxng.env) and the Basic Auth file (.htpasswd) live on the dedicated Azure data disk at /var/lib/searxng, so they are captured into the image and re-provisioned on every VM. List them:
sudo ls -la /var/lib/searxng/
sudo grep -E 'bind_address|port:|limiter|method:|- html|- json' /var/lib/searxng/settings.ymlThe settings bind SearXNG to loopback 127.0.0.1:8080. They disable the rate limiter, so no Valkey or Redis is needed for this single-tenant, password-gated instance. They also enable both the html and json response formats.
To use a different set of engines or change the instance name, edit settings.yml and run sudo systemctl restart searxng.
Maintenance
- Change the password. Regenerate the Basic Auth file with
sudo htpasswd -B /var/lib/searxng/.htpasswd admin, then update/root/searxng-credentials.txtfor your records. - Add engines or change settings. Edit
/var/lib/searxng/settings.yml, which merges over SearXNG's shipped defaults viause_default_settings: true. Then runsudo systemctl restart searxng. - Add TLS for production. Put your own domain in front of nginx and terminate TLS with a certificate from your CA or Let's Encrypt. Then set
server.base_urlinsettings.ymlto yourhttps://URL. - Updates. SearXNG is a rolling release, pinned in this image to a specific upstream commit for reproducibility. SecureAnyCloud publishes refreshed images. For security patches, apply OS updates with sudo apt update && sudo apt upgrade.
- Rate limiting. This image disables the limiter because the nginx Basic Auth gate already restricts access. If you open the instance more widely, enable
server.limiterinsettings.ymland provision a Valkey instance as described in the SearXNG documentation.
Support
SecureAnyCloud maintains this image and provides 24/7 support. For help deploying or operating SearXNG on Azure, contact SecureAnyCloud support through the Azure Marketplace listing.
Deploy on Azure
Launch SearXNG Privacy Metasearch Engine on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com