Deploy Your Own Search Engine

Run a metasearch engine in Docker and expose it to the internet via Cloudflare.

Introduction

30 Second Summary

Every time you search the web, your queries pass through a company that tracks what you search, when you search, and builds a profile of your interests. What if you could run your own search engine that pulls results from Google, Bing, and hundreds of other sources without anyone watching?

In this project, you will deploy your own search engine to the internet using Docker and a free Cloudflare tunnel. By the end, anyone in the world can search the web through your custom-built engine.

What You'll Build

A personalized metasearch engine powered by SearXNG that aggregates results from up to 280 search services, running in a Docker container on your Windows machine and exposed to the public internet through a Cloudflare tunnel.

By the end of this project, you'll have:

  • A running SearXNG Docker container with persistent configuration on your local machine.
  • A custom settings.yml with your search engine's name, security settings, and privacy features.
  • A live public URL on trycloudflare.com that anyone can use to search the web through your engine.
  • Secret Mission: Add a custom theme and configure category-specific engine preferences.

Are there any prerequisites?

No prior experience is required. This guide walks you through installing every tool from scratch, including Docker Desktop, WSL 2, and cloudflared. You just need a Windows 11 machine with at least 8 GB of RAM.

Set Up Your Tools

To deploy a search engine, you need two things: a way to run the search engine software on your machine, and a way to make it accessible on the internet.

In this step, you will install Docker (which runs your search engine inside a container) and cloudflared (which creates a tunnel from your machine to the public internet).

In this step, get ready to:
  • Enable WSL 2 and install Docker Desktop.
  • Verify Docker is working.
  • Download cloudflared.
Enable WSL 2 and install Docker Desktop

Docker Desktop on Windows uses a Linux layer called WSL 2 (Windows Subsystem for Linux) to run containers. You need to enable WSL 2 first, then install Docker Desktop on top of it.

  • Press the Windows key to open your search bar.
  • Type PowerShell and look for Windows PowerShell in the results.
  • Right-click Windows PowerShell and select Run as administrator.
  • If a User Account Control prompt appears, click Yes to allow it.

Why run as administrator?

Enabling WSL 2 changes a Windows system feature, which requires administrator privileges. This is a one-time operation.

  • Enable WSL 2 by running this command:
wsl --install

What does this command do?

This enables the WSL 2 feature on Windows and installs Ubuntu as the default Linux distribution. Docker Desktop uses this Linux layer to run containers efficiently.

  • After the command finishes, restart your computer when prompted.
  • Once your computer restarts, Ubuntu may briefly open a terminal window to finish its setup. You can close it after it completes.

Command failed or WSL already installed?

If you see a message saying WSL is already installed, that means you are good to go. Skip the restart and continue to the Docker Desktop download below.

If you see an error about virtualization, you may need to enable it in your BIOS settings. Help me enable virtualization in my BIOS

Now that WSL 2 is ready, it is time to install Docker Desktop.

What will the installer ask?

The installer will ask which installation mode you prefer. Choose per-user installation. This does not require administrator privileges to install or update.

You will also see a Use WSL 2 instead of Hyper-V option on the Configuration page. Make sure this is selected (it should be by default for per-user installs).

  • Select Per-user when the installer asks which installation mode you prefer.
  • Ensure Use WSL 2 instead of Hyper-V is selected on the Configuration page.
  • Click through the remaining prompts to finish the installation.
  • Once installed, press the Windows key, type Docker Desktop, and press Enter to open it.
  • Wait for Docker Desktop to finish initializing. The whale icon in the system tray will stop animating when it is ready.

How to tell Docker Desktop is ready

Look at the system tray (bottom-right corner of your screen near the clock). You will see a small whale icon. When it stops moving, Docker is ready to use.

Verify Docker is working

With Docker Desktop running, you can now confirm everything is working from the command line.

  • Press the Windows key, type PowerShell, and press Enter to open a regular (non-admin) PowerShell window.
  • Check that Docker is installed by running this command:
docker --version

✔️ I see a version number

Docker is installed and ready. Move on to the next command below.

ⓧ Command not recognized

Docker Desktop may not be fully running yet, or the PATH was not updated.

  • Make sure Docker Desktop is open and the whale icon in the system tray has stopped animating.
  • Close your PowerShell window and open a new one (the PATH updates only apply to new windows).
  • Try running docker --version again.

Help me troubleshoot Docker not being recognized in PowerShell

  • Confirm Docker can pull and run containers by running:
docker run hello-world

✔️ I see Hello from Docker!

Docker successfully pulled an image from the internet and ran it as a container. Your Docker installation is fully working.

ⓧ I see an error

Common causes:

  • Docker Desktop is still starting up. Wait for the whale icon to stop animating, then try again.
  • Your network may be blocking the download. Try switching to a different network (e.g., a mobile hotspot) and running the command again.
  • WSL 2 may not be fully configured. Restart your computer and try again.

Help me fix docker run hello-world failing on Windows

Download cloudflared

The last tool you need is cloudflared, a lightweight program from Cloudflare that creates a secure tunnel between your computer and the public internet.

Now you need to place this file in a dedicated folder and rename it so it is easy to use from the command line.

  • Create a folder for cloudflared by running this command in PowerShell:
mkdir C:\cloudflared
  • Open File Explorer and navigate to your Downloads folder.
  • Find the file cloudflared-windows-amd64.exe you just downloaded.
  • Rename it to cloudflared.exe.
  • Move (drag or cut-paste) cloudflared.exe into the C:\cloudflared\ folder.

Rename and move in one step

You can also do this entirely from PowerShell instead of File Explorer:

Move-Item ~\Downloads\cloudflared-windows-amd64.exe C:\cloudflared\cloudflared.exe
  • Navigate to the cloudflared folder and verify it works by running these commands:
cd C:\cloudflared
.\cloudflared.exe --version

✔️ I see a version number

cloudflared is ready to use. You will use it in a later step to put your search engine on the internet.

ⓧ Command not recognized or file not found

  • Make sure you renamed the file to exactly cloudflared.exe (not cloudflared.exe.exe which can happen if file extensions are hidden).
  • Confirm the file is inside C:\cloudflared\ by running ls C:\cloudflared in PowerShell. You should see cloudflared.exe listed.
  • If the file is there but the command still fails, make sure you ran cd C:\cloudflared first so PowerShell is in the right folder.

Help me get cloudflared working on Windows

What is cloudflared?

cloudflared is Cloudflare's tunnel client. It creates a secure connection between your local machine and Cloudflare's network, giving you a public URL without needing to configure a router, firewall, or domain name.

On Windows, cloudflared does not automatically update. You downloaded a standalone executable that works as-is.

All three tools are installed and verified. Next up, you will use Docker to launch a real search engine on your machine.

Launch Your Search Engine

Your tools are ready to go. Now it's time to use Docker to run an actual search engine on your machine.

SearXNG is a free internet metasearch engine that aggregates results from up to 280 search services. Instead of building a crawler from scratch, you'll pull a pre-built container image and have a fully working search engine in one command.

In this step, get ready to:
  • Create project folders for SearXNG configuration and data.
  • Launch the SearXNG container with Docker.
  • Test your search engine in a browser and confirm it returns results.
Create project folders and run SearXNG

SearXNG needs two folders on your machine. One stores configuration files. The other stores cached data like favicons.

  • Create the configuration and data folders by running these commands in PowerShell:
mkdir C:\searxng\config
mkdir C:\searxng\data
  • Confirm the folders exist by running:
ls C:\searxng

You should see config and data listed in the output.

  • Launch the SearXNG container by running this command:
docker run --name searxng -d -p 8888:8080 -v "C:\searxng\config:/etc/searxng/" -v "C:\searxng\data:/var/cache/searxng/" docker.io/searxng/searxng:latest

What does this command do?

  • --name searxng gives the container a friendly name you can reference later.
  • -d runs the container in detached mode (in the background), so you get your terminal back.
  • -p 8888:8080 maps port 8080 inside the container to port 8888 on your machine. This is called port mapping.
  • -v mounts your local folders into the container so configuration and data persist between restarts.
  • docker.io/searxng/searxng:latest is the official SearXNG container image that Docker pulls from the registry.

Docker will download the SearXNG image (this may take a minute on first run) and then print a long container ID. That means your container is running.

Seeing a port conflict error?

If you see a message about port 8888 already being in use, another application is occupying that port. Close whatever is using it, or change -p 8888:8080 to a different host port like -p 9999:8080 and use that port in the rest of the project.

If you see a permissions error about the volume mounts, make sure Docker Desktop is running (check for the whale icon in your system tray).

help me fix a Docker port conflict or volume mount error

Test your search engine locally
  • Open your web browser.
  • Visit http://localhost:8888 in the address bar.
  • Type a search query (anything you like) and press Enter.

You should see the SearXNG search interface load and return results pulled from multiple search engines.

Page not loading?

Make sure you typed http://localhost:8888 exactly. Using https (with an S) will not work because you have not set up SSL.

If the page still does not load, go back to PowerShell and run docker ps to check whether the container is still running. If the list is empty, the container may have crashed on startup. Run docker logs searxng to see what went wrong.

help me troubleshoot why my SearXNG container is not loading in the browser

Understand what is running

You now have a full search engine running inside a Docker container. Let's confirm it and understand what is happening under the hood.

  • View your running container by running:
docker ps

You should see a table with columns like CONTAINER ID, IMAGE, STATUS, PORTS, and NAMES. Your searxng container should appear with a status of Up and ports showing 0.0.0.0:8888->8080/tcp.

How does SearXNG work?

The container runs a full search engine on port 8080 internally. Your -p 8888:8080 flag maps that internal port to port 8888 on your Windows machine, so your browser can reach it.

When you type a search query, SearXNG sends that query to multiple search engines simultaneously (Google, Bing, DuckDuckGo, and more). It collects all the results, removes tracking elements, and presents them to you in a single clean interface.

Your search engine is running and returning results. Next, you'll customize it with your own name and security settings.

Customize Your Search Engine

Your search engine is running and returning results. But right now it still looks like a default SearXNG instance with no identity.

In this step, you will personalize your search engine by editing its configuration file. You will give it a custom name, add a security key, and configure privacy settings.

In this step, get ready to:
  • Stop the container and open the configuration file.
  • Replace the default settings with your personalized configuration.
  • Restart the container and verify your custom name appears.
Stop the container and open settings

Before you can edit the configuration, you need to stop the running container. SearXNG reads its settings file at startup, so changes only take effect after a restart.

  • Stop the SearXNG container by running this command in PowerShell:
docker stop searxng

What does this command do?

The docker stop command gracefully shuts down a running container. The container's data and configuration remain intact on disk.

  • Open the settings file in Notepad by running:
notepad C:\searxng\config\settings.yml

Notepad opens with the default settings.yml that SearXNG generated on first run.

Why does this file already exist?

When you started the container in the previous step, SearXNG detected an empty config directory and generated a default settings.yml automatically. You will now replace its contents with your own configuration.

Personalize your search engine

Rather than editing individual lines in the auto-generated file (which can have unpredictable formatting), you will replace the entire contents with a clean configuration.

  • Select all the text in Notepad by pressing Ctrl+A.
  • Delete the selected text by pressing Delete.
  • Paste the following configuration into the empty file:
# SearXNG settings

use_default_settings: true

general:
  debug: false
  instance_name: "MySearch"

search:
  safe_search: 0
  autocomplete: "duckduckgo"
  default_lang: "en"
  formats:
    - html

server:
  secret_key: "change-this-to-your-own-random-secret-key"
  limiter: true
  image_proxy: true
  method: "POST"

ui:
  default_theme: "simple"
  center_alignment: true
  • Replace the secret_key value with your own random string. Type at least 16 random characters between the quotes (for example, mash your keyboard).
  • Optionally, change instance_name from "MySearch" to any name you like.

What does this configuration do?

The use_default_settings: true line tells SearXNG to load its built-in defaults for all 280+ search engines, then apply your overrides on top. This keeps your file short.

The general section sets your search engine's display name. The search section enables DuckDuckGo-powered autocomplete suggestions and sets English as the default language.

The server section adds a secret key for internal cryptography, enables the rate limiter to slow down bots, proxies images for privacy, and uses POST requests so search queries stay out of URL logs.

The ui section centers the search results on screen and uses the simple theme.

What is the limiter?

The limiter is SearXNG's built-in bot detection feature. It rate-limits excessive requests to protect your instance from abuse.

It works best with a Valkey database, but since this is a personal instance, SearXNG will still run without one. You may see a warning in the container logs about Valkey. That is safe to ignore for local use.

  • Save the file by pressing Ctrl+S.
  • Close Notepad.

Notepad showing extra characters?

If you see strange characters or the file looks garbled, the auto-generated file may have been saved in a different encoding. Delete all the text, paste the configuration above fresh, and save again.

Make sure you have not accidentally added extra spaces before the key names. YAML is whitespace-sensitive. Each indentation level must be exactly two spaces.

help me fix my settings.yml file

✔️ Awesome, I've got everything!

Great. Make sure you have saved settings.yml before continuing.

ⓧ I'd like to double check the full code

Here is the complete settings.yml file. Your secret_key value will be different (your own random string).

# SearXNG settings

use_default_settings: true

general:
  debug: false
  instance_name: "MySearch"

search:
  safe_search: 0
  autocomplete: "duckduckgo"
  default_lang: "en"
  formats:
    - html

server:
  secret_key: "change-this-to-your-own-random-secret-key"
  limiter: true
  image_proxy: true
  method: "POST"

ui:
  default_theme: "simple"
  center_alignment: true
Restart with new settings
  • Start the container again by running:
docker start searxng
  • Wait about 5 seconds for SearXNG to read the new configuration and start up.
  • Open your web browser and visit http://localhost:8888.
  • Look at the browser tab title and the page header. You should see your custom instance name (e.g. "MySearch") instead of the default "SearXNG".
  • Try a search query to confirm results still come back.

Still seeing the default name?

Make sure you saved the file before restarting the container. If Notepad is still open with unsaved changes, save it now, then run docker stop searxng followed by docker start searxng.

If the page does not load at all, check that the container is running by typing docker ps in PowerShell. If the container is not listed, your YAML file may have a syntax error. Re-open it and check for mismatched quotes or incorrect indentation.

help me troubleshoot my SearXNG container not starting

Your search engine now has a unique identity. Next up, you will expose it to the public internet so anyone can use it.

Go Live on the Internet

Your search engine is running and customized, but right now only you can use it. Anyone else trying to reach http://localhost:8888 from their own device would hit a dead end.

To make your search engine accessible to anyone on the internet, you need a tunnel that connects your local machine to a public URL. Cloudflare Quick Tunnel does exactly this in a single command, with no account required.

In this step, get ready to:
  • Create a public tunnel that exposes your local search engine to the internet.
  • Verify your search engine is accessible from any device using the public URL.
Create a public tunnel

A tunnel creates a secure connection between your computer and Cloudflare's network. When someone visits the public URL, Cloudflare forwards their request through the tunnel to your local search engine and sends the response back.

  • In your PowerShell window, navigate to your cloudflared folder by running this command:
cd C:\cloudflared
  • Start a Quick Tunnel pointing to your search engine by running:
.\cloudflared.exe tunnel --url http://localhost:8888

What does this command do?

The tunnel --url flag tells cloudflared to create a Quick Tunnel. It connects to Cloudflare's network and registers a random public subdomain on trycloudflare.com that forwards traffic to http://localhost:8888 on your machine.

No Cloudflare account is needed. The tunnel is free and runs for as long as your terminal session stays open.

After a few seconds, cloudflared prints several lines of log output. Look for a line containing a URL that ends in .trycloudflare.com.

  • Find and copy the full https:// URL from the terminal output (it looks like https://random-words.trycloudflare.com).

Not seeing a URL?

Make sure your SearXNG container is still running. In a separate PowerShell window, run docker ps and confirm searxng appears in the list.

If the container stopped, run docker start searxng and try the cloudflared command again.

If you see a connection error, check that your firewall is not blocking outbound traffic on UDP port 7844.

Help me troubleshoot my cloudflared tunnel

Share your search engine with the world

Your search engine is now live on the public internet. Anyone with the URL can use it to search the web through your self-hosted engine.

  • Open a new browser tab (or an incognito window) and paste your trycloudflare.com URL.
  • Confirm that your custom search engine name appears in the page header and browser tab.
  • Try a search query to verify results come back from multiple sources.
  • Share the URL with a friend or open it on your phone to see it working from a completely different device.

Why use incognito or a different device?

Testing from localhost only proves that your machine can reach itself. An incognito window or different device proves the tunnel is routing public traffic correctly through Cloudflare's network to your local container.

Your tunnel is temporary

This URL is live only while cloudflared is running in your terminal. Closing the terminal window or pressing Ctrl+C stops the tunnel and takes your search engine offline.

Each time you restart cloudflared, it generates a new random URL. This is expected behavior for the free Quick Tunnel tier. There is also a 200 concurrent request limit.

Page not loading from another device?

Make sure you copied the full URL including https://. The URL is case-sensitive.

Check that your PowerShell window with cloudflared is still running. If you accidentally closed it, navigate back to C:\cloudflared and run the tunnel command again.

Help me fix my public tunnel URL

Secret mission

Add a Custom Theme and Engine Preferences

Your search engine works and it is live on the internet. Now take it further by switching your autocomplete provider and confirming your custom theme is deployed publicly. This challenge has you edit YAML configuration to fine-tune how your search engine behaves.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally, so there are no ongoing costs. The Cloudflare Quick Tunnel is free and requires no account.

Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • Docker Desktop (installed locally, free for personal use).
  • SearXNG Docker container and configuration files in C:\searxng\.
  • cloudflared executable in C:\cloudflared\.

Keep everything running

No action needed. Choose this if you are still actively building or want to keep your search engine ready to go.

  • Your SearXNG container is still running and accessible at http://localhost:8888.
  • You can get a new public URL anytime by re-running cloudflared.exe tunnel --url http://localhost:8888 from C:\cloudflared\.
  • Docker Desktop will continue running in the background. It uses some memory but no ongoing charges.

Pause - I'll come back to this later

Stop the container to free up memory. Your configuration files are preserved and no resources are consumed while stopped.

  • Stop the SearXNG container by running this in PowerShell:
docker stop searxng
  • Your settings in C:\searxng\config\settings.yml are preserved.
  • To restart later, open Docker Desktop and run docker start searxng in PowerShell.

Delete - I don't want to use this again

Remove all project resources and start fresh. This deletes your container, image, configuration, and the cloudflared executable.

  • Stop and remove the SearXNG container by running these commands in PowerShell:
docker stop searxng
docker rm searxng
  • Remove the SearXNG Docker image:
docker rmi searxng/searxng:latest
  • Delete the project folders:
Remove-Item -Recurse -Force C:\searxng\
Remove-Item -Recurse -Force C:\cloudflared\
  • To uninstall Docker Desktop, open Settings, then select Apps, then Apps & features.
  • Find Docker Desktop in the list and click Uninstall.

Nice Work!

Nice Work!

You just deployed your own search engine to the public internet. Anyone with your URL can now search the web through a service you built and configured yourself.

Here's what you learned:

  • Installed Docker Desktop and ran your first container on Windows, learning how port mapping connects containers to your local machine.
  • Deployed SearXNG, a metasearch engine that aggregates results from up to 280 search services, and customized it with your own name and security settings.
  • Exposed your local search engine to the public internet using Cloudflare Quick Tunnel, making it accessible to anyone with the URL.
  • Secret Mission: Configured a custom theme with centered alignment, swapped the autocomplete provider, and set language defaults through YAML configuration.

Ready to quiz yourself?