SearXNG on Ubuntu 24.04 on Azure User Guide
Overview
SearXNG is a free, open source, privacy-respecting metasearch engine. Instead of profiling you, it forwards your query to 70 plus upstream engines (Google, Bing, DuckDuckGo, Brave, Startpage, Wikipedia and many more), aggregates and de-duplicates the results, and returns them without ever storing your search history, setting tracking cookies or building an advertising profile. The cloudimg image installs SearXNG at a pinned upstream commit into a dedicated Python virtualenv, runs it as a hardened non-root searxng systemd service bound to loopback, and fronts it on port 80 with an nginx reverse proxy that 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, and the configuration and secret live on a dedicated Azure data disk. Backed by 24/7 cloudimg support.
What is included:
- 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.service+nginx.serviceas systemd units, enabled and active- An unauthenticated
/healthzendpoint for Azure Load Balancer health probes - 24/7 cloudimg 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 cloudimg image places no source-distribution obligation on you.
Prerequisites
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; SearXNG is light on resources. NSG inbound: allow 22/tcp from your management network, 80/tcp for the web interface, and 443/tcp if 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 cloudimg, 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). Review the dedicated data disk on the Disks tab, then Review + create -> Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name searxng \
--image <marketplace-image-urn> \
--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 1010
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm the services are running
systemctl is-active searxng.service nginx.service
Both 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 and a unique password is generated on the first boot of your VM and written to a root-only file:
sudo cat /root/searxng-credentials.txt
This 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, and 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:
curl -s http://localhost/healthz
It returns ok. This endpoint never requires authentication, so it is safe for an Azure Load Balancer health probe.
Step 7 - Confirm authentication and the JSON search API
Because a password is set on first boot, an unauthenticated request returns HTTP 401, so nobody reaches your instance without the password. The following reads the per-VM password from the credentials file and proves the round-trip - unauthenticated 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", [])))'
It prints 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>/. Your browser prompts for a username and password: enter admin and the password from Step 5. SearXNG opens on its 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 shows them grouped by category (General, Images, Videos, News, Map, Music, IT, Science, Files, Social Media). Each result lists which engines returned it and offers a cached link, and 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. From here you set the default categories and search language, choose an autocomplete backend, toggle SafeSearch, and - on the Engines tab - 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
The Engine stats page (linked from the footer) reports, for every enabled engine, its result count, median response time and a reliability score, so you can see at a glance which engines are healthy and 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:
sudo ls -la /var/lib/searxng/
grep -E 'bind_address|port:|limiter|method:|- html|- json' /var/lib/searxng/settings.yml
The settings bind SearXNG to loopback 127.0.0.1:8080, disable the rate limiter (so no Valkey or Redis is needed for this single-tenant, password-gated instance), and enable both the html and json response formats. To repoint SearXNG at 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(it merges over SearXNG's shipped defaults viause_default_settings: true) and 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 to a specific upstream commit in this image for reproducibility. cloudimg 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 per the SearXNG documentation.
Support
This image is maintained by cloudimg with 24/7 support. For help deploying or operating SearXNG on Azure, contact cloudimg support through the Azure Marketplace listing.