· Jeff · 教程  · 8 分钟阅读

FileBrowser 免登录图片直链:容器部署 + Notion 嵌入完整指南

想让 Notion 页面直接嵌入服务器上的图片,又不想把 FileBrowser 的管理登录暴露给所有人?核心思路不是 FileBrowser 自带功能,而是 nginx 层用 alias 把图片目录直接映射出来绕过认证。这篇是完整实战指南,含部署、直链、验证和排障。

想让 Notion 页面直接嵌入服务器上的图片,又不想把 FileBrowser 的管理登录暴露给所有人?核心思路不是 FileBrowser 自带功能,而是 nginx 层用 alias 把图片目录直接映射出来绕过认证。这篇是完整实战指南,含部署、直链、验证和排障。

FileBrowser 免登录图片直链:容器部署 + Notion 嵌入完整指南

用 Notion 做知识库的朋友多半踩过这个坑:想往页面里嵌一张自己服务器上的图片,但 Notion 采集图片需要一个无需登录就能直接访问的图片 URL。FileBrowser 默认所有访问都要登录,直接把登录页面丢给采集器显然不行。

这篇文章分享我实际跑通的方案:Docker 部署 FileBrowser 做文件管理 + nginx 层开放 /static/ 免登录直链,让 Notion 无需任何账号密码就能嵌入图片,同时 FileBrowser 管理后台依然安全锁在登录后面。

适用:Notion 重度用户 / 自建图床 / 站长 | 更新:2026-08-29


一、核心机制:免登录不是 FileBrowser 的功能

先澄清一个误区:免登录直链并不是 FileBrowser 自带的能力,而是 nginx 层用 alias 直接把图片目录映射出来,绕过 FileBrowser 的认证。

整条链路长这样:

Notion 页面
   │ 嵌入 https://files.example.com/static/<图片名>.jpg

CDN (缓存静态文件)

Nginx (443 SSL)
   ├── location /static/  → alias /data/images/   ← 免登录直链(本次重点)
   └── location /         → proxy_pass 127.0.0.1:8080   ← FileBrowser 页面(需登录)

Docker filebrowser 容器 (8080, 仅本机可访问)

关键点:直链走的是 nginx 直接读磁盘,完全不经过 FileBrowser 的 8080 端口,所以绕过了认证;而 FileBrowser 页面本身仍走反代、仍需登录。两者互不干扰。


二、FileBrowser 容器部署

Docker 部署

docker run -d \
  --name filebrowser \
  --restart unless-stopped \
  -p 8080:80 \
  -v /data/images:/srv \
  -v /data/filebrowser-db:/database \
  -v filebrowser-config:/config \
  -e UID=1000 \
  -e GID=1000 \
  filebrowser/filebrowser:v2.63.14

三个关键挂载:

宿主机容器内用途
/data/images/srv图片/文件根目录(直链映射的就是这里)
/data/filebrowser-db/databaseSQLite 数据库(用户、权限)
filebrowser-config/configsettings.json 配置

settings.json(容器内 /config/settings.json

{
  "port": 80,
  "baseURL": "",
  "address": "",
  "log": "stdout",
  "database": "/database/filebrowser.db",
  "root": "/srv"
}

root: /srv 表示 FileBrowser 管理的就是图片目录,与直链目录一致,管理后台看到的内容和直链吐出的文件是同一份。

⚠️ 端口安全:8080 必须封死外网

容器端口经 docker-proxy 默认监听 0.0.0.0:8080外网直连 8080 就等于把 FileBrowser 登录页暴露到公网。用 DOCKER-USER 链把外网访问 DROP 掉,只允许本机 nginx 反代访问:

iptables -I DOCKER-USER 1 -p tcp --dport 8080 -j DROP
iptables-save > /etc/iptables/rules.v4   # 持久化

实测效果:外网无法直连 8080,只能走 nginx 443 反代;而免登录直链走 nginx alias 直读磁盘、不经过 8080,不受这条限制,两条路各走各的。


三、nginx 反代配置(免登录直链核心)

1. 主反代:FileBrowser 页面(需登录)

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 Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_http_version 1.1;
}

2. ⭐ 免登录直链:Notion 嵌入的核心

新建一个独立的 location 配置(比如 static.conf):

# 公开静态文件服务(无需认证),用于 Notion 图片嵌入
# 优先从本地磁盘服务,文件不存在时回退到 FileBrowser 后端
location /static/ {
    alias /data/images/;
    expires 30d;
    add_header Cache-Control "public, immutable";
    add_header Access-Control-Allow-Origin "*";
    try_files $uri @filebrowser;
}

# 回退到 FileBrowser 后端
location @filebrowser {
    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;
}

每一行的作用:

配置项作用
location /static/前缀匹配直链路径统一带 /static/ 前缀
alias /data/images/本地磁盘映射绕过 FileBrowser 认证,nginx 直接吐文件
expires 30d + public, immutable长缓存图片不变,浏览器/CDN 强缓存
Access-Control-Allow-Origin "*"CORS 全开Notion 嵌入必须,否则浏览器跨域拦截
try_files $uri @filebrowser回退文件不存在时交给 FileBrowser(服务其自身 JS/CSS)

3. 生效

nginx -t && nginx -s reload

四、使用与验证

免登录直链 URL

https://files.example.com/static/<文件名>.jpg

三条验证命令

# 免登录直链(不带 cookie,期望: HTTP 200 image/jpeg)
curl -s -o /dev/null -w "HTTP %{http_code} type %{content_type} size %{size_download}\n" \
  "https://files.example.com/static/<文件名>.jpg"

# FileBrowser 页面(需登录,返回 SPA HTML,期望: 200 text/html)
curl -s -o /dev/null -w "%{http_code} %{content_type}\n" "https://files.example.com/"

# 受保护 API(无凭证,期望: 401)
curl -s -o /dev/null -w "%{http_code}\n" "https://files.example.com/api/raw/<文件名>.jpg"

三条全过,说明:直链公开可用、管理页仍受保护、API 没被误开放——安全性和可用性同时达标


五、Notion 接入

  1. 图片上传到服务器 /data/images/ 目录(或通过 FileBrowser 网页上传到根目录)
  2. 在 Notion 页面嵌入:https://files.example.com/static/<文件名>.jpg
  3. Notion 采集脚本/工具直接使用该 URL,无需任何认证头

为什么能嵌入 NotionAccess-Control-Allow-Origin: * + 公开 GET 直链 + CDN 缓存,三者缺一不可。缺 CORS 头的话浏览器会跨域拦截,Notion 页面里就是一片空白。


六、排障速查

症状原因解决
直链返回 text/html 而非图片走了 FileBrowser SPA(路径不对)确认 URL 带 /static/ 前缀
直链 404alias 目录下无此文件检查 /data/images/ 文件名
Notion 显示空白/跨域缺 CORS 头确认 static.confAccess-Control-Allow-Origin "*"
FileBrowser 页面打不开nginx 反代或 iptables 问题检查 8080 端口 DOCKER-USER 链、容器状态
图片更新后不刷新expires 30d 强缓存改文件名(换 hash)或手动清 CDN 缓存

总结

这套方案的价值在于用最小的改动解决了一个很实际的问题:FileBrowser 负责管理、nginx 负责公开,一个容器、一段 alias 配置,就把「私有文件管理」和「公开图片直链」安全地拆开了。Notion 嵌入图片从此不用再到处找图床,自己的服务器就是图床。

如果你也在折腾自建图床和 Notion 工作流,这套配置值得直接抄走。相关文章:

☕ 如果这篇文章对你有帮助

欢迎请 Jeff 喝杯咖啡,支持我持续分享更多软件技巧~

打赏功能即将上线,先点个赞也是支持 ❤️

返回博客

相关文章

查看全部 »
进程还在,端口已死:一个单线程 HTTP 服务的「假活」陷阱,和我的四层加固

进程还在,端口已死:一个单线程 HTTP 服务的「假活」陷阱,和我的四层加固

我自建的一个统计面板曾经挂了整整 16 天我才发现:进程从没退出、端口一直在 LISTEN、CPU 占用是零,看上去「健康得不得了」,可所有新连接都拿不到响应,公网一律 504。根因是单线程 HTTPServer 没有 socket 超时,被一条半开连接永久阻塞;更值得记的是第二层——进程监督器只认「进程存活」,这种假活对它完全不可见。这次我给它上了四层加固,也第一次想明白:为什么「重启脚本」这种修复,会被下一次部署悄悄冲掉。

1.3GB 内存的服务器上,浏览器自动化必然 OOM:我最后用纯 HTTP 重写了一遍签到

1.3GB 内存的服务器上,浏览器自动化必然 OOM:我最后用纯 HTTP 重写了一遍签到

一个每天跑的签到脚本,用 Playwright 时 6 分钟才启动完浏览器、随后必崩。我一度以为是脚本写得不对,换了三种写法都没用。真正的结论是:在 1.3GB 内存、swap 全满的机器上,浏览器自动化注定失败——不是代码问题,是物理问题。更值得记的是第二层翻车:当时得出的「必须借浏览器上下文」这个结论本身就是错的,而它被固化进了代码,白折腾了一周。

自建 AI Agent 记忆系统的冲突消解:软失效、事件账本,和同一个 bug 我修了两次

自建 AI Agent 记忆系统的冲突消解:软失效、事件账本,和同一个 bug 我修了两次

Agent 的记忆越攒越多,新事实和旧事实开始打架。本文记录我给自己那套记忆系统做「冲突消解」的完整实现:为什么不能直接删、软失效 + 事件账本怎么设计、用什么判据判定两条记忆冲突。重点是一个真实的翻车——判据太激进,一条新记忆横扫了 50 条无关事实,误杀 19 条。更值得记的是:同一个 bug,我修了两次。

Google Search Console 从验证到收录:新站接入实操与踩坑清单

Google Search Console 从验证到收录:新站接入实操与踩坑清单

新站被搜索引擎冷落,第一步不是狂发外链,而是把 Google Search Console 接上——它决定你能不能看见「爬虫到底来没来、收录卡在哪」。这篇是完整实操:网域还是网址前缀、四种验证方式怎么选、DNS TXT 验证的准确姿势、验证后必做的三件事、多久有数据,以及我踩过的六个坑,附 GSC / Bing / 百度三平台对照。