Files
HomeDash/nginx.conf
HomeDash Bot 994d93cc98 feat(gateway): 一体化统一入口——路由与 Dashy 导航同一份数据、内置登录、原自定义错误页
目标:一个 HomeDash 容器取代 navi + portal-nginx + portal-auth。

- Route 扩展为"反代 + 导航"一条记录:kind(proxy/portal/auth)、streaming、
  insecureTls、bypassPaths、injectBeian,以及 navEnabled/navSection/navName/
  navDescription/navUrl/navIcon/navAutoIcon
- 保存路由时**同时**写 gateway.yml 与 conf.yml 的导航项(gateway_nav.go):
  同 host 接管而不是重复、未勾选导航的会被清理、无关手工项与系统「历史访问」分组
  一律不动;两步任一步失败都回滚(避免后台显示与导航页各说各话)
- 未知域名与上游故障改用**内置自定义 404/500 页面**(portal/ 目录),
  不再是一行纯文本;HTTP→HTTPS 跳转段用 RedirectPort 复刻原 3081 设计
- 内置统一登录(auth.go):HMAC 签名 cookie、恒定时间比较、登录跳转白名单校验,
  portal-auth 容器可以退场
- 自动抓图标对托管导航项同样生效(history-server 识别 naviGatewayAutoIcon)
- 后台卡片补齐"加入导航/分组/名称/描述/图标/自动抓图标/服务类型"字段
- 内部入口端口 8080 → 18080:为一体化 host 模式让开宿主机 blog(:8080)
- 修掉上一轮编辑写坏的 deploy/zd.sh 一行(会让脚本直接失败)

测试:新增自定义错误页、portal 类型、导航字段校验、导航同步(接管/清理/保留)、
分组不存在必须报错等用例;admin-server 与 history-server 全绿。
2026-09-11 21:27:40 +08:00

154 lines
6.1 KiB
Nginx Configuration File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 1024;
}
http {
# 统一入口路由表(由管理后台生成):后台改完"哪个域名→哪个后端、是否走统一认证"
# 会写到这里并 nginx -s reload。默认监听旁路端口(见 gateway.yml 的 listenPort),
# 验证通过后再改成 80/443 接管正式入口。
include /app/data/gateway/*.conf;
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
client_max_body_size 0;
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
# HomeDash 内部入口固定 18080。选择这个端口是为了在 --network host
# 的一体化模式下避开宿主机现有的 blog(:8080) 等服务。
server {
listen 18080;
server_name _;
# 容器内部监听 18080,但对外由 gateway 的 3080/8443 终结 TLS。
# nginx 生成重定向时默认拼绝对地址 $scheme://$host:$server_port,
# 会把内部端口泄漏到公网(曾把 /admin 跳到 http://<域名>:8080/admin/),
# 而且 https 会被降级成 http。关掉绝对重定向,改用相对 Location。
absolute_redirect off;
port_in_redirect off;
# Dashy 静态文件
root /app/dashy;
index index.html;
# ===== SearXNG 反向代理 =====
# SearXNG 路由是 /search(无尾斜杠),/search/ 会 404,故 rewrite 去掉尾斜杠。
location ~ ^/search/?$ {
rewrite ^/search/?$ /search break;
proxy_pass http://127.0.0.1:8888;
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;
}
# SearXNG 静态资源(主题/前端脚本,页面上以 /static/... 绝对路径引用)
location /static/ {
proxy_pass http://127.0.0.1:8888;
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;
}
# 其他 SearXNG 页面/接口(结果页内的链接会引用这些根路径)
location ~ ^/(autocompleter|preferences|stats|about|donate|opensearch.xml|image_proxy|translations)/? {
proxy_pass http://127.0.0.1:8888;
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;
}
# History API(内部 3004)
location /api/history/ {
proxy_pass http://127.0.0.1:3004/;
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;
}
# Admin WebUI(内部 3005)
#
# 不带尾斜杠的 /admin 必须**直接返回页面**,不能靠重定向:
# 1) 它会落到 `location /` 的 try_files $uri/ 分支,nginx 自动补斜杠时按
# $host:$server_port 拼绝对地址,把内部端口 8080 泄到公网;
# 2) 即便改成相对重定向,301 会被浏览器**永久缓存**,用户改好后仍被旧跳转带走。
# 所以这里精确匹配并直接反代(尾斜杠由 proxy_pass 的 / 吸收)。
location = /admin {
proxy_pass http://127.0.0.1:3005/;
# 管理页不缓存:避免旧的跳转/旧页面被浏览器长期记住
add_header Cache-Control "no-store" always;
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;
}
location /admin/ {
proxy_pass http://127.0.0.1:3005/;
add_header Cache-Control "no-store" always;
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;
}
# conf.yml 由 nginx 直接提供(从 data volume 读取)
location = /conf.yml {
alias /app/data/conf.yml;
}
# 可选的扩展商店链接:部署方把 extension-store.json 放进 data 卷即可,
# /extension/install.html 会读取它并显示「一键安装」按钮。
location = /extension/store.json {
alias /app/data/extension-store.json;
add_header Cache-Control "no-store";
}
# item-icons 从 data volume 提供
# 用 302(不是 301):这两个目录不需要浏览器永久记住跳转。
location = /item-icons {
return 302 /item-icons/;
}
location /item-icons/ {
alias /app/data/item-icons/;
}
# 自定义壁纸(后台「外观」上传,目录也在 data 卷)
location = /wallpapers {
return 302 /wallpapers/;
}
location /wallpapers/ {
alias /app/data/wallpapers/;
add_header Cache-Control "public, max-age=31536000, immutable";
}
# 浏览器扩展安装目录:/extension 和 /extension/ 都直接给安装页,不靠重定向
location = /extension {
rewrite ^ /extension/install.html last;
}
location = /extension/ {
rewrite ^ /extension/install.html last;
}
# 容器健康检查(部署脚本与 Docker HEALTHCHECK 使用)
location = /healthz {
proxy_pass http://127.0.0.1:3005/healthz;
}
# Dashy SPA 路由兜底
location / {
try_files $uri $uri/ /index.html;
}
}
}