首页 / 资讯中心 / 文章详情

SearXNG部署实战:基于Ubuntu与Docker搭建隐私友好元搜索引擎

SearXNG部署实战:基于Ubuntu与Docker搭建隐私友好元搜索引擎 ★ FEATURED ARTICLE
我最近把SearXNG部署到一台Ubuntu服务器上整个流程走下来踩了不少坑也积累了不少能直接复用的经验。SearXNG是一个开源的元搜索引擎它可以同时聚合Google、Bing等多家搜索引擎的结果在一个统一的搜索结果页面里展示同时不会保存你的搜索历史、IP地址和浏览器指纹信息从源头减少针对个人的数据收集和追踪画像。这篇博文面向有一定Linux基础、想搭建一个干净搜索入口的开发者或运维同学我会从方案选型讲到Docker部署再到Nginx反向代理和HTTPS证书配置最后把常见问题排查一并整理出来照着操作基本能把一个可用的搜索服务搭起来。1. 项目概述与部署思路1.1 SearXNG解决什么问题先说一个很现实的场景。日常用搜索引擎时我们搜索什么关键词、几点搜的、从哪个网络段来的、停留了多久这些行为数据大多会被记录和分析。时间一长你会发现广告越来越“懂你”搜索结果也越来越被个人兴趣过滤。这种体验表面上是便利本质上是把自己的搜索轨迹交给了第三方平台。SearXNG的核心逻辑是用“聚合”代替“直达”。你输入一个关键词它并行请求多个上游搜索引擎把抓回来的结果重新整理成一个干净页面。由于请求是从你自己的服务器发出的最终用户和上游搜索引擎之间隔了一层用户的真实IP不会直接暴露给上游网站同时SearXNG默认不写持久化的搜索日志访问记录只停留在内存层面。这就是它作为“隐私友好元搜索”的真正价值不替你保管隐私数据而是干脆不收集。从使用体验上讲自托管SearXNG最大的好处是可控。默认主题干净无广告搜索结果支持按类别切换通用、图片、视频、新闻、学术还提供了JSON格式的API端口方便接入自动化脚本或做成浏览器默认搜索。部署在自己服务器上意味着搜索前缀、页面主题、启用的上游引擎、限流策略都由你说了算不依赖任何第三方托管方的调度。1.2 为什么选择Ubuntu Docker部署方式我对比过两条路线原生Python环境安装和Docker容器化。原生安装需要手动管理Python版本、依赖库、uwsgi进程、静态文件和系统服务升级时依赖文件容易散落各处回滚也没有干净的操作粒度。Docker方案把SearXNG主程序、依赖和运行环境打包成一个镜像宿主机只需要装好Docker和Compose插件配置文件用volume挂载出来升级镜像版本基本等于拉一个tag再重建容器。Ubuntu作为宿主系统是我的首选原因很朴素社区资料多、apt源稳定、内核版本足够新对Docker和OverlayFS的支持成熟。我用的版本是Ubuntu 22.04 LTSDocker采用官方apt源安装而非系统自带的snap版这样Compose插件的兼容性更好。如果你手头是Debian系或Ubuntu 20.04下面步骤同样适用只是包名和源地址需要稍微调整。部署架构上我只跑两个容器一个是SearXNG本体另一个是Redis。Redis在这里的职责不是缓存搜索结果——SearXNG的限流器依赖Redis保存客户端访问计数如果没有Redislimiter功能默认无法正常工作。Nginx则直接装在宿主机上作为入口反向代理负责结束HTTPS连接并把流量转发给SearXNG容器。2. 环境准备与依赖安装2.1 基础系统配置部署前先确认三件基础事情服务器能公网访问、防火墙放行了需要的端口、系统时间正确。时间不同步会导致后面申请HTTPS证书时签名校验失败这个坑很多新手遇到过建议一上来就执行一遍timedatectl set-ntp true并确认输出没有异常。然后更新系统软件包sudo apt update sudo apt upgrade -y服务器内存方面SearXNG空载时占用大约150MB到250MB加上Redis和Nginx512MB内存的小机器也能运行。但如果上游引擎并发拉取频繁内存会往上跳1GB内存体验更从容。磁盘空间不需要焦虑镜像加配置文件不超过1GB。防火墙规则建议只在初期开放SSH和HTTP/HTTPS端口SearXNG的8080端口不需要对外暴露因为所有外部流量都走Nginx。2.2 安装Docker与Compose插件我用官方源安装Docker相比Ubuntu自带的snap版本官方源更新及时不会出现容器运行时的兼容怪问题。先配置GPG密钥和apt源sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null然后安装sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y这里我直接用docker-compose-plugin而不是单独安装docker-compose原因是Compose v2是Docker官方维护的命令行插件语法和兼容性更好。验证安装sudo docker version sudo docker compose version为了让当前用户免sudo执行docker命令把用户加入docker组sudo usermod -aG docker $USER newgrp docker提示加入docker组后需要重新登录会话才生效否则后续docker命令依然会提示权限不足。我习惯重新SSH登录一次避免在同一个会话里反复折腾。3. SearXNG的Docker部署实践3.1 目录结构与docker-compose.yml我习惯把容器编排文件放在一个独立的目录下方便后续备份和迁移。这里用/opt/searxngsudo mkdir -p /opt/searxng sudo mkdir -p /opt/searxng/searxng sudo chown -R $USER:$USER /opt/searxng目录里的searxng子目录用于挂载SearXNG的配置文件和静态主题数据。创建一个docker-compose.ymlservices: searxng: image: searxng/searxng:latest container_name: searxng restart: unless-stopped ports: - 127.0.0.1:8080:8080 volumes: - ./searxng:/etc/searxng environment: - SEARXNG_BASE_URLhttps://search.example.com - SEARXNG_SECRET_KEY请替换为随机字符串 depends_on: - redis cap_drop: - ALL cap_add: - CHOWN - SETGID - SETUID - DAC_OVERRIDE healthcheck: test: [CMD, python3, -c, import urllib.request; urllib.request.urlopen(http://localhost:8080)] interval: 30s timeout: 5s retries: 3 redis: image: redis:alpine container_name: searxng-redis restart: unless-stopped volumes: - ./redis-data:/data command: redis-server --save 60 1 --loglevel warning这个compose文件有几点值得说明。端口监听在127.0.0.1:8080而不是0.0.0.0这是刻意为之所有外部请求都由宿主机Nginx转发SearXNG不需要对公网暴露端口减少攻击面。cap_drop: ALL再按需添加少量Linux capabilities属于容器加固的常规操作让容器内的进程只有必要权限。Redis容器加了一条--save 60 1的持久化配置虽然SearXNG的限流数据丢失也无伤大雅但60秒一次的快照能让重启后的计数不至于完全从零开始。启动之前需要拉取镜像并生成secret key。secret key是SearXNG签名会话和内部数据的密钥一定不能使用默认值否则会有会话伪造风险。生成方法很多我用的是openssl rand -hex 32把输出结果填到compose文件里的SEARXNG_SECRET_KEY环境变量中。如果不想写在compose文件里也可以把密钥写进settings.yml的server.secret_key字段但compose环境变量优先级更高两者二选一即可。3.2 settings.yml核心参数解析第一次启动前SearXNG容器如果发现挂载目录里没有配置文件会自动生成默认的settings.yml。但自动生成的配置不一定适合你的场景我建议启动一次生成默认文件后就停掉容器然后手动修改配置cd /opt/searxng docker compose up -d docker compose stop searxng这时./searxng目录里已经出现了默认的settings.yml和uwsgi.ini。用编辑器打开settings.yml我主要调整这几个地方。搜索类别和结果显示search: safe_search: 0 autocomplete: default_lang: zh-CNsafe_search控制SafeSearch等级0为关闭1为中等2为严格。这个按你的实际需求设定。默认语言设为zh-CN搜索结果页会优先给出中文环境排序当然这个也可以在页面右上角手动切换。启用的搜索引擎engines: - name: google engine: google shortcut: g disabled: false - name: bing engine: bing shortcut: b disabled: falseSearXNG默认的引擎列表很长很多小众引擎默认是打开的但实际响应速度不稳定。我建议只保留几个自己常用的主流引擎一是减少请求并发、降低源站风控概率二是页面结果更可控。每个搜索引擎还能设置weight参数权重越高在最终排序中的影响越大。限流器配置server: limiter: true redis_url: redis://redis:6379/0limiter: true开启请求频率限制这时必须配置redis_url因为SearXNG的限流计数依赖Redis。没有Redis的情况下开启limiter会导致每次搜索都变429错误。隐私相关配置默认值已经比较安全我基本不动server: public_instance: false outgoing: request_timeout: 5.0 pool_connections: 100 pool_maxsize: 20public_instance保持false这意味着不会在页面footer显示“公共实例”标识也避免搜索引擎目录把自己注册为公共实例。outgoing.request_timeout控制在5秒防止某个上游引擎卡住整个搜索流程。3.3 启动并验证服务修改完配置后正式启动cd /opt/searxng docker compose up -d docker compose ps如果容器状态是running先验证容器内部服务是否正常curl -I http://127.0.0.1:8080正常情况会返回HTTP 200。如果返回502或连接失败先看容器日志docker logs searxng --tail 50我遇到过一次启动失败原因是手动改settings.yml时把server.secret_key字段写成了带空格的特殊字符导致签名校验报错。启动日志会直接打印ValueError: invalid secret_key之类的情况排查起来很快。此时直接访问http://服务器IP:8080是不通的因为我们把端口绑在127.0.0.1上。这一步的是安全的先用本机curl确认服务无异常再进入下一步Nginx配置。4. Nginx反向代理与HTTPS配置4.1 安装并配置Nginx如果服务器还没有Nginx直接安装sudo apt install nginx -y我的站点配置如下放在/etc/nginx/sites-available/searxng并软链接到sites-enabledsudo tee /etc/nginx/sites-available/searxng /dev/null EOF server { listen 80; 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; } } EOF sudo ln -s /etc/nginx/sites-available/searxng /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginxproxy_set_header这几行不是随便抄的。SearXNG的X-Forwarded-For能帮助它识别真实客户端IP配合限流器使用如果漏配所有请求都会被当作来自同一个来源要么全部放行要么全部限流限流功能等于白开。配置好之后把域名解析指向服务器IP然后访问http://search.example.com能正常看到搜索界面就算通了。如果页面样式加载不出来十有八九是Nginx没转发静态资源路径检查location是不是只写了/而不是某些特定规则。4.2 用certbot申请HTTPS证书HTTP部署只适合内网测试公网搜索服务必须套HTTPS否则搜索词在链路里明文传输跟SearXNG的隐私定位自相矛盾。我用certbot申请Let‘s Encrypt证书sudo apt install certbot python3-certbot-nginx -y sudo certbot --nginx -d search.example.com --redirect--redirect参数让certbot自动把HTTP请求301跳转到HTTPS同时修改Nginx配置并重载服务。整个过程会询问邮件地址用于证书过期提醒。Let’s Encrypt证书有效期90天certbot会自动配置定时续期任务不需要手动操作。证书申请完成后修改Nginx站点配置把HTTPS相关的参数补上。实际上certbot已经帮我们写好了一大半只需要确认proxy_pass部分没有被破坏sudo vi /etc/nginx/sites-available/searxng验证证书续期任务存在sudo certbot renew --dry-run注意如果服务器时间漂移超过几分钟证书申请的DNS验证会失败报错通常类似Timeout during CA issue。先同步时间再重试别反复删证书申请。4.3 更新SearXNG的base_urlHTTPS启用后需要让SearXNG对外生成的所有链接都基于HTTPS。compose文件里已经设置了SEARXNG_BASE_URL但如果你没设过需要在settings.yml里修改server: base_url: https://search.example.com/修改后重建容器cd /opt/searxng docker compose up -d --force-recreate searxng这一步容易被忽略。不加base_url的话搜索结果页里的RSS链接、导出链接、开放搜索接口的URL可能仍以http://127.0.0.1:8080开头页面功能看着正常但点某些按钮会跳到不存在的地址。5. 常见问题与排查技巧实录5.1 搜索请求频繁返回429或超时这是自托管SearXNG最常见的症状。429可能是SearXNG自身的限流触发也可能是上游搜索引擎对数据中心IP的请求限制。前者表现为短时间内搜索几次就出现限流提示说明limiter阈值设置过低或Redis连接有问题。参考我的调整思路server: limiter: true limiter_ban_time: 86400如果你只是自己一个人用可以把limiter_ban_time调大同时把search.autocomplete关闭减少不必要的自动补全请求。实践中我发现自动补全请求是触发限流的高频来源每个关键词补全请求也会消耗配额。如果是上游引擎超时表现是搜索页面能打开但部分类别结果空白排查方法很直接在设置页面勾选某个引擎单独测试观察返回结果。数据中心IP段的确容易被部分搜索引擎降权应对策略是打开设置里的“并行请求”选项让SearXNG并行请求多个引擎而不是逐个等待并把可用引擎数量控制在合理范围。5.2 容器频繁重启容器状态循环出现restarting通常有两种可能配置文件语法错误、健康检查失败。先停掉容器再用前台模式运行一次cd /opt/searxng docker compose stop searxng docker compose run --rm searxng前台运行能把启动时的报错完整打印到终端。如果日志没有输出但容器直接退出检查宿主机可用内存用free -h看内存是否耗尽。我在一台512MB的小机器上遇到过OOM killer把容器直接干掉的情况最终把Redis和SearXNG都加了mem_limit并关闭了不必要的引擎才稳定下来。5.3 升级版本后配置失效SearXNG迭代速度比较快偶尔大版本升级会调整settings.yml的字段结构。我的习惯是升级前先备份cp -r /opt/searxng/searxng /opt/searxng/searxng.bak.$(date %Y%m%d)然后拉取新镜像cd /opt/searxng docker compose pull searxng docker compose up -d --force-recreate searxng如果启动后搜索报错先对照新镜像内默认模板检查配置项。快速对比方式是把新镜像的默认配置提取出来docker run --rm -it searxng/searxng:latest cat /etc/searxng/settings.yml /tmp/settings_new.yml和当前配置做diff不认识的字段优先删掉。实际升级时遇到过server.default_http_headers字段被拆成多个独立字段的变更旧的写法不会报错但新功能不生效类似这种问题都要靠对比默认配置发现。5.4 常见问题速查表症状可能原因处理办法首页打开502Nginx没启动或proxy_pass写错检查nginx -t和 systemctl status nginx搜索后无结果上游引擎风控或超时设置页切换引擎减少同时启用的引擎数量页面样式全乱Nginx未正确转发静态资源确认location /包含所有静态路径429限流过于灵敏Redis未配置或阈值太小检查redis连接调大限流窗口或拉长ban时间搜索历史被记录下来未禁用持久化日志确认settings.yml中server.log_level为 warn内网访问正常外网不通防火墙未放行443端口放行UFW或云安全组443端口6. 维护与扩展建议SearXNG跑起来之后常规维护动作其实不多主要就是镜像升级、配置文件备份和日志清理。镜像升级建议一个月看一次release公告没必要追最新但安全修复版本要跟紧。备份方面/opt/searxng整个目录定期打包扔到对象存储或用rsync同步到另一台机器恢复时只要原目录放回去、重新起容器即可。个人使用体验中有几个细节值得进一步优化。一是把SearXNG接入浏览器默认搜索引擎以手动添加搜索引擎的方式把地址指向https://search.example.com/search?q%s日常搜索框地址一输就能用。二是配置页里的外观选项支持自定义CSS把结果字体、页面宽度、暗色主题调成自己喜欢的样子减少默认搜索页在视觉上的“工具感”。三是有开发需求的话SearXNG的搜索接口支持formatjson参数比如请求https://search.example.com/search?qtestformatjson会返回结构化JSON写自动化查询脚本或做信息聚合非常顺手。真正让我觉得这个部署值回票价的是每天高频搜索产生的查询词、点击行为、停留时长全部留在自己的控制范围内没有多一层第三方平台在做数据沉淀。每次打开搜索页页面干净、没有个性化推荐噪音搜索结果排序也相对中性找回了一点早期互联网的秩序感。部署过程其实没有太高门槛一台低配云主机加一个域名就能搞定花一个下午把配置调顺后后面基本是长期安静的运行状态。
阅读完成 · 觉得有帮助?
咨询建站