Files
HomeDash/nginx.conf
JianFeeeee 1d86e81d42 feat(extension): Firefox 包改为优先供给数据卷里的 AMO 已签名包
正式版 Firefox 要求扩展经 AMO 签名,未签名一律拒绝且报成「插件损坏」。
签名包不进镜像:它是 AMO 针对具体内容生成的产物,提交进仓库会与源码脱节
(改代码就得重新签名)且是二进制。放数据卷可跨部署存活,更新只覆盖一个文件。
数据卷没有时回落镜像内未签名包(开发/调试仍可用)。

实测三条路径(本地 nginx 沙箱,nginx -t + 真实请求):
  数据卷有签名包 → SIGNED;数据卷无 → 回落镜像内未签名包;两者都无 → 404。
注:用 root 而非 alias,因为 alias 配 try_files 会把 URI 再拼一次导致 404。
2026-10-03 08:19:17 +08:00

172 lines
7.0 KiB
Nginx Configuration File
Raw Permalink 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;
}
# Firefox 扩展包:优先用数据卷里的 **AMO 已签名包**。
# 为什么不直接把签名包打进镜像:签名是 AMO 针对具体内容生成的产物,
# 提交进仓库既会与源码版本脱节(改代码就得重新签名),又是二进制。
# 放进数据卷则能跨部署存活,需要更新时覆盖这一个文件即可。
# 数据卷里没有(还没签名/没上传)时回落到镜像内的未签名包。
# 这里用 root 而非 alias:alias 配 try_files 会把 URI 再拼一次,
# 实测容易 404。root=/app/data 时 $uri=/extension/navi-firefox.xpi
# 正好解析成 /app/data/extension/navi-firefox.xpi。
location = /extension/navi-firefox.xpi {
root /app/data;
try_files $uri @firefox_xpi_image;
}
location @firefox_xpi_image {
root /app/dashy;
try_files $uri =404;
}
# 容器健康检查(部署脚本与 Docker HEALTHCHECK 使用)
location = /healthz {
proxy_pass http://127.0.0.1:3005/healthz;
}
# Dashy SPA 路由兜底
location / {
try_files $uri $uri/ /index.html;
}
}
}