图床,是每个 Markdown 写作者绕不开的一道坎。用别人的图床(SM.MS、七牛、腾讯云 COS、阿里云 OSS)要么有流量/容量限制,要么要花钱,要么担心哪天服务关停。自建图床——把图片存到自己的服务器上,一劳永逸,数据完全在自己手里。
本文手把手带你用MinIO(自托管对象存储) + PicGo(上传工具) + Typora(编辑器)搭建一套属于自己的图床,并重点解决一个新手必踩的坑:图片明明上传成功了,Typora 里却死活不显示
目录
一、整体架构:先搞懂图片是怎么"流"的
二、环境准备:Docker 部署新版 MinIO
2.1 拉取并启动 MinIO
2.2 确认部署成功
三、创建 Bucket
四、安装并配置 PicGo
4.1 安装 PicGo
4.2 安装 MinIO 插件
4.3 配置 MinIO 图床
五、配置 Typora 关联 PicGo
六、测试上传
七、核心问题排查:上传成功但图片不回显
7.1 先做一个"一锤定音"的测试
7.2 主因:Bucket 是 PRIVATE,匿名读被拒绝
7.3 解决办法:把 Bucket 设为"匿名可下载"
7.4 用 MinIO Client(mc)命令行设置匿名下载
7.5 其他可能的原因
7.6 为什么用 DOWNLOAD,而不是 PUBLIC?
一、整体架构:先搞懂图片是怎么"流"的
关键点:这个链路里有两个完全不同的动作——
上传(PUT):PicGo 拿着你的
AccessKey/SecretKey认证,所以能写进去;读取(GET):浏览器打开图片 URL 时是匿名的,没有任何认证信息。
"上传成功但不回显"的根因,几乎总是出在第二步——Bucket 不允许匿名读取。
二、环境准备:Docker 部署新版 MinIO
MinIO 是一个开源、兼容 Amazon S3 协议的对象存储服务,轻量、部署简单,非常适合做图床后端。本文以新版 MinIO + Docker为例(旧版和新版在端口、控制台界面上有差异,注意区分)。
2.1 拉取并启动 MinIO
在服务器上执行(docker权限不够时前面加sudo):
docker run -d \ --name minio \ --restart unless-stopped \ -p 19000:9000 \ -p 19001:9090 \ -e MINIO_ROOT_USER=minioadmin \ -e MINIO_ROOT_PASSWORD=你的密码 \ -v /data/minio:/data \ minio/minio server /data --console-address ":9090"参数说明:
| 参数 | 含义 |
|---|---|
-p 19000:9000 | 把宿主机的19000映射到容器的 S3API 端口9000(PicGo 上传、浏览器访问图片都走它) |
-p 19001:9090 | 把宿主机的19001映射到容器的Console 控制台端口9090(Web 管理界面) |
MINIO_ROOT_USER/MINIO_ROOT_PASSWORD | 管理员账号密码(新版统一用这两个环境变量,旧的MINIO_ACCESS_KEY/MINIO_SECRET_KEY已废弃) |
-v /data/minio:/data | 数据持久化,把数据挂到宿主机,容器删了数据还在 |
划重点:新版 MinIO 的默认端口是API
9000、Console9090。上面的例子我映射成了19000/19001只是演示,你可以用任何端口,但后面 PicGo 里填的 endpoint 必须对应 API 端口(这里即19000),不是 Console 端口。填错端口是最常见的低级错误之一。
如果你的服务器上有可视化控制面板,会更简单。
2.2 确认部署成功
浏览器访问 Console 控制台:
http://你的服务器IP:19001用 username/ password登录,能看到控制台就说明 MinIO 跑起来了。
注意:如果访问不了,先检查云服务器安全组是否放行了19000、19001这两个端口,以及防火墙(firewalld/ufw)是否拦截。这步不通,后面全白搭。
三、创建 Bucket
Bucket 就是"放图片的文件夹"。在新版MinIO Console 左侧点击Buckets → Create Bucket:
Bucket Name:typora(名称全局唯一,且一旦创建不可改,建议用小写字母)
创建完,Bucket 列表里会出现一个typora,它的Access(访问策略)默认是PRIVATE
四、安装并配置 PicGo
4.1 安装 PicGo
PicGo 是一款开源免费的图床工具,支持 Windows / macOS / Linux。
https://github.com/Molunerfinn/PicGo
4.2 安装 MinIO 插件
PicGo 原生并没有内置 MinIO 图床,所以我们需要去下载插件。
安装后重启 PicGo,在图床列表就能看到MinIO
4.3 配置 MinIO 图床
endPoint填写你的服务器ip地址或域名
port填写你部署的MinIO占用的端口
useSSL根据前面的endPoint选择,如果是https的话,就是yes,反之是no
accessKey填写你的MinIO的账号(用户名)
secretKey填写你的MinIO的密码
bucket填写你创建的“桶”名
不同插件的字段命名可能略有差异(有的叫
endpoint,有的拆成server/port),以你实际安装的插件界面为准
填完记得保存,并把 MinIO 设为默认图床(图床设置里点"设为默认")。
五、配置 Typora 关联 PicGo
打开 Typora →文件 → 偏好设置 → 图像;
"插入图片时…"选择上传图像;
勾选对本地位置的图片应用上述规则、对网络位置的图片应用上述规则;
"上传服务设定"选择PicGo (app);
"PicGo 路径"填 PicGo 的安装路径。
六、测试上传
在 Typora 里粘贴一张图片,如果右下角弹出"上传成功",并且去看 MinIO 的 Bucket 里确实多出了文件,说明PicGo → MinIO 这一段已经通了。
但重点来了:此时 Typora 里的图片可能依然是一片裂图 / 空白。这就是本文要解决的核心问题。
七、核心问题排查:上传成功但图片不回显
7.1 先做一个"一锤定音"的测试
把 Typora 里生成的那串图片 URL 直接复制到浏览器地址栏打开:
http://你的IP:19000/typora/20260901092717125.png
会出现三种结果,对应三种病因:
| 现象 | 结论 |
|---|---|
| ✅ 图片直接显示 | MinIO 权限、PicGo 都正常,问题在 Typora 侧 |
❌ 显示AccessDenied | Bucket 权限问题 |
| ❌ 打不开 / 超时 | 安全组 / 端口 / 反向代理问题 |
7.2 主因:Bucket 是 PRIVATE,匿名读被拒绝
AccessDenied的原因 99% 是:Bucket 的 Access 策略还是默认的PRIVATE。
前面说过,上传走的是认证 PUT,能成功;但浏览器读取是匿名 GET,`PRIVATE` 不允许任何匿名访问,于是 MinIO 直接拒绝,图片自然显示不出来。
一句话总结:上传成功 ≠ 能公开读取。
7.3 解决办法:把 Bucket 设为"匿名可下载"
去 MinIO 控制台,找到typora这个 Bucket 的Access Policy(访问策略 / 匿名访问),把它从PRIVATE改成DOWNLOAD。
新版 MinIO Console 已经不在 Bucket 页面上直接提供这个切换入口了(旧版有),所以新手常在这里迷路。没关系,用命令行
mc更稳妥、也更通用。
7.4 用 MinIO Client(mc)命令行设置匿名下载
这里有个大坑,先预警:Linux 上有两个东西都叫mc——
如果你直接在服务器敲mc anonymous set download ...,很可能会启动那个蓝色的文件管理器,而不是 MinIO 客户端,导致"命令看似执行了,其实什么都没改"。解决方式是避开这个命令冲突,推荐直接用 Docker 跑 MinIO Client,干净又不污染系统:
sudo docker run --rm -it --entrypoint /bin/sh minio/mc进入容器后(提示符变成sh-5.1#之类),依次执行:
# ① 确认现在用的是真正的 MinIO Client mc --version # 应该显示 "mc version ...",而不是 "GNU Midnight Commander" # ② 配置你的 MinIO 连接(alias 起个名字,这里叫 minio) mc alias set minio http://你的IP:19000 # 然后按提示输入 Access Key 和 Secret Key # ③ 验证连接是否成功(可选) mc admin info minio # ④ 设置 typora 这个 Bucket 允许匿名下载 mc anonymous set download minio/typora # ⑤ 验证权限已生效 mc anonymous get minio/typora # 应该输出:Access permission for `minio/typora` is `download`Docker 提示
permission denied ... /var/run/docker.sock?说明当前用户没权限访问 Docker 守护进程。要么每次前面加sudo,要么执行sudo usermod -aG docker $USER后退出重新登录 SSH即可。
7.5 其他可能的原因
如果权限改完浏览器还是打不开,依次检查:
云服务器安全组:是否放行 API 端口
19000(TCP 入方向);Docker 端口映射:
-p 19000:9000是否映射正确,用docker ps确认;HTTP / HTTPS 混合内容:如果你的 Typora 页面环境是 HTTPS,却引用
http://的图片,浏览器会因"混合内容"拦截而加载失败。图床方案里尽量给 MinIO 配 HTTPS。
7.6 为什么用DOWNLOAD,而不是PUBLIC?
MinIO 的匿名策略有四档:
| 策略 | 匿名读(GET) | 匿名写(PUT) | 说明 |
|---|---|---|---|
none(PRIVATE) | ❌ | ❌ | 完全私有,任何人匿名都不能访问 |
download | ✅ | ❌ | 只允许匿名下载/读取 |
upload | ❌ | ✅ | 只允许匿名上传 |
public | ✅ | ✅ | 读写都开放 |
做图床,我们要的是"别人能看图片,但不能随便往你 Bucket 里传东西",所以
DOWNLOAD是唯一正确选择。设成public等于把桶完全敞开,谁都能往里写文件,有被塞垃圾文件甚至被滥用的风险,切勿。
写在最后
本文是博主在配置Typora+PicGo+MinIO时踩的坑,写作时查阅了大量公开资料与文献,力求内容准确。若有疏漏或表述不当之处,欢迎大家指正,也请多多包涵~
如果这篇笔记对你有帮助,欢迎点赞 👍、收藏 ⭐、关注 🔔,你的支持是我继续更新的最大动力
往期文章
Linux 学习笔记 04 番外:用户权限典型场景实操
Linux 学习笔记 04:一文读懂 Linux 用户与权限管理
响应式之道 —— 媒体查询、容器查询与多列布局
打破常规 —— CSS 定位与层叠上下文全解
二维布局之王 —— CSS Grid 完全指南