install_searxng.sh
bash
#!/bin/bash
# ============================================================
# SearXNG 物理机安装脚本(不用 Docker,源码 + venv)
# 适用:TencentOS / CentOS,已装 Python3
# 装到:/data/app/searxng
# 端口:8888(可在 settings.yml 改)
# ============================================================
set -e
# -------- 可按需修改的变量 --------
INSTALL_DIR="/data/app/searxng" # 安装根目录
SRC_DIR="$INSTALL_DIR/searxng-src" # 源码目录
VENV_DIR="$INSTALL_DIR/venv" # 虚拟环境
CONF_DIR="$INSTALL_DIR/conf" # 配置目录(settings.yml 放这)
PIP_MIRROR="https://mirrors.tencent.com/pypi/simple/"
# ----------------------------------
echo "==> [1/7] 安装系统依赖(编译 lxml 等需要)"
yum install -y git gcc gcc-c++ make \
libxml2-devel libxslt-devel zlib-devel \
python3-devel openssl-devel libffi-devel || {
echo "!! yum 装依赖失败,若已装可忽略,继续..."; }
echo "==> [2/7] 创建目录"
mkdir -p "$INSTALL_DIR" "$CONF_DIR"
echo "==> [3/7] 拉取 SearXNG 源码"
if [ -d "$SRC_DIR/.git" ]; then
echo " 源码已存在,git pull 更新"
cd "$SRC_DIR" && git pull
else
git clone https://github.com/searxng/searxng.git "$SRC_DIR"
fi
echo "==> [4/7] 创建 venv"
if [ ! -d "$VENV_DIR" ]; then
python3 -m venv "$VENV_DIR"
fi
"$VENV_DIR/bin/pip" install -U pip setuptools wheel -i "$PIP_MIRROR"
echo "==> [5/7] 安装 SearXNG 运行依赖"
cd "$SRC_DIR"
# 注意:不用 pip install -e .(那会触发 setup.py import searx,
# 而 searx/__init__.py 加载时需要 yaml/msgspec 等一堆依赖,导致连环报缺模块)。
# 正确做法:只装 requirements.txt 里的运行依赖,然后从源码目录用
# `python -m searx.webapp` 直接启动即可,无需把 searxng 装成 pip 包。
if [ -f "$SRC_DIR/requirements.txt" ]; then
"$VENV_DIR/bin/pip" install -r "$SRC_DIR/requirements.txt" -i "$PIP_MIRROR"
else
echo "!! 未找到 requirements.txt,请检查源码是否完整"; exit 1
fi
echo "==> [6/7] 生成/检查 settings.yml"
if [ ! -f "$CONF_DIR/settings.yml" ]; then
# 如果同目录带了模板就用模板,否则生成一个最小配置
if [ -f "$INSTALL_DIR/settings.yml" ]; then
cp "$INSTALL_DIR/settings.yml" "$CONF_DIR/settings.yml"
else
SECRET=$(openssl rand -hex 32)
cat > "$CONF_DIR/settings.yml" <<EOF
use_default_settings: true
server:
bind_address: "127.0.0.1"
port: 8888
secret_key: "$SECRET"
limiter: false
image_proxy: true
search:
formats:
- html
- json
default_lang: "zh-CN"
EOF
fi
echo " 已生成 $CONF_DIR/settings.yml"
else
echo " settings.yml 已存在,跳过"
fi
echo "==> [7/7] 完成!"
echo ""
echo "手动前台测试启动:"
echo " export SEARXNG_SETTINGS_PATH=$CONF_DIR/settings.yml"
echo " $VENV_DIR/bin/python -m searx.webapp"
echo ""
echo "验证 JSON 接口:"
echo " curl 'http://127.0.0.1:8888/search?q=test&format=json'"
echo ""
echo "正式部署用 systemd(见 searxng.service 和 README)"
searxng.service
bash
[Unit]
Description=SearXNG Search Engine (physical machine)
After=network.target
[Service]
Type=simple
# SearXNG 源码目录
WorkingDirectory=/data/app/searxng/searxng-src
# 指向你的配置文件
Environment=SEARXNG_SETTINGS_PATH=/data/app/searxng/conf/settings.yml
# 如果出网要走代理,取消下面两行注释并填写
# Environment=HTTP_PROXY=http://your-proxy:port
# Environment=HTTPS_PROXY=http://your-proxy:port
# 用 venv 里的 python 启动内置 webapp
ExecStart=/data/app/searxng/venv/bin/python -m searx.webapp
Restart=always
RestartSec=5
# 简单起见用 root 跑;讲究点可建专用用户再改 User=
User=root
[Install]
WantedBy=multi-user.target
settings.yml
bash
# SearXNG 配置(物理机版)
# 放在 /data/app/searxng/conf/settings.yml
# 启动时通过环境变量 SEARXNG_SETTINGS_PATH 指向本文件
#use_default_settings: true
# SearXNG 配置(物理机版)
# 放在 /data/app/searxng/conf/settings.yml
use_default_settings:
# 【关键】只保留这 3 个引擎,其余默认引擎全部禁用
engines:
keep_only:
- duckduckgo
- startpage
- wikipedia
server:
# 监听地址:只给本机网关调用,绑 127.0.0.1 更安全
# 若想浏览器从外网直接访问,改成 "0.0.0.0"(注意防火墙)
bind_address: "127.0.0.1"
port: 8888
# 一定改成你自己的随机串:openssl rand -hex 32
secret_key: "please_change_me_run_openssl_rand_hex_32"
# 程序高频调用,关掉单IP限流;内网自用建议 false
limiter: false
image_proxy: true
search:
# 【重点】必须开 json,否则 ?format=json 返回 403
formats:
- html
- json
default_lang: "zh-CN"
# 可选:如需走出网代理,取消注释
# outgoing:
# proxies:
# all://:
# - http://your-proxy:port
部署流程
如果执行脚本报错,就直接执行下面,在运行服务就行
bash
cd /data/app/searxng/searxng-src
/data/app/searxng/venv/bin/pip install -r requirements.txt -i https://mirrors.tencent.com/pypi/simple/
SearXNG 物理机部署(不用 Docker)全流程
源码 + venv 直接跑,SearXNG 官方支持的方式。适合已有 Python 环境的机器。
安装位置:/data/app/searxng 端口:8888(只绑 127.0.0.1,给本机网关调用)
一、传文件到服务器
把这 4 个文件传到服务器 /data/app/searxng-standalone/(临时放,脚本会把东西装到 /data/app/searxng):
install_searxng.sh # 一键安装脚本
settings.yml # 配置模板
searxng.service # systemd 服务
README.md # 本文件
二、一键安装(脚本全干完)
bash
cd /data/app/searxng-standalone
chmod +x install_searxng.sh
./install_searxng.sh
脚本会依次做:
- yum 装编译依赖(gcc、libxml2-devel 等,装 lxml 要用);
- 建目录
/data/app/searxng; - git 拉 SearXNG 源码到
searxng-src/; - 建 venv;
pip install -r requirements.txt只装运行依赖(不用 pip install -e .,见下方说明);- 生成
conf/settings.yml(自动填随机 secret_key); - 打印测试启动命令。
为什么不用
pip install -e .:SearXNG 的 setup.py 构建时会 import searx,而 searx 初始化时要加载 yaml/msgspec 等依赖,导致"缺 msgspec / 缺 yaml"连环报错。其实根本不用装成包------装好依赖后,从源码目录直接python -m searx.webapp就能跑(searx 包就在当前目录)。
若第 1 步 yum 报错(比如某包名不同),大多不影响,只要系统里已有 gcc/libxml2 即可,继续往下。
三、把配置模板放到位(可选)
脚本会自动生成一份 settings.yml。如果你想用我给的模板(注释更全),在跑脚本前先复制:
bash
cp /data/app/searxng-standalone/settings.yml /data/app/searxng/settings.yml
(脚本检测到 /data/app/searxng/settings.yml 会优先用它)
记得改 secret_key:
bash
openssl rand -hex 32 # 复制输出
# 编辑 /data/app/searxng/conf/settings.yml,把 secret_key 换成上面的串
四、前台测试启动
先手动跑一下,确认能起、能搜:
bash
export SEARXNG_SETTINGS_PATH=/data/app/searxng/conf/settings.yml
/data/app/searxng/venv/bin/python -m searx.webapp
看到类似 INFO ... Listening on http://127.0.0.1:8888 就是起来了。
另开一个终端验证 JSON 接口(网关要用的就是这个):
bash
curl "http://127.0.0.1:8888/search?q=Big+Buck+Bunny&format=json" | head -c 500
返回带 results 的 JSON = 成功。
- 返回 403 → settings.yml 里
formats没加json,或改完没重启; - 返回空 results → 可能出网被挡,检查服务器能不能访问 google/bing。
测好后 Ctrl+C 停掉,进入正式部署。
五、装成 systemd 服务(开机自启、常驻)
bash
cp /data/app/searxng-standalone/searxng.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now searxng
systemctl status searxng # 看到 active (running) 即 OK
常用命令:
bash
systemctl restart searxng # 改了 settings.yml 后重启
systemctl stop searxng
journalctl -u searxng -f # 看实时日志
六、接到你的 LLM 网关
SearXNG 跑通后,网关把搜索源从 ddgs 换成调它的 JSON 接口即可。核心就一个 GET:
python
import httpx
def searxng_search(query, top_k=5):
r = httpx.get("http://127.0.0.1:8888/search",
params={"q": query, "format": "json", "language": "zh-CN"},
timeout=10)
results = r.json().get("results", [])[:top_k]
# 结构和 ddgs 对齐:title / href / body
return [{"title": x.get("title"), "href": x.get("url"),
"body": x.get("content", "")} for x in results]
告诉我一声,我帮你把网关 main.py 改成"SearXNG 优先、ddgs 兜底",模型调用方完全无感。
七、常见坑速查
| 现象 | 原因 / 解决 |
|---|---|
| pip 装 lxml 编译报错 | 缺 libxml2-devel libxslt-devel gcc python3-devel,yum 补装 |
pip install -e . 报缺 msgspec/yaml |
别用 -e .,改用 pip install -r requirements.txt 装依赖,然后 python -m searx.webapp 直接跑 |
?format=json 返回 403 |
settings.yml 没开 formats: [html, json],改完 restart |
| 搜索 results 为空 | 服务器出网被挡;或搜索引擎被限,换引擎/加代理 |
| 启动报 secret_key 相关 | 没改 secret_key,用 openssl rand -hex 32 生成后填入 |
| 端口冲突 | 8888 被占,改 settings.yml 的 port + service 无需改 |