整体架构
两层结构:
- 存储层:GitHub 仓库,存放所有图片
- 分发层:Cloudflare Worker,从 GitHub 取图、缓存、通过自定义域名对外提供访问
上传工具用 PicList,配合 Obsidian 插件可以实现粘贴图片自动上传、自动插入链接,写作流程零打断。
如果只是自用笔记、网络能顺畅访问 GitHub,可以跳过 Cloudflare 部分,直接用 GitHub 原始链接。
第一步:创建 GitHub 图片仓库
访问 GitHub 创建新仓库,名字随意,比如 imgs。
仓库可见性的选择:
- Public:图片地址可以直接用,省事。代价是任何人都能看到和下载你的整个图库
- Private:需要 Cloudflare Worker 做中转才能外链访问,但仓库完全私有,访问可控
建议打开 Add README 选项,避免空仓库不知道怎么操作。
然后生成 Personal Access Token。进入 GitHub Settings → Developer settings → Personal access tokens,选 classic 类型。过期时间选 No Expiration,权限勾选 repo。
这里有个坑:repo 权限能读写你账户下所有仓库,Token 等同于仓库密码。绝对不要提交到公开仓库,不要分享给任何人。
生成后立刻复制保存,页面刷新就没了。
第二步:配置 PicList 上传工具
PicList 是基于 PicGo 的新一代图床工具,接口兼容 PicGo。
打开 PicList,侧边栏选「图床」→「GitHub」,新增配置:
- 设定仓库名:格式是
用户名/仓库名,比如innomadio/imgs - 设定分支名:
main - 设定 Token:填入上一步生成的 token
确认后上传一张图片测试。上传成功后图片地址会自动复制到剪贴板,格式类似:
https://raw.githubusercontent.com/innomadio/imgs/main/unnamed%20(1).jpg
顺手点一下界面顶部的「复制上传 API」,下一步配置 Obsidian 要用。
第三步:Obsidian 自动上传配置
安装 Obsidian 插件 Image auto upload,在设置中把 PicGo server 上传接口填入上一步复制的 API 地址即可。
配置完成后,在 Obsidian 里粘贴图片会自动上传到 GitHub 仓库,Markdown 链接自动插入。写作体验和本地图片一样,但图片实际存在云端。
到这里基础图床已经可用。下面是进阶部分。
进阶:Cloudflare Worker 实现私有仓库外链 + CDN 加速
这一步解决三个问题:私有仓库的图片也能外链访问、绑定自定义域名、全球 CDN 加速。
准备域名
需要一个自己的域名,因为 Cloudflare 自带的 workers.dev 域名在国内无法访问。.xyz 域名很便宜,支持支付宝付款。
买完后把域名 DNS 托管到 Cloudflare:
- Cloudflare 首页点击「加入域」,填入域名
- 选择免费套餐
- 按 Cloudflare 提示,去域名注册商修改 Nameservers 为 Cloudflare 提供的两个地址
- 等待生效,Cloudflare 状态变为 Active
创建 Worker
在 Cloudflare 侧边栏进入「Compute」→「Workers 和 Pages」,创建应用程序,选 Hello World 模板,直接部署。
然后做两件事:
绑定域名:在「域和路由」里添加子域名,比如 imgs.innomad.io。
添加环境变量:在「变量和机密」里添加 4 个文本变量:
| 变量名 | 值 |
|---|---|
GH_BRANCH |
main |
GH_NAME |
你的 GitHub 用户名 |
GH_REPO |
仓库名,比如 imgs |
GHTOKEN |
GitHub Token(ghp 开头) |
部署代码:点击「编辑代码」,把 Worker 代码粘贴进去并部署。这段代码的逻辑很简单——收到图片请求时,用 Token 从 GitHub 私有仓库取图,缓存一年,后续请求直接从 CDN 返回。
最后回到 PicList,在自定义域名设置里填入你的域名(比如 https://imgs.innomad.io),这样上传后自动复制的就是自定义域名的地址。
最终效果
整套链路:Obsidian 粘贴图片 → PicList 自动上传到 GitHub → Cloudflare Worker 中转 + CDN 缓存 → 通过自定义域名全球可访问。
零运维、零月费,存储和流量都吃的免费额度。对个人博客和知识管理来说,这套方案能用很久。搭一次,后面就不用再想图片存哪的问题了。