为什么要给 MinIO 配置子域名、HTTPS 和 Nginx 反向代理?
很多同学第一次部署 MinIO 时,都是直接通过 IP + 端口访问,例如:
http://123.123.123.123:9000
上传图片后,数据库中保存的图片地址也是:
http://123.123.123.123:9000/weblog/20250101/test.jpg
开发环境这样做没有问题,但是到了生产环境,这种方式并不推荐。
那么,为什么很多项目都会给 MinIO 配置一个子域名,再通过 Nginx 配置 HTTPS 和反向代理呢?
本文就带大家理解其中的原因。
一、开发环境为什么直接使用 IP?
MinIO 安装完成后,默认会监听:
9000
例如:
http://服务器IP:9000
浏览器访问:
http://123.123.123.123:9000
即可进入 MinIO。
上传图片以后,数据库保存的图片地址也是:
http://123.123.123.123:9000/weblog/a.jpg
整个流程非常简单。
开发阶段为了方便调试,通常都会采用这种方式。
二、为什么生产环境不建议这样做?
虽然可以正常访问,但它存在几个明显的问题。
1、图片地址不够规范
例如:
http://123.123.123.123:9000/weblog/logo.png
相比之下:
https://img.example.com/weblog/logo.png
显然更加专业。
对于正式网站来说,图片一般都会使用独立的图床域名。
例如:
www.example.com
负责博客。
而:
img.example.com
负责图片资源。
这样职责更加清晰,也方便后续维护。
2、容易出现 HTTPS 混合内容问题
假设博客已经开启 HTTPS:
https://www.example.com
但是图片仍然来自:
http://123.123.123.123:9000
浏览器就会认为:
HTTPS 页面加载 HTTP 资源。
这种情况被称为 Mixed Content(混合内容)。
现代浏览器通常会阻止这类请求,最终导致:
网页正常打开
↓
图片加载失败
因此,图片资源也应该使用 HTTPS。
3、直接暴露 MinIO 端口存在安全风险
很多人安装完成 MinIO 后,会直接开放:
9000
公网任何人都可以访问。
例如:
http://服务器IP:9000
虽然设置了账号密码,但直接暴露对象存储服务始终存在安全隐患,例如:
- 被扫描端口;
- 被暴力破解;
- 利用漏洞进行攻击。
因此,生产环境通常不会直接开放 MinIO 服务端口。
三、生产环境一般怎么部署?
最常见的方案就是:
给 MinIO 配置一个专门的子域名。
例如:
www.example.com
用于博客。
而:
img.example.com
用于图片资源。
之后所有图片地址都会变成:
https://img.example.com/weblog/logo.png
用户访问图片时,也不会知道 MinIO 实际运行在哪个端口。
四、为什么还需要 Nginx?
很多同学会问:
既然有了子域名,为什么还需要 Nginx?
原因很简单。
MinIO 默认提供的是:
HTTP
并不负责 SSL 证书。
而真正处理 HTTPS 的,一般都是:
Nginx
整体访问流程如下:
浏览器
│
HTTPS
▼
img.example.com
│
▼
Nginx
│
HTTP
▼
MinIO(9000)
浏览器实际上访问的是:
443
Nginx 收到请求之后,再转发给 MinIO。
这就是所谓的反向代理。
Nginx 配置通常如下:
server {
listen 443 ssl;
server_name img.example.com;
ssl_certificate /etc/nginx/cert/img.pem;
ssl_certificate_key /etc/nginx/cert/img.key;
location / {
proxy_pass http://172.17.0.1:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
这里最重要的一句就是:
proxy_pass http://172.17.0.1:9000;
表示:
收到图片请求后,由 Nginx 转发给 MinIO。
五、为什么后端项目也要修改?
很多项目都会在配置文件中保存 MinIO 地址,例如:
minio:
endpoint: http://123.123.123.123:9000
上传图片后,数据库保存的就是:
http://123.123.123.123:9000/weblog/a.jpg
如果已经切换到了图床域名,就应该修改为:
minio:
endpoint: https://img.example.com
这样新上传的图片都会保存成:
https://img.example.com/weblog/a.jpg
以后访问图片时,全部通过域名即可。
六、为什么最后要关闭 9000 端口?
这是很多人容易忽略的一步。
如果已经通过:
https://img.example.com
访问图片,那么:
9000
其实已经不需要对公网开放了。
正确的访问路径应该是:
浏览器
│
▼
443
│
▼
Nginx
│
▼
9000(服务器内部)
│
▼
MinIO
也就是说:
9000 只允许服务器内部访问。
如果公网仍然可以访问:
http://服务器IP:9000
那么别人依然可以绕过 Nginx,直接访问 MinIO。
因此,生产环境建议关闭安全组中的 9000 端口,只保留:
- 80(HTTP,可选)
- 443(HTTPS)
这样整体安全性会更高。
七、为什么还要修改数据库中的旧图片?
如果之前数据库保存的是:
http://123.123.123.123:9000/weblog/a.jpg
关闭 9000 后:
浏览器
↓
访问旧地址
↓
图片无法加载
因此需要批量把旧图片地址修改为:
https://img.example.com/weblog/a.jpg
这样历史数据才能正常访问。
八、整体架构
整个部署完成后,图片访问流程如下:
浏览器
│
▼
https://img.example.com
│
▼
Nginx(SSL)
│
反向代理
▼
MinIO(9000)
│
▼
对象存储
浏览器始终不知道 MinIO 实际运行在哪个端口。
真正暴露到公网的,只有 Nginx。
九、总结
很多人以为给 MinIO 配置子域名只是为了让图片地址更好看,其实真正的目的远不止如此。
通过 子域名 + HTTPS + Nginx 反向代理,可以获得以下几个好处:
- 使用独立图床域名,图片地址更加规范;
- 全站支持 HTTPS,避免浏览器混合内容问题;
- 利用 Nginx 统一管理 SSL 证书;
- 隐藏 MinIO 的真实访问地址,提高安全性;
- 关闭 MinIO 公网端口,减少被攻击的风险;
- 后续即使更换 MinIO 部署方式,也无需修改前端图片访问地址。
因此,在生产环境中,MinIO 并不是直接对外提供服务,而是作为对象存储运行在 Nginx 后面。这也是目前大多数博客系统、企业项目和对象存储服务的常见部署方式。