🗼使用Caddy反向代理加速NotionNext博客图片访问

2025-1-2|2025-3-5
Yawatasensei
Yawatasensei
type
status
date
slug
summary
tags
category
icon
password
📌
NotionNext默认使用的是Notion图床。Notion在国内没有服务器,所以通过Notion.so域名请求的图片资源文件在国内的访问速度不是很好,我们可以通过使用Caddy反向代理的方式加快Notion.so的图片访问,降低加载图片所需时间,从而提高使用NotionNext的博客在国内的访问速度与用户体验。
我这个使用NotionNext,部署在Vercel上的博客页面加载时间太长的问题,也是由于昨天突然博客的国内用户的访问量增加,我在Cloudlfare Web Analytics里面进行日常数据查看时发现的,涉及到的文章页面主要是《小米15手机(澎湃OS2):如何关闭推荐广告 | Deep Router》这篇文章,原因在于这篇文章我放了很多的手机截屏图片,这些图片需要进行加载,即使我已经使用了图片的延迟加载功能,但是依旧会因为首屏需要加载3-4张图片,而造成整体页面的加载时间过长,影响用户体验。因为Notion在国内没有服务器,访问速度不算很好,所以大部分图片的LCP(Largest Contentful Paint)延迟都在5秒左右,FCP也因为我未使用webp格式的图片造成访问延迟上升。在一篇包含很多张图片的文章里,整体的加载速度更堪称灾难级,可能需要30秒以上才能完成首屏加载,这一点在移动端设备上,因为性能差异进一步被放大。为了优化博客国内的访问体验,所以我尝试寻找解决方案,让NotionNext的图片加载不再那么灾难。在《Nginx设置Notion反代加速NotionNext图片资源访问》这篇文章中,作者提到可以通过使用Nginx反向代理(反代)方式进行解决,通过Nginx将用户对图片素材的访问请求反向代理至notion.so,这样只要部署Nginx的机器在国内的访问速度够快,那么托管的Notion上的图片资源也能够很快的进行加载,降低LCP延迟。我没有使用Nginx作为Web服务器,而是使用的Caddy这个更轻量化的解决方案,所以就在这篇文章的基础上,提供一份基于Caddy的反向代理解决方案。
在开始之前,我们先查看一下目前Notion.so在国内的访问情况,大部分浅绿,平均加载时间在3s左右,且在部分地区无法直接进行访问:
notion image

📝 Caddy反向代理配置前提

你需要一台云服务器,境内境外均可,我所使用的小鸡(云服务器)是在香港,购自CoalCloud(碳云),国内访问速度在ITDOG上查询还不错。平常只作为RSS推送服务和Docker加速镜像使用。如果不使用Cloudflare的话,需要自行在云服务器为用于反向代理的域名申请证书,例如使用letsencrypt或者acme,但是如果你也和我一样使用Caddy的话,那么Caddy会自动帮你通过acme申请好所配置的域名的证书。
也有一些解决方案是通过Cloudflare Worker实现,我没有使用Cloudflare Worker进行反向代理的原因是担心会被认为在滥用,从而导致Cloudflare账号被封禁(Ban)或限制服务。

📝 什么是Caddy

Caddy是一个开源的Web服务器和反向代理工具,专注于简化配置流程和提升安全性。它以自动化HTTPS部署为核心特性,无需手动操作即可为站点申请并更新 SSL/TLS证书。支持HTTP/3、静态文件托管、负载均衡等功能,通过简洁的配置文件(或直接通过 API)即可快速部署服务。凭借原生Go语言编写的高效性和跨平台兼容性,Caddy常被用于轻量化场景,适合开发者和运维人员快速构建安全的网络服务。
Caddy的最新版本是Caddy2,主流版本也是Caddy2。需要注意的是,Caddy和Caddy2的配置文件语法并不完全一样。

📝 安装Caddy

Caddy的安装很简单,由于不使用其他第三方插件,所以可以直接通过系统的包管理器进行安装,例如我使用的是Debian系统:

📝 修改Caddy配置文件

这里我所使用的域名是notion.dolingou.com ,即通过notion.dolingou.com域名替代notion.so域名从而实现反向代理加载位于Notion上的图片。安装完Caddy之后,配置文件位于/etc/caddy/Caddyfile ,你可以使用你喜欢的编辑器进行编辑,例如我使用的是Vim ,添加如下内容:

Caddy2配置要点

拒绝所有非来自博客域名请求

涉及代码段:
这部分代码主要是避免这个反向代理被恶意使用,造成反向代理服务器的负载过高出现问题,或者盗刷大量流量。所有非博客域名的请求均会返回403错误。你可以将*.dolingou.com 替换为你的域名。

处理Caddy反向代理域名根目录请求

涉及代码段:
这部分代码主要用于当用户直接访问根目录及根目录下/image时,返回200 请求,并设置响应头的Content-Typetext/plain ;一方面为特定路径提供简单的占位符响应,另一方面可以快速测试服务器的响应,便于Debug。

Caddy反向代理转发配置

涉及代码段:
用于将匹配特定路径的请求代理转发到目标服务器https://www.notion.so,并在转发过程中设置一些请求头、Host、Referer、User-Agent和SSL/TLS配置。
具体如下:
  1. 定义匹配器 @imagePath
      • @imagePath 是一个匹配器(matcher),用于匹配特定的请求路径。
      • path_regexp image ^/image.*$:使用正则表达式匹配路径。
        • ^/image.*$:匹配以 /image 开头的所有路径,例如 /image/image/123/image/test.jpg 等。
      • 这个匹配器会捕获所有路径符合正则表达式 ^/image.*$ 的请求。
  1. 反向代理配置:
      • reverse_proxy 是一个指令,用于将请求代理转发到指定的后端服务器。在Caddy 1版本中,反向代理是proxy
      • @imagePath:指定匹配器,表示仅对匹配 @imagePath 的请求生效。
      • https://www.notion.so:目标服务器的地址,所有匹配的请求都会被转发到这里。根据NotionNext的默认配置文件NEXT_PUBLIC_NOTION_HOST 的默认值提示,填写notion.so域名。
  1. 设置请求头:
      • header_up 是一个指令,用于设置转发到后端服务器的请求头。
      • Host www.notion.so:将 Host 头设置为 www.notion.so,确保后端服务器知道请求的目标主机。
      • Referer https://www.notion.so:将 Referer 头设置为 https://www.notion.so,模拟请求来源。
      • User-Agent {http.request.header.User-Agent}:将 User-Agent 头设置为客户端原始请求的 User-Agent,确保后端服务器能够识别客户端类型。
      • X-Real-IP {http.request.remote.host}:将 X-Real-IP 头设置为客户端的真实IP地址,用于后端服务器记录或处理。
      • Accept-Encoding "":清空 Accept-Encoding 头,防止后端服务器返回压缩内容(如果需要)。
      • Accept-Language {http.request.header.Accept-Language}:将 Accept-Language 头设置为客户端原始请求的 Accept-Language,确保后端服务器返回正确的语言内容。
      • X-Cache {http.reverse_proxy.header.X-Cache-Status}:将 X-Cache 头设置为反向代理的缓存状态(如果有)。
  1. SSL/TLS配置:
      • transport http:定义HTTP传输配置。
      • tls:启用TLS(HTTPS)加密,确保与后端服务器的通信是安全的。
      • tls_server_name www.notion.so:设置TLS的服务器名称为www.notion.so,用于SNI(Server Name Indication)验证。
完成以上配置后,直接访问反代域名,这时候浏览器应该会显示一个200 OK! ,即表示配置成功。
  1. Caddy缓存配置:
我没有像上面Nginx样例中一样为反向代理添加缓存。原因在于目前Caddy2自身没有提供缓存功能,需要通过插件实现。而插件在命中率和缓存污染等方面的实现情况并不是很好。我的博客本身流量也不是很大,而且又有Cloudflare的CDN作为缓存,所以也就没有继续研究Caddy的这部分缓存功能。
  1. 重启Caddy
在完成上述配置文件修改后,需要对Caddy进行重启

📝 配置Vercel环境变量

完成以上在云服务器的Caddy配置后,在Vercel中的NotionNext项目下添加环境变量NEXT_PUBLIC_NOTION_HOST,用于替换默认的Notion Host变量(https://notion.so)。
Vercel环境变量配置的位置位于SettingsEnvironment Variables 中,新增环境变量:
注意需要携带https,否则无法正常使用。添加完成后,需要在Vercel中对NotionNext进行重新部署即可生效。
这时候打开博客的图片,查看图片地址,应该类似于https://notion.dolingou.pro/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F6d3fda40-6b03-4bf3-842b-4c9bb68a90f1%2F5a7f71fc-218f-4ac0-b76f-e471232cd7647%2Fandroid-chrome-512x512-min.webp?table=collection&id=f87dcb58-ba2a-40bb-a156-53d7877975e9&t=f87dcb58-ba2a-40bb-a156-53d7877975e9&width=800&cache=v2" 这种。如果直接访问这个地址,会通过302重定向的方式,经由s3.us-west-2.amazonaws.com ,最终到https://img.notionusercontent.com/s3/prod-files-secure%2F6d3fda40-6b03-4bf3-842b-4c9bb68a90f1%2F5a7f71fc-218f-4ac0-b76f-e47602cd7647%2Fandroid-chrome-512x512-min.webp/size/w=800?exp=1741086188&sig=klZmCOx0XSjO_rQwnGGeMEyR_Kuz1dct7Y5cyf3Fdv4

🤗 Caddy反向代理配置总结归纳

因为我最终还是将反向代理域名使用Cloudflare CDN服务,也就是开启小黄云,所以为反向代理域名配置了SaaS回源使用Cloudflare域名优选(没错,CNAME到了Linux.do),优化国内的访问速度。同时由Cloudflare提供缓存,故未在反向代理服务器的Caddy配置中添加缓存配置。目前的国内访问情况如下,相比使用默认的Notion.so ,在全国范围内速度提升了不少,延迟基本都控制在1.5s ~ 2s左右,同时在全国范围应该都可以正常访问。
notion image

📎 参考文章

💡
有关Caddy安装或者使用上的问题,欢迎您在底部评论区留言,一起交流~
Android免拔SIM卡使用官方TikTok使用Pipedream同步RSS至Twitter(X.com)
Loading...