Markdown图片托管:GitHub与MinIO图床配置及选型全攻略
写 Markdown 的人,十有八九都被图片折磨过。MarkText 这款 Markdown 编辑器,用来写长文、做笔记都很顺手,但图片从来不是它的强项;PicGo 则正好负责“图片上传”这一件事,两者搭配,是很多博客作者固定下来的写作工作流。真正让大家纠结的往往是图床本身:免费现成的 GitHub 和自建可控的 MinIO,到底选哪个?这篇文章我就把两者的完整配置、联动方式、踩坑经验,以及我个人的选型思路一次性说清楚。
我最早写博客的时候也图省事,图片直接丢进本地文件夹,等换电脑或者把文章同步到其他平台才发现,所有图片全挂了。后来改用 MarkText + PicGo 的组合,才第一次体会到什么叫“截图即贴图”:截完图自动上传、自动生成 Markdown 链接、粘贴进正文,整个过程不超过三秒。但图床的选择又把我卡住了很久,GitHub 免费但有各种限制,MinIO 可控但需要服务器。下面是我折腾完两条路之后留下的完整记录。
1. 图片问题为什么绕不开图床
1.1 Markdown 图片的本质是一个 URL
先回到最基础的一件事:Markdown 里插图片,写法是。这个地址可以是本地相对路径,比如./images/foo.png,也可以是一个完整的 URL,比如https://example.com/foo.png。本地方案的坏处太明显——文章最终要发布到博客、公众号或者笔记平台,换一台设备,路径就失效,图片就成了裂图。所以只要你有长期写作、跨端查看、发布分享的需求,图片地址就应该是一个能在任何地方访问的 URL,图床解决的,就是“提供一个稳定、可达的 URL 来挂图片”。
很多新人第一次配图床时会以为这是把图片“存储”在哪里,其实问题的核心不是存储,而是“公开访问”。对 GitHub 来说,它本质是个代码托管平台,只是因为你把图片放进了仓库,而仓库能生成 raw 访问地址,所以可以当图床用;MinIO 本身就是一个对标云对象存储的服务,只是它部署在你自己的服务器上。两者没有本质上的“能不能用”区别,只有“访问链路怎么搭”“数据在谁手里”“成本怎么算”的区别。
1.2 一个图床应该满足哪些条件
我在实际用下来,觉得合格的图床至少得满足这五点:
- 可访问:返回的 URL 能被浏览器、CDN、RSS 阅读器正常打开,没有防盗链。
- 稳定:图片地址不会三天两头变,平台不会突然停止服务或者删除文件。
- 速度:尤其面向公网访客时,图片加载不能等半天。
- 可控:我能知道图片放在哪,能导出、能备份、能清理,而不是上传之后石沉大海。
- 成本可接受:要么免费但代价清晰,要么自建但运维可控。
GitHub 和 MinIO 在这五点上的表现是完全不同的。先说说结论:GitHub 胜在零成本、配置简单、套上 CDN 后速度也不错;MinIO 胜在数据归属你自己,稳定性和隐私控制都能掌握。理解完这个前提,再进入具体配置就不会一头雾水,因为你始终知道自己在为什么而配置。
2. MarkText 和 PicGo:编辑与上传的分工
2.1 谁负责编辑,谁负责上传
MarkText 的核心能力是编辑 Markdown,语法高亮、实时预览、导出文件都做得不错,但它不是一个图床客户端。你在设置里通常只能配置本地图片保存目录,它并不会帮你把图片上传到远程。PicGo 则恰好相反,它不负责编辑,只负责一件事:把图片上传到你指定的图床,并返回一个可用的 URL。它同时支持多个图床插件,桌面端和命令行版都有。
正因为两者各管一段,组合在一起刚好能拼出一条完整的图片处理流水线:截图或文件出现 → PicGo 自动上传 → URL 回到剪贴板 → 粘贴进 MarkText。很多刚从普通文本编辑器转过来的人,会下意识在 MarkText 里找“上传到图床”的按钮,找不到就以为是软件坏了。其实这很正常,MarkText 对不同版本和平台的上传支持有过调整,有的版本可以在设置里配置自定义上传命令,有的版本弱化了这个入口。与其和版本较劲,不如直接把 PicGo 当作上传中心,用系统级的工作流把两者串起来。
2.2 我目前最顺手的组合方式
我的日常流程是这样的,三步:
- 用系统自带截图工具或独立截图软件截取需要的图,图片会自动进入剪贴板。
- PicGo 开启剪贴板监听后,会立刻上传剪贴板里的图片,并在上传完成后把 URL 以 Markdown 格式复制到剪贴板。
- 回到 MarkText 编辑器,直接
Ctrl+V粘贴。如果剪贴板里是 Markdown 链接,MarkText 通常会直接插入;如果粘贴的是图片内容本身,不同版本的表现会有点差异,但多数情况会弹出本地保存或 URL 二选一的提示。
如果你要插入的是本地已经存在的图片文件,而不是截图,那就把文件拖进 MarkText,让它先按本地图片处理,然后再打开 PicGo 选择这张图上传,最后把返回的 Markdown 链接替换掉本地路径。这看上去多了一步,但实际写作中很少发生,因为写博客配图大都是实时截屏。
如果你用的 MarkText 版本保留了自定义命令接口,也可以尝试在设置里把上传命令指向picgo upload的可执行文件,这样在编辑器中插入图片时,编辑器会先把图片传给 PicGo 上传,再把结果写回文档。这个方案对版本要求比较挑剔,我的建议是用不了就不勉强,流程顺不顺比功能全不全更重要。
2.3 一个版本差异导致的坑
这里要特别提一句:MarkText 的历史版本里,内置图床上传的入口、图片菜单的布局改过好几次。有些老教程直接让你在 MarkText 里选某个图床,或者到某个菜单点“上传到云端”,放到新版本里可能根本找不到。不要因为找不到按钮就觉得自己配置错了,更不要随便去找来路不明的修复包。正确的做法很简单:MarkText 只负责编辑和预览,图片的“上传”动作统一交给 PicGo,这样版本的变动影响最小,未来换编辑器也不会推翻整套流程。
3. GitHub 当图床:三步配置和四个暗坑
3.1 配置只要走三步
GitHub 当图床,本质是利用仓库来存储图片文件,通过 raw 地址或 CDN 地址对外提供访问。配置动作本身不复杂,但顺序别乱:
建仓库。在 GitHub 上新建一个公开仓库,比如叫
blog-images。注意仓库必须设置为 Public,否则图片 URL 需要登录才能访问,第三方博客展示时全都会抓瞎。生成 Token。打开个人设置里的 Developer settings,创建 Personal Access Token,勾选
repo权限。这个 Token 相当于 PicGo 访问你仓库的钥匙,生成后只显示一次,一定要先复制保存再关闭页面。在 PicGo 里配置 GitHub 图床。填仓库名(格式是“用户名/仓库名”)、分支(一般是
main)、Token,再填一个存储路径(比如img/,表示图片上传到仓库的 img 目录下)。保存并设为默认图床后,上传一张测试图,返回的 URL 会类似https://raw.githubusercontent.com/用户名/blog-images/main/img/abc.png。
到这里,GitHub 图床其实已经可用了。但直接把 raw 地址丢给博客,只能保证可访问,速度和稳定性就看网络环境了。这也是为什么很多人会用 jsDelivr 之类的公共 CDN 对 raw 地址做分发:把 PicGo 里的自定义域名填成https://cdn.jsdelivr.net/gh/用户名/blog-images,上传后得到的 URL 就变成带加速域名的形式,访客加载图片会更快,也能减少直连不稳定带来的失败。
3.2 公开仓库和私密信息的边界
用 GitHub 当图床,最容易被忽视的是隐私边界。仓库既然是 Public,那么任何知道你图片 URL 的人都能看到文件,搜索引擎也可能索引这些图片。放博客配图没问题,但千万别把身份证扫描件、内部文档截图、服务器密码之类的图片传上去。如果你传错了,即使马上删文件,也不等于世界上没人看过,公开仓库的历史里可能还留着记录。我的习惯是单独建一个图片仓库,和代码仓库完全隔离,万一要清理或者转移,影响面可控。
3.3 Token 泄漏后的处理方案
PicGo 配置里明文保存的 Token,如果哪天你的配置文件被上传到公开仓库,或者电脑交给别人维修,Token 就等于暴露了。一旦发现,正确的做法不是改仓库设置,而是去 Developer settings 里把这个 Token 删掉或重新生成,再去 PicGo 里更新新 Token。不要抱着“可能没人看到”的侥幸心理,公网上的扫描行为远比想象中勤快,各种明文密钥是第一优先级的收集对象。
3.4 仓库膨胀和图片被滥用问题
GitHub 对单个文件有 100MB 的大小限制,单仓库也建议控制在 1GB 左右。如果图片又多又碎,仓库会越来越重,操作也会变慢。PicGo 上传时还会受 API 请求速率限制,认证后的配额对个人写作完全够用,但如果你是重度截图党,一天传几百张,就可能短时间遇到 403 或上传失败,这是限流的正常表现,不代表配置有误。
还有一个容易被忽视的现实问题:公开仓库的图片可能被其他人直接引用、盗链。一旦某张图被放到高流量页面,你的仓库会被持续请求,虽然一般不会产生直接费用,但会影响你正常使用时的访问体验。GitHub 本来就不鼓励把仓库当作图床长期高强度使用,所以任何基于它的方案都更适合“轻量、低频、能接受变动”的个人博客场景。
3.5 常见故障排查顺序
如果你配完之后上传失败或者图片打不开,按这个顺序排查:
- 上传超时或失败:先确认网络环境,再看 Token 是否有效,最后看仓库名和分支拼写是否正确。
- 图片打不开但仓库里有文件:多半是 raw 直连不稳定,换 jsDelivr 域名,或检查自定义域名是否填写完整。
- 返回的 URL 缺少用户名或仓库名:常见原因是自定义域名配置时前缀写错,直接把期望的完整 URL 复制到浏览器测试一遍就清楚了。
总的来说,GitHub 适合作为入门首选,零成本、资料多、不需要服务器,但想长期稳定使用,就得接受它在网络速度和滥用控制上的短板。
4. MinIO 自建图床:部署、接入和四个必踩的坑
4.1 用 Docker 快速部署一个 MinIO
MinIO 是一个兼容对象存储协议的服务,可以部署在任意一台能跑 Docker 的服务器上。对个人博客来说,一台低配置的云服务器就够了,部署命令大致是这样:
docker run -d \ --name minio \ -p 9000:9000 \ -p 9001:9001 \ -e "MINIO_ROOT_USER=minioadmin" \ -e "MINIO_ROOT_PASSWORD=minioadmin" \ -v /data/minio:/data \ minio/minio server /data --console-address ":9001"9000 是对象存储的 API 端口,PicGo 上传走的是它;9001 是网页控制台端口,用来管理 Bucket 和策略。启动后,访问http://服务器IP:9001就能打开管理界面,用minioadmin / minioadmin登录。正式用于博客之前,务必把默认的管理员账号密码改掉,默认口令在公网上只要几秒钟就会被扫描到。
我个人的建议是不要直接在裸奔的 9000 端口上对接 PicGo,而是用 Nginx 或 Caddy 做一层反向代理,把请求转发到 9000,同时配上 HTTPS 证书。这样 PicGo 端不需要记 IP 加端口,后续换服务器、迁移数据时影响也最小。
4.2 创建 Bucket 并设置只读策略
登录 MinIO 控制台后,先创建一个 Bucket,名字按你的域名习惯来,比如blog-img。创建完成后,默认 Bucket 是私有的,外部无法直接访问。这时候把图片丢进去,浏览器也打不开,所以需要给 Bucket 配置一条匿名只读策略,允许任何人通过 URL 读取文件,但不能上传、不能删除。
控制台里可以直接编辑 Bucket Policy,一个典型配置是把Principal设为*,Action只保留s3:GetObject,Resource指向arn:aws:s3:::blog-img/*。理解上,这相当于给目录设置了一个“只允许所有人读取”的权限,上传动作仍然只能通过带有密钥的客户端完成。如果你常用命令行工具管理对象存储,也可以借助mc客户端来设置策略,效果一样。这里的关键是 Bucket 策略必须和你的使用方式匹配,很多人配完发现图片 403,十有八九就是漏掉了公开只读这一环。
4.3 PicGo 接入 MinIO 的配置细节
回到 PicGo 这边,添加 MinIO 图床时,主要配置项包括:服务地址、端口、AccessKey、SecretKey、存储路径和自定义域名。AccessKey 和 SecretKey 就是上面控制台的账号和密码,如果你追求更细的权限控制,也可以在 MinIO 控制台里单独生成一对服务账号密钥。
几个配置细节在实操中容易踩:
- 服务地址不要带协议,也不要带路径。例如
minio.example.com或服务器 IP,端口单独填。如果前面做了 Nginx 反代且走 443,端口就填 443,并选择 HTTPS。 - 存储路径字段要理解成“存储前缀和目录”。有的版本里有单独的 Bucket 字段,路径就写 Bucket 下的目录;有的版本没有单独的 Bucket 字段,就把 Bucket 名拼在存储路径最前面,比如
blog-img/。这样上传后的对象会落到对应 Bucket 根目录,最终 URL 也能按预期拼接。 - 自定义域名一定要填你能真实访问的地址,比如
https://img.example.com,不要填 MinIO 控制台地址。PicGo 上传成功后会根据自定义域名拼接最终图片 URL,如果这个 URL 缺少 Bucket 路径,就会一直 404。
4.4 四个我实测踩过的坑
第一个坑是 Content-Type 问题。有些情况下 MinIO 存储对象后没有正确返回图片的 Content-Type,结果浏览器打开图片地址不是展示图片,而是直接触发下载。解决方法是上传时通过客户端设置Content-Type,或者在 Nginx 反代层根据文件后缀补上image/jpeg、image/png这类 MIME。如果发现图片能访问但浏览器老是下载而不是展示,优先检查这一项。
第二个坑是指定 HTTPS 后的证书问题。MinIO 默认生成的证书是自签名的,你在 PicGo 里强行启用 HTTPS 而不配置受信任证书,上传会直接报证书错误。要么给图片域名配置正规证书并让反代完成 TLS,要么在测试阶段继续用 HTTP。不要为了省事直接关掉证书校验,否则传图时会遇到奇怪的中断。
第三个坑是路径和重定向。如果反向代理把根路径原封不动透传到 MinIO 的 9000 端口,上传和访问都能成功;一旦你加了路径前缀,比如把所有请求转发到某个子路径下,对象地址和反代规则很容易互相冲突。个人使用最省心的做法是单独用一个域名或子域作为图片域名,根路径直接透传。
第四个坑是备份意识。MinIO 数据都在服务器本地磁盘,一旦磁盘故障、服务器被入侵或误删 Bucket,图片就全没了。图床方案里“自建可控”的前提是“你自己负责备份”。我在实际使用中会把 MinIO 的数据目录定期同步到另一块磁盘或远端存储,最低限度也要保证服务器故障后能恢复。
到这里,MinIO 作为图床已经能正常工作了。相比 GitHub 方案,它需要一台服务器、一次 Docker 部署和一点维护意识,但换来的是稳定的访问速度、可掌控的数据,以及不用担心仓库限流或公共服务政策变化。
5. GitHub 还是 MinIO:给一个能直接套用的选型逻辑
5.1 一张表看清差异
我整理过一个对比表,基本可以覆盖大多数人做决定时关心的点:
| 对比维度 | GitHub 图床 | MinIO 自建 |
|---|---|---|
| 前期成本 | 免费,只要有账号 | 需要一台服务器和域名 |
| 配置复杂度 | 三个字段,几分钟 | 服务部署、策略、反代,半天起 |
| 数据掌控 | 在 GitHub 手里,公开可见 | 完全在自己服务器上 |
| 访问速度 | 直连看网络环境,可套 CDN | 取决于带宽,可控,可内网高速 |
| 稳定性 | 依赖公共服务政策和 API 配额 | 依赖你的运维能力和机器稳定性 |
| 隐私保护 | 适合非敏感图片 | 可放截图、文稿等较敏感内容 |
| 运维成本 | 几乎为零 | 需要关注磁盘、备份、证书、安全更新 |
| 扩容与长期使用 | 仓库会膨胀,限制多 | 磁盘够大就够用,成熟协议支持 |
这张表看下来,其实没有绝对的好与坏。GitHub 更像“省心但受限”的方案,MinIO 更像“投入成本换掌控”的方案。如果你在意的是快速跑通,那就选 GitHub;如果在意的是长期稳定和隐私边界,那就选 MinIO。最怕的是选了 GitHub 又嫌弃它不稳定,或者选了 MinIO 又不想做任何运维,这都相当于拿错了工具硬干活。
5.2 我实际会怎么选
如果只是写个人博客、技术笔记,图片数量不大,想快速跑通整套工作流,起步阶段直接选 GitHub 最省事,唯一要做的就是及时给仓库套 CDN,并注意隐私边界。等积累了上千张图、访问速度开始变慢、或者图片内容变得私密,再迁到 MinIO。迁移动作本身不大:把 MinIO 部署好,去 PicGo 里新建一个图床配置,然后把旧仓库里的图片批量下载再上传到 MinIO,最后更新文章里的 URL 前缀即可。
我在某次写作项目中就经历过从 GitHub 到 MinIO 的迁移,触发点不是 GitHub 不能用,而是某张被转载的图片带来了大量外部请求,导致我日常访问仓库的速度明显下降。迁移之后,图片域名换成了自己的子域,加载速度可控,心里也踏实很多。这个经历让我后来对“免费羊毛”多了一层认识:你可以依赖它起步,但要有随时能搬走的底气。
5.3 一种折中:两者同时保留
如果你的文章既有普通配图,也有少量隐私性较强的图片,可以不把两者做成二选一。PicGo 支持多个图床并存,你可以在不同场景手动切换。比如公开博客配图走 GitHub + CDN,内部文档或含隐私信息的笔记走 MinIO。这样一来,公开内容不耗服务器流量,私密内容不暴露在公共仓库,算是一个兼顾成本和隐私的思路。唯一需要注意的是定期检查每个图床的使用情况,避免冷门图床里的文件长期无人访问却占着磁盘。
6. 图床搭好之后,维护比选择更重要
6.1 从一开始就规范命名和目录
无论是 GitHub 还是 MinIO,图片目录结构建议从一开始就规划好,而不是让所有图片堆在一个根目录下。我的习惯是按文章主题分目录,比如2025-xx-article/作为前缀。PicGo 的上传配置里可以设置存储路径前缀,上传时的文件名建议用英文或数字组合,关键词里不要带中文、括号或者空格,否则在部分 CDN 或 URL 编码场景下会出现乱码和路径截断。截图默认生成的名字通常很乱,可以在 PicGo 设置里打开自动重命名,加上时间戳,减少重名覆盖的概率。
6.2 定期体检和备份
图床不是配好就能一劳永逸的。每过一段时间,我会抽查文章里几张历史图片的 URL 是否还能打开,并检查 GitHub 仓库大小和 MinIO 磁盘占用。对 MinIO,还会看服务日志里有没有异常访问,并定时备份数据目录。这些工作没有多难,但能避免某天文章页面突然出现大量裂图时才手忙脚乱。有一个更简单的方法:写一个定时脚本,每天把文章里出现的图片 URL 批量请求一次,状态码不是 200 的列出来,就能提前发现隐患。
6.3 图片加载变慢时的处理顺序
如果遇到图片加载变慢,我一般按这个顺序排查:先确认是不是域名解析或者 CDN 节点问题;再检查原始图片大小,很多博客图片其实是几 MB 的原始截图,这往往是加载慢的主因,而不是图床本身。给图片做一次压缩或转成更适合网页展示的格式,往往立竿见影;最后才去检查图床的带宽或仓库状态。不要一慢就急着换图床,大多数时候是你的图太大了,换到哪里都一样。
6.4 最后一个小技巧
分享一个我用了很久的习惯:在 PicGo 里设置上传后自动复制 Markdown 格式链接,并把 MarkText 的粘贴操作统一成“直接粘贴链接”。这样整条链路里完全不需要手动点“上传”按钮,只需要截图、粘贴,写文章的速度会明显提升。工具选型上,GitHub 和 MinIO 只要适合你的场景都是好方案,真正决定体验的往往是这些日常细节。