SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 已更新 2026-10-21

如何使用 Docker Compose 自架 SearXNG 搜尋引擎

透過 Docker Compose 在 VPS 部署 SearXNG。本文涵蓋 settings.yml 設定、Nginx TLS 反向代理配置,以及如何串接 JSON API 供指令碼或 AI 代理程式使用,無需額外付費或受限於 API 配額。

您正在建置的內容

自架 SearXNG 能讓您在自己的伺服器上運行私有搜尋引擎。SearXNG 是一個元搜尋引擎(metasearch engine):它接收您的查詢,向 Google、Bing、DuckDuckGo 與 Wikipedia 等其他引擎發送請求,並將回傳結果合併至單一頁面。由於只有您的機器會保留查詢紀錄,因此不會建立個人檔案,也不會設定任何追蹤 cookie。若您曾找到關於 Searx 的舊指南,請注意該專案已於 2023 年 9 月停止維護,當時其儲存庫已公告不再更新;儘管 2026 年 5 月曾有過一次文件更新提交,但並未改變其停止維護的狀態。因此,請在參考指南前先確認兩者的狀態。

此技術堆疊相當精簡,包含兩個容器、一個設定檔與一個反向代理。它能與其他服務共用小型 VPS,這點並非所有自架服務都能做到:例如在 PhotoPrism 與 Immich 的比較 中提到的相片庫,其記憶體需求取決於索引器而非網頁應用程式。您必須決定的關鍵在於執行個體是「私有」還是「公開」:私有代表僅限您本人與您的指令碼存取;公開則代表網際網路上的任何人皆可使用。此選擇會影響安全性設定,請在輸入任何指令前先做好決定。預設建議為私有。

運行此服務還有第二個理由。SearXNG 執行個體支援 JSON 格式,這意味著您撰寫的任何指令碼或 AI 代理程式都能擁有一個屬於自己的搜尋 API,無需金鑰、無需按次計費,也不會收到配額限制通知。

使用 Docker Compose 安裝 SearXNG

該專案發布了容器映像檔與 Compose 檔案。請將兩者下載至已安裝 Docker Engine 與 Compose 外掛程式的全新 Ubuntu 24.04 伺服器上。若您對 Docker 不熟悉,請先閱讀 Docker Compose 在 VPS 上的基礎應用,完成後再回來。

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

此 Compose 檔案定義了兩個服務。core 為 SearXNG 本身,valkey 則是記憶體資料儲存庫,用於速率限制與短期狀態儲存。它將 ./core-config/ 掛載至容器內的 /etc/searxng/,因此您所有的設定都會保留在主機上的該目錄中。

現在請編輯 .env。範例檔案中的每一行預設皆為註解,這就是為什麼容器啟動時會在所有位址的 8080 埠上監聽。請取消註解並設定以下三項。

SEARXNG_VERSION=latest
SEARXNG_HOST=127.0.0.1
SEARXNG_PORT=8080

SEARXNG_HOST=127.0.0.1 是關鍵設定。它將發布的埠號改為 127.0.0.1:8080:8080 而非原本的 8080:8080;由於 Docker 會在所有位址上發布埠號,此設定能確保容器僅在 loopback 位址回應,防止網際網路直接存取。若忽略此步驟,容器一啟動就會直接暴露,因為 Docker 發布的埠號會優先於您的防火牆規則。此陷阱值得詳閱:已發布的 Docker 埠號會繞過 ufw。

SEARXNG_VERSION=latest 在學習階段尚可使用。但在正式伺服器上,請務必鎖定版本標籤。截至 2026 年 10 月,發布標籤皆以日期命名,例如 2026.10.4-d48c4b555;鎖定版本後,您可自行決定升級時機,而非隨映像檔倉庫的變更而自動更新。此原則適用於伺服器上所有長期運行的服務,這也是為何 自架 RustDesk 中繼站 也會鎖定映像檔標籤的原因:遠端存取服務若在無人看管下自動升級,往往會在最糟糕的時刻發生故障。

settings.yml:關鍵設定

請在首次啟動前建立 core-config/settings.yml。use_default_settings: true 會指示 SearXNG 先載入內建預設值,再套用您自訂的鍵值,這能讓設定檔保持精簡,並確保在升級新增選項時不會發生衝突。

請先產生 secret,因為該數值會直接寫入檔案中。

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 用於簽署工作階段與權杖資料。預設值為字串 ultrasecretkey,若不修改,任何知曉此預設值的人皆可偽造權杖。請務必更換一次,之後便無須更動:若日後變更,所有已儲存的偏好設定將會失效。

base_url 必須設定為公開的 HTTPS 位址,並包含結尾斜線。這是 SearXNG 產生連結時所使用的位址。若維持指向 localhost,遠端瀏覽器中的「下一頁」連結將會指向使用者自己的機器,導致連線失敗。

formats 決定 Web 端點產生的輸出類型。json 不在預設清單中,因此若未加入,JSON 請求將會回傳 403 錯誤。image_proxy: true 會透過您的伺服器轉送結果縮圖,確保託管這些圖片的網站無法取得訪客的 IP 位址。

valkey.url 使用主機名稱 valkey,因為這是 Compose 檔案中的服務名稱;Compose 會將兩個容器置於同一網路中,使服務名稱可被解析。若將其指向 localhost,限制器將會失效,因為在 core 容器內部,localhost 指的是容器自身。

由於 secret 儲存於純文字檔案中,請務必保護該目錄。chmod 750 /opt/searxng 可防止其他主機使用者存取。您也可以將 core-config/settings.yml 的權限縮減為 600 而不會造成問題:官方容器的 entrypoint 會以 root 身分啟動,且在 FORCE_OWNERSHIP 維持預設值 true 的情況下,會在 SearXNG 啟動前將掛載的設定目錄交給容器內的 searxng 使用者,因此該檔案對其仍具備可讀性。此操作在主機端會產生副作用:該步驟會將 core-config/ 的擁有者變更為容器的使用者 ID,因此後續編輯檔案時請務必使用 sudo。

啟動堆疊並進行檢查。

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

docker compose ps 應顯示兩個容器皆處於 running 狀態。curl 應回應 HTTP/1.1 200 OK。若無任何回應,請閱讀 docker compose logs core,因為 settings.yml 中的 YAML 語法錯誤會以解析錯誤的形式顯示在該處,並標註錯誤行號。

透過 Nginx 進行 TLS 終止

容器僅監聽 loopback 介面,因此必須透過 Nginx 才能對外存取,同時由 Nginx 負責處理傳輸層安全(TLS)。請編寫 /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 會在重載前輸出 syntax is ok 與 test is successful。Certbot 會重寫該檔案,使其監聽 443 埠並套用憑證,同時加入從 80 埠的重新導向。search.example.com 的 DNS 紀錄必須已指向此伺服器,因為憑證授權單位會透過 HTTP 請求驗證檔案以確認所有權。包含續期在內的完整操作流程,請參閱 Ubuntu 24.04 的 Certbot 與 Nginx 設定指南。

這兩個轉發標頭並非裝飾。若缺少 X-Forwarded-For 與 X-Real-IP,所有抵達 SearXNG 的請求都會顯示為代理伺服器的位址,導致速率限制器誤判所有流量皆來自同一客戶端,進而無法區分不同訪客。

為什麼指令碼與代理程式需要 JSON 搜尋 API

透過 json 在 formats 中,同一個端點既能渲染頁面,也能回傳結構化資料。

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

您會收到一個包含 results 陣列的物件,其中每個項目都帶有 url、title、content 以及提供該結果的引擎,同時還包含 answers、infoboxes 與 suggestions。這些資訊足以提供給摘要工具、連結檢查器或研究迴圈使用。將這些結果交給語言模型處理的複雜度比表面看起來更高,因為搜尋結果屬於不可信的文字,可能夾帶指令,這正是 將 AI 代理指向您的 SearXNG 執行個體 一文詳細探討的內容。

這對於任何代理程式架構都至關重要。語言模型有訓練截止日期,因此需要即時搜尋來回答關於當下的問題,而商業搜尋 API 則會按查詢次數收費並嚴格限制速率。自架執行個體僅需佔用您既有伺服器上的一個容器,且查詢流量不會離開該伺服器。如果您正在將工具串接到模型中,同樣的邏輯也適用於 在 VPS 上執行 MCP 伺服器,其中搜尋工具通常是人們新增的第一個工具。

使用 API 時有兩項規則。請保持執行個體私有,將 API 端點綁定至 loopback 位址或私有網路,僅允許您自己的主機存取,這與 自架位置追蹤器 對手機回報位置的端點所採取的處理方式相同。接著,請溫和地進行查詢。SearXNG 會將您的請求轉發給真實的搜尋引擎,因此若指令碼每秒執行一百次查詢,等於是在要求 Google 封鎖您的伺服器。

限制器與公開實例的變更事項

限制器是 SearXNG 的機器人防禦機制。它會監控請求標頭、位址與請求速率,並丟棄看起來像是自動化的流量。此機制需要 Valkey 來保存狀態,這也是 Compose 檔案中包含該服務的原因。

若是私人實例,請保留 limiter: false。您的腳本本質上就是自動化流量,因此限制器會封鎖您建立該實例所要呼叫的 JSON。存取控制應由反向代理負責:在 nginx location 中設定 allow 與 deny 配對、使用 HTTP 基本驗證,或設定僅允許您其他伺服器存取的防火牆。如果您需要從經常更換網路的筆記型電腦存取私人實例,在前方設定 v3 onion 位址是第四種選擇,因為 Tor 會連線至相同的 loopback 埠,且不會向網際網路暴露任何新內容。

如果您要將實例公開給他人使用,請開啟這兩個開關。

server:
  limiter: true
  public_instance: true

更細緻的控制位於 core-config/limiter.toml,容器會讀取該檔案於 /etc/searxng/limiter.toml。您只需寫入想要變更的鍵值即可。若位於代理伺服器後方,您必須宣告該代理,否則限制器會將您的 nginx 位址視為唯一的濫用客戶端。

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

[botdetection.ip_limit]
link_token = true

link_token = true 會讓 SearXNG 發出僅有真實瀏覽器工作階段才會擷取的權杖,這能阻擋大多數簡單的爬蟲。請預期公開實例在幾天內就會吸引爬蟲。同時也請預期會出現引擎錯誤,因為您轉發的流量越多,上游引擎就越快開始對您的伺服器位址回傳 CAPTCHA。公開的 SearXNG 實例是一項持續性的維護工作。私人實例則不然,這也是為何它常出現在 2026 年值得自架的服務清單中的原因。這些清單上的項目並不全是基礎設施:將 Jellyfin 媒體庫重建為 90 年代風格的影音出租店,同樣是放在 nginx 區塊後方的容器,只是用途從工作流程轉變為休閒娛樂。

為什麼搜尋結果為空

請開啟您執行個體上的 /stats。該頁面會列出每個搜尋引擎的錯誤率與回應時間,當搜尋結果異常稀少時,這是您首要檢查的地方。

若引擎顯示「Access denied」或「CAPTCHA」錯誤,代表該引擎已封鎖您的伺服器位址。這在資料中心 IP 區段中相當常見,因為搜尋引擎會預設這些位址屬於爬蟲。SearXNG 隨後會暫停該失效引擎一段時間,而非持續重試,因此被封鎖的引擎會自動從您的搜尋結果中消失。您可以在 settings.yml 中停用該引擎,或接受搜尋結果減少的事實。這並非僅有的兩種處理方式,因為 部分 CAPTCHA 封鎖有重啟後依然有效的解決方案。其餘引擎仍會正常回應。429 錯誤則較為模糊,因為它可能來自您自身的限制器,也可能來自拒絕您伺服器連線的上游引擎;在變更設定前,日誌行會明確指出您目前遭遇的是哪一種情況。

若所有引擎同時失效,代表容器沒有正常的對外名稱解析功能,或是沒有連往網際網路的路由。請從容器內部進行測試。

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

當此檢查失敗時,伺服器本身不會發出任何通知,因此請透過 cron 執行檢查,並在失敗時 透過您自己的 ntfy 伺服器將警報推送到手機,無須等到發現搜尋結果變少才處理。

FAQ

SearXNG 能讓我的搜尋匿名嗎?

它會對搜尋引擎隱藏您的身分,因為引擎看到的是您的伺服器發出的請求,而非您的瀏覽器。但它不會對您的伺服器隱藏搜尋內容,也不會對搜尋引擎隱藏您的伺服器。在單人使用的實例中,來自該位址的所有流量皆屬於您,因此該位址本身即成為識別碼。您的瀏覽器與實例之間的流量受 TLS 憑證保護。至於這對您的 ISP、公開實例的營運商以及搜尋引擎本身意味著什麼,請參閱 SearXNG 實際隱藏的內容。

為什麼 JSON 請求會回傳 403 Forbidden?

原因有二,皆與設定有關。一是 json 未包含在 settings.yml 中 search: 下的 formats 清單內(這是預設狀態),二是限制器已開啟並將您的腳本判定為機器人。請先加入該格式,使用 docker compose restart core 重啟後再試。若仍失敗,請設定 limiter: false 並改由反向代理控制存取權限。

如果我關閉限制器,還需要 Valkey 容器嗎?

請讓它保持執行。SearXNG 在沒有它的情況下仍可運作,但若未執行該容器,日後將無法開啟限制器,且它還負責儲存其他短期狀態。該容器佔用空間極小且僅儲存快取資料,移除它節省的資源微乎其微,卻會讓您失去後續調整的彈性。

如何更新 SearXNG?

在 /opt/searxng 中執行 docker compose pull,接著執行 docker compose up -d。Compose 會重建映像檔已更新的容器,並保留您的 core-config/ 目錄,因此 settings.yml 不會遺失。由於 use_default_settings: true 會將您的金鑰與預設值合併,上游新增的選項會自動套用合理預設值,而不會導致檔案損毀。

多人可以共用同一個實例嗎?

可以,這種情況下您應開啟限制器並設定 public_instance: true。偏好設定儲存在每位訪客各自的瀏覽器中,因此無需管理帳號。開放存取後,請持續監控 /stats 一週,因為上游搜尋引擎在您察覺搜尋結果缺失之前,往往早已開始拒絕來自您伺服器的請求。

這篇文章對您有幫助嗎?