写 Markdown 文档最烦的事不是内容写不出来而是图片处理。你辛辛苦苦截了三张图插进去之后换台电脑打开文档图全裂了。或者发给别人对方看到一堆本地路径完全不知道你在说什么。MarkText 加 PicGo 这套组合就是我用了很久之后觉得最顺手的一套方案解决了“图片往哪放”和“图片怎么放”这两个核心问题。这篇文章围绕“MarkText PicGo 图床选择GitHub 或 MinIO”这个主题把选型逻辑、配置步骤、踩坑经验一次性讲清楚适合那些正在被 Markdown 图片问题折磨的文字工作者、技术博主和开源项目维护者。1. 整体思路为什么是 MarkText 加 PicGo而不是其他组合1.1 图片问题的根源在哪Markdown 本身只是个纯文本格式它不像 Word 那样把图片“嵌”进文件里。你在 Markdown 里写的![](./img/流程图.png)本质上是一个路径引用这个路径可以是相对路径、绝对路径也可以是一个网址。问题恰恰出在这里如果你把图片放在本地某个文件夹那么文档离开这台电脑图片就丢了。如果你把图片放在和 Markdown 文件同级的目录那整个项目文件夹会变得越来越臃肿多人协作时同步起来也很痛苦。刚开始写技术文档的时候我图省事直接在 Markdown 里用 base64 编码图片。看起来完美一个文件全搞定但几个大截图下来文档体积直接多出几 MBGit 提交时明显卡顿而且后续每一次编辑都要重新解码编码效率极低。后来我意识到真正的解法不是“怎么存图”而是“把图片放到一个稳定的公共访问位置再让编辑器自动生成访问链接”。这就是图床存在的意义。1.2 MarkText 和 PicGo 各自的定位MarkText 是一款开源的 Markdown 编辑器主打实时预览和沉浸式写作体验。它的一个关键能力在于内置了图床支持可以在粘贴图片时自动调用外部图床工具完成上传。但它本身不做图片存储也不直接对接各种对象存储服务它把这件事外包给了 PicGo。PicGo 是一个开源的上传工具负责把本地图片推送到你指定的存储端比如 GitHub 仓库、MinIO、阿里云 OSS、腾讯云 COS 等并返回一个可在公网访问的图片链接。两者结合写作时粘贴截图的动作就被简化成了“粘贴-自动上传-自动生成链接-自动插入”四步一气呵成。MarkText 支持的上传接口分为两种一种是原生支持 PicGo 的图床配置包含内置 CLI 和自定义命令行模式另一种是兼容 PicGo Server 的上传 API。实际使用中我推荐直接使用 PicGo 的本地服务监听模式MarkText 会把图片发送到localhost:36677这个端口PicGo 收到后立即上传并回传链接。相比 CLI 模式这种方式更稳定也不容易出现路径或转义问题。1.3 图床选型的基本盘图床选择是整个方案里最需要动脑子的部分。它决定了你的图片安全性、访问速度和后续维护成本。市面上能选的方案很多但“免费且稳定”和“私有化且可控”这两个需求最常见的落点就是 GitHub 和 MinIO。GitHub 依托仓库托管图片天然免费还能借助版本管理追溯图片变更。MinIO 则是开源的对象存储服务你可以部署在自己的服务器上图片数据完全自持不受第三方平台限制。一个偏向“零成本起步”一个偏向“数据主权”两者适合的场景完全不同。2. 图床方案拆解GitHub 和 MinIO 的核心差异2.1 GitHub 图床的运行逻辑GitHub 图床的本质是利用仓库的 raw 文件访问能力。你往仓库里推送图片文件PicGo 通过接口获取到该文件在仓库中的路径然后拼出其 raw 链接。默认的 raw 链接域名是raw.githubusercontent.com路径结构为https://raw.githubusercontent.com/用户名/仓库名/分支名/目录路径/图片名.png。也就是这个过程是否稳定取决于这个 raw 服务能否正常访问。在大多数网络环境下这个域名都是可用的只是速度有高有低。需要注意不同仓库的权限设置会影响图片的可访问性仓库必须设为 Public 才能被所有人看到。这是用 GitHub 做图床的硬性前提。GitHub 图床的图片管理依赖 Git 提交记录。每次上传一张图片本质上就是一次 commit。你可以在仓库中按日期或主题分目录比如images/2025/02/这样时间长了也不会乱。我见过有人将所有图片都堆在仓库根目录几个月后文件夹里密密麻麻几百个文件找一张旧图简直灾难。从一开始规划好目录结构后续的维护成本会低非常多。2.2 MinIO 图床的运行逻辑MinIO 是纯开源的对象存储服务兼容 S3 API。部署起来非常轻量一个 Docker 命令就能启动一个实例。它的核心概念是 Bucket存储桶和 Object对象图片就是 ObjectBucket 相当于顶层目录。和 GitHub 不一样MinIO 不依赖“提交”这个概念上传图片直接存储到磁盘立即生成访问链接。它的访问链接形如http://你的服务器IP:9000/桶名/图片路径但这个链接能不能被外网访问取决于你在创建 Bucket 时是否开放了公共读取权限。如果是个人使用MinIO 完全可以跑在一台闲置的服务器上。它的磁盘占用和内存占用都比传统图床服务低但性能却很稳定。部署时需要考虑的一个核心点是MinIO 本身提供两个端口一个是 API 端口默认 9000一个是控制台端口默认 9001。PicGo 对接的是 API 端口不要搞混。在配置时如果你用的是反向代理加域名访问还要记得把 API 路径的转发规则设置正确否则会出现“图片上传成功但链接无法访问”的怪现象。2.3 两个方案的关键参数对比对比项GitHub 图床MinIO 图床费用免费Public 仓库无存储费用自建服务费用取决于服务器成本依赖条件需要 GitHub 账号须保证仓库 Public需要一台服务器或 NAS访问速度受网络环境影响存在波动速度快慢取决于服务器带宽和地理位置数据安全数据托管在第三方平台数据完全自持图片管理通过 Git 提交记录管理支持版本回溯通过对象存储控制台管理可用性风险仓库被封禁或改名会导致图片失效服务器宕机会导致图片暂时不可访问适合场景个人博客、开源项目文档、学习笔记企业内部系统、数据敏感场景、生产环境这个表格基本上回答了我被问过无数次的问题“到底选哪个”。如果只是自己写博客、记笔记GitHub 图床的免费属性非常诱人。如果是公司项目、商业系统或者对数据隐私要求比较高的场景必须上 MinIO 这类自建对象存储。也有一些人在 GitHub 图床上跑了一段时间后发现个别网络环境下 raw 链接加载很慢于是切换到了 MinIO这属于实际使用中的合理迁移。3. 实操环节从零配置一套 MarkText PicGo GitHub 图床3.1 第一步创建专用图床仓库打开 GitHub新建一个仓库名字建议直接叫images或者blog-images直白清晰。仓库权限必须选 Public否则图片无法被匿名访问。如果选 Private就算 PicGo 里的链接配置完全正确外人也看不到图片。创建完仓库后下一步是生成访问令牌。点击头像进入 Settings找到 Developer settings 下的 Personal access tokens选择生成一个新 token。在权限勾选时只需要勾选repo权限即可不需要给它其他权限。生成的 token 只会显示一次务必复制保存到一个临时文本文件里。需要注意这个 token 等同于你账号的一把钥匙一旦泄露别人可以往你的图床仓库里推送任意文件所以千万不要把它提交到公开仓库也不要贴在配置文件的示例里到处发。3.2 第二步安装并配置 PicGoPicGo 支持 Windows、macOS 和 Linux。我这里以 Windows 为例下载安装包后一路下一步就可以了。安装完成后打开主界面左侧菜单选择“图床设置”找到“GitHub 图床”。这里需要填写几个关键项设定仓库名格式为你的用户名/仓库名例如someone/images。设定分支名如果你的仓库默认分支是main就填main。设定 Token粘贴上一步保存的令牌。指定存储路径推荐填一个明确的目录比如img/这样图片上传后不会散落在仓库根目录。自定义域名这是非常关键的一项。默认情况下PicGo 会生成一个指向raw.githubusercontent.com的链接但你可以填上自己的加速地址或者直接使用https://cdn.jsdelivr.net/gh/用户名/仓库名这种加速前缀。不过要注意加速服务的可用性并不稳定直接使用默认配置是最稳妥的。填完后点击“设为默认图床”然后打开“上传区”尝试拖一张图片进去。如果看到返回的图片链接并且用浏览器打开能正常显示就说明配置成功。3.3 第三步打通 MarkText 与 PicGo 的通道MarkText 的图床设置入口在左上角“文件”菜单下的“偏好设置”中切换到“图片”选项卡。这里有两种模式一种是“使用 Core 上传器”另一种是“自定义命令”。我需要重点说明的是推荐使用 PicGo 的 Server 模式。在 PicGo 的设置中开启“开机启动”和“PicGo Server”默认的监听地址是http://127.0.0.1:36677。然后在 MarkText 的图片设置中选择“自定义命令”在命令行输入框里填上 PicGo 可执行文件的路径并在参数里加上upload指令。不同版本系统的路径写法有差异Windows 下通常是C:\Users\你的用户名\AppData\Local\Programs\picgo\picgo.exemacOS 下是/Applications/picgo.app/Contents/MacOS/picgo。这里有个实用的测试技巧配置完成后直接在 MarkText 中粘贴一张截图观察光标附近是否出现短暂的上传提示并最终生成图片链接。如果没有任何反应去 PicGo 的上传记录里看有没有报错信息。绝大多数配置问题都能在这里找到答案。3.4 第四步验证配置的完整性配置结束之后不要急着开始写长篇文档先做一轮验证。我在第一次配置完成后测试了三类情况正常插入本地图片、复制网络图片后粘贴、从剪贴板截图粘贴。发现从剪贴板截图粘贴是最顺滑的方式因为 MarkText 会把剪贴板里的位图数据转成 PNG 文件然后交给 PicGo 上传整个过程不需要手动保存临时文件。这里需要提醒的是用鼠标拖拽图片文件和直接用 CtrlV 粘贴是两种路径后者更推荐操作起来更流畅。4. 实操环节从零部署一套 MarkText PicGo MinIO 图床4.1 第一步用 Docker 快速部署 MinIOMinIO 的部署复杂度完全取决于你对服务器和 Docker 的熟悉程度。我已经默认你的目标服务器上已经装好了 Docker如果没有先安装 Docker 再继续。启动命令非常简洁docker run -d \ --name minio \ -p 9000:9000 \ -p 9001:9001 \ -e MINIO_ROOT_USERadmin \ -e MINIO_ROOT_PASSWORDyour-strong-password \ -v /data/minio:/data \ minio/minio server /data --console-address :9001这里有几个参数值得解释一下。MINIO_ROOT_USER和MINIO_ROOT_PASSWORD是 Web 控制台的登录凭证密码强度一定要够不要用123456这种级别否则你的服务器可能被扫描并被种马。-v /data/minio:/data是把容器里的数据目录挂载到宿主机这一步非常关键不然容器一删你的所有图片就全没了。启动后浏览器访问http://服务器IP:9001可以看到图形化管理界面。4.2 第二步创建存储桶并配置访问权限登录 MinIO 控制台后左侧点击“Buckets”点“Create Bucket”新建一个桶名字建议叫md-images。这里最关键的步骤是设置访问策略。默认情况下新建的 Bucket 是私有的访问链接会提示AccessDenied。如果你希望图片能通过链接被直接访问编辑 Bucket 的 Access Policy选择Public。需要权衡的是公共读意味着任何人知道链接就能访问图片但图片毕竟是用于 Markdown 展示这个暴露范围是可以接受的。如果你有更高安全需求可以改成 Pre-signed URL 方式由后端生成短期有效的访问链接但这种方式不适合静态图片嵌入 Markdown 文档因为链接会过期。接着在控制台的“Access Keys”页面创建一对 Access Key 和 Secret Key。这个 Secret Key 只会显示一次一定复制保存。这对密钥就是 PicGo 连接 MinIO 的凭证。4.3 第三步用 PicGo 连接 MinIOPicGo 的图床设置里有一个选项专门叫“MinIO”或者“自定义 S3”。MinIO 兼容 S3 API所以本质上使用 S3 类型的配置就可以。需要填写的项目包括服务地址Endpoint如果你直接用 IP如http://服务器IP:9000如果有域名和反向代理如https://images.example.com。存储桶名填写刚才创建的md-images。Access Key ID 和 Secret Access Key填写上一步创建的密钥。区域RegionMinIO 默认可以不填或者填us-east-1不会影响正常使用。自定义域名如果设置了反向代理这部分填代理后的域名保证生成的图片链接是可控的域名而不是带端口的 IP 形式。配置完成后一样是拖一张测试图片。上传成功后返回的链接格式类似http://服务器IP:9000/md-images/2025/02/01/xxx.png。在浏览器里打开能显示图片即大功告成。4.4 第四步给 MinIO 加一层域名反向代理如果条件允许我强烈建议用 Nginx 代理 MinIO 的 API 端口。这样链接是https://img.example.com/md-images/xxx.png看起来更专业而且未来如果你想把图床迁移到其他存储可以保持链接不变。Nginx 配置片段如下server { listen 443 ssl; server_name img.example.com; location / { proxy_pass http://127.0.0.1:9000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }这个配置对很多人来说可能是第一次接触 Nginx但实际操作并不复杂关键是理解proxy_pass把访问/路径的请求转发到了本机 9000 端口也就是 MinIO 的 API 端口。配置完成后需要重载 Nginxnginx -s reload。注意如果 MinIO 收到的请求头Host不匹配可能出现签名校验失败所以proxy_set_header Host $host;这行不要漏掉。5. 常见问题与排查技巧实录5.1 GitHub 图床图片上传成功但访问 404这个问题很典型原因通常有三种。第一种是仓库的可见性没有设为 Public检查仓库首页右上角有没有Private标签。第二种是分支名填错比如仓库默认分支是master但你在 PicGo 里填了main导致拼接出的 raw 链接路径不存在。第三种是图片路径写错尤其是自定义目录名带了多余的空格或者特殊字符。排查时把 PicGo 生成的完整链接复制到浏览器地址栏一步一步去掉路径层级就能定位是哪一层出了问题。5.2 MinIO 上传成功但访问链接报 AccessDenied这种情况几乎都出在 Bucket 的权限策略上。MinIO 默认新建的 Bucket 是私有读写直接访问 Pre-signed 之外的链接都会返回 Denied。进控制台编辑对应 Bucket 的 Access Policy 为 Public。另外一种排查思路是从上传使用的密钥反推如果 User 权限没有覆盖到这个 Bucket也会造成读权限异常。这类问题本质上是权限模型理解不透建议把读写策略拆开理解上传需要 Write 权限公开访问则是 Bucket Policy 层面的匿名读两者是独立配置的并不是上传成功就等于公开可读。5.3 MarkText 粘贴图片后没有触发上传MarkText 在粘贴图片时如果完全没有上传动效优先检查 PicGo Server 是否在正常运行。打开 PicGo 主界面右下角有一个“服务”状态灯确保是绿色。其次检查 MarkText 填写的自定义命令路径是不是正确。我遇到过一种情况MarkText 里填的路径没错但反斜杠被自动转义导致命令无法执行。解决办法是在自定义命令外层的引号内使用正斜杠实测下来兼容性更好。5.4 图片上传了但文档里的链接被截断偶尔会遇到链接插入后被 Markdown 语法错误截断的问题尤其是图片文件名里包含了空格、括号或者中文。Markdown 解析器对括号嵌套非常敏感如果链接文本内有右括号会导致图片显示失败。解决方法是上传前统一将文件命名改为英文字母和连字符比如把截图(2025-02-01 10.30.00).png改成Screenshot-20250201-103000.png。这个习惯在多种 Markdown 工具间通用成本极低收益巨大。5.5 GitHub Token 过期或权限不足GitHub Token 没有固定的过期时间只有你自己在创建时可以选择有效期但很多人设置了 30 天或 90 天有效到期后 PicGo 就一直报Bad credentials。碰到这个报错直接去 GitHub 生成新 Token替换 PicGo 里的旧 Token 即可。另外如果创建 Token 时没有勾选repo权限上传时会提示权限不足也必须回到 Token 设置里检查授权范围。5.6 MinIO 容器重启后图片丢失出现这种情况的人几乎都是部署时忽略了数据持久化。容器是一个临时运行环境如果启动命令里没有-v /data/minio:/data这个挂载项每次把容器删掉重建之前上传的图片就全部丢失。所以部署时一定要确认宿主机路径的存在并且启动命令里挂载关系要写对。如果你已经是在无挂载情况下跑了很久可以用docker cp先把容器里的数据拷贝到宿主机再重新用挂载方式启动容器这样能挽回之前的数据。6. 选型建议与长期维护心得6.1 从实际需求倒推方案用了这套组合很久之后我意识到一个最简单的选型原则图床选型不是看哪个技术更高级而是看你的图片要活多久、被谁看、多看重。如果是个人笔记图片丢了顶多重截一下不会伤筋动骨那 GitHub 免费方案完全够用。如果是技术博客读者分散在不同网络环境访问稳定性很重要GitHub 自身的 raw 链接总体可用但不同时间段和区域的表现有差异这一点要有心理预期。如果是公司内部的知识库或者产品文档图片就是生产资产必须用 MinIO 这种可控方案同时要建立备份机制。6.2 维护层面的三个习惯第一目录按时间切分。无论是 GitHub 仓库还是 MinIO Bucket我建议把所有图片放到形如年/月/日的结构里。这样不仅便于查找也能避免在目录列表上卡出大量文件。第二定期清理无用图片。写作过程中难免会上传一些最终没用上的图这些图囤积在仓库里会慢慢变成一个遥不可及的数字。每个月抽十分钟打开 GitHub 仓库或者 MinIO 控制台把零散的未引用图片清理掉。第三控制图片体积。截图工具默认保存的 PNG 可能有好几 MB对于博客场景来说体积偏大。建议在粘贴前先压缩到 200KB 以内色彩简单的截图用 PNG照片类内容用 JPEG这样既能保证清晰度也能减少上传时间和存储空间。6.3 关于迁移备份迁移备份是很多人忽视的话题。严格来说GitHub 图床没有提供批量导出功能哪怕你有仓库的 git 历史也需要注意仓库存在被误删、被改名、账号异常等风险虽然概率很低但一旦发生就很恼人。建议定期用git clone拉取整个图床仓库到本地或者用脚本调用 GitHub API 拉取文件列表。MinIO 在这方面有一个天然优势mc mirror命令可以镜像整个 Bucket 到本地目录或者另一个对象存储备份操作非常简单。如果你用过一段时间的 GitHub 图床后觉得不适合完全可以用脚本把仓库里的图片全部下载到本地再改装到 MinIO 上虽然路径拼接需要做一次适配但图片本身是可以完整迁移的。6.4 链接命名的可读性在图片链接的细节里有一个小习惯我特别推荐在 PicGo 的自定义路径中留一个有意义的前缀比如blog/marktext-picgo/。这样当一个文档里插入了多张图时打开仓库看到的文件是成组排列的哪几张图属于哪篇文章一目了然。如果你上传的时候全是用时间戳文件名一旦要批量修改某个文档的配图在仓库里凭文件名找图会非常痛苦。路径前缀的命名可以按主题走也可以按项目名走只要保持稳定就能长期受益。6.5 最终建议先小规模试跑再全面迁移我个人的建议是不要第一天就决定用哪一套图床然后把你所有历史图片一股脑传上去。可以先用两周时间在 GitHub 和 MinIO 各配一个测试桶随手写几篇带图笔记观察上传速度、链接稳定性、出错率。两周后你自然会有体会是不是经常出现上传失败是不是每次打开文档都要等很久而账号安全、数据私密、成本控制这些长期因素也会在实际使用中变得越来越清晰。选图床不仅是选工具更是选一套让你长期舒服的工作流。稳定大于一切顺手大于折腾这是我实验过很多方案之后最大的体会。最后再分享一个小技巧每次写完文档后手动打开纯文本预览检查所有图片链接前缀是否一致不要让一篇文章里同时出现 GitHub 链接和 MinIO 链接这种混用状态日后排查起来特别费劲。