天覆云搭建 MinIO 作为 S3 存储对接附件
本文记录一种常见方案:以 Ubuntu 24.04 上自建 MinIO,作为 S3 兼容对象存储,然后让附件读写切换到 MinIO。同时也说明已有平台附件如何从原存储迁移到新 MinIO 中。
一、整体架构
切换前:
1 | 天覆云 |
切换后:
1 | 天覆云 |
天覆云文件服务会通过 S3 协议访问 MinIO。只要对象的 bucket 映射和文件 key 保持一致,已有附件通常不需要修改数据库,只需要把对象文件迁移过去,并正确配置 s3-config.json。
二、准备信息
假设环境如下:
1 | 服务器:<SERVER_IP> |
注意:
9000是 S3 API 端口,给天覆云程序访问。9001是 MinIO Web Console 管理端口,给管理员浏览器访问。- 天覆云的
bucketEndPoint必须填写 S3 API 地址,不要填写 Console 地址。 - 如果你对外映射了其他端口,例如
5405:9000,那配置里就要写http://<MINIO_SERVER_IP>:5405。
三、安装 Docker 和 Docker Compose
Ubuntu 24.04 推荐使用 Docker 官方 APT 源安装 Docker Engine 和 Compose 插件。
1 | sudo apt update |
四、部署 MinIO
创建目录:
1 | sudo mkdir -p /data/minio/data |
创建 .env 文件:
1 | sudo tee .env >/dev/null <<'EOF' |
生产环境请务必把 MINIO_ROOT_PASSWORD 改成高强度密码。
创建 docker-compose.yaml:
1 | sudo tee docker-compose.yaml >/dev/null <<'EOF' |
启动 MinIO:
1 | sudo docker compose up -d |
验证 MinIO API:
1 | curl -I http://127.0.0.1:9000/minio/health/live |
如果返回 HTTP/1.1 200 OK,说明 MinIO API 正常。
浏览器访问:
1 | http://<MINIO_SERVER_IP>:9001 |
登录账号密码就是 .env 里的:
1 | MINIO_ROOT_USER |
五、天覆云需要哪些 bucket
天覆云当前主要使用 4 个逻辑 bucket:
1 | mdmedia |
六、配置对接 MinIO
在服务器上,找到微服务目录。常见路径是:
1 | cd /data/mingdao/script |
创建 S3 配置目录:
1 | mkdir -p /data/mingdao/script/volume/s3 |
创建 s3-config.json:
1 | tee /data/mingdao/script/volume/s3/s3-config.json >/dev/null <<'EOF' |
这里有两个非常重要的点。
第一,bucketEndPoint 要带协议:
1 | "bucketEndPoint": "http://<MINIO_SERVER_IP>:9000" |
如果你的 MinIO 没有配置 HTTPS,就不要写 https://。
第二,自建 MinIO 使用 IP 地址访问时,必须加:
1 | "addressingModel": 1 |
这个参数会让天覆云使用 path-style 访问方式:
1 | http://<MINIO_SERVER_IP>:9000/mdmedia/xxx.jpg |
如果不加这个参数,程序可能会自动把 bucket 拼到 endpoint 前面,变成:
1 | http://bucketName.<MINIO_SERVER_IP>:9000/xxx.jpg |
如果 endpoint 是 IP 地址,就会出现类似这样的 DNS 错误:
1 | lookup mdmedia.192.168.1.10 on 127.0.0.11:53: no such host |
七、挂载 s3-config.json 到 sc 容器
编辑 docker-compose.yaml,找到 sc 服务,添加挂载:
1 | services: |
核心是这一行:
1 | - ./volume/s3/s3-config.json:/usr/local/file/s3-config.json |
天覆云文件服务会从容器内的这个路径读取 S3 配置:
1 | /usr/local/file/s3-config.json |
修改后重启微服务:
1 | cd /home/skyinfor/mdy |
验证配置是否已经挂载进容器:
1 | docker exec -it script-sc-1 sh -lc 'cat /usr/local/file/s3-config.json' |
八、验证新附件是否写入 MinIO
1、进入平台页面,上传一个附件或图片,然后在 MinIO web界面中查看对应 bucketName下 是否出现新文件。如果新上传的文件已经进入 MinIO,说明附件已经成功切换到自建 S3 存储。
2、登录平台查看头像,应用icon是否正常显示
九、已有天覆云附件如何迁移到新 MinIO
如果是已经运行了一段时间的天覆云,切换 S3 前必须迁移历史附件。迁移原则是:
1 | 1、内网/公网之间网络互通 |
前置条件
1、检查单机版本老环境的 kafka 队列有无消息堆积
1 | docker exec -it $(docker ps | grep mingdaoyun-sc | awk '{print $1}') bash |
2、检查当前容器内是否有 minio 进程
1 | ps aux|grep [m]inio |
- 如果有输出,代表当前容器内运行的文件存储服务是 V2 版本
- 如果没有输出,代表代表当前容器内运行的文件存储服务是 V1 版本
- 后续迁移文件存储服务时,V1 与 V2 的迁移步骤会有不同
3、检查 kafka 工作流队列有无堆积1
/usr/local/kafka/bin/kafka-consumer-groups.sh --bootstrap-server ${ENV_KAFKA_ENDPOINTS:=127.0.0.1:9092} --describe --group md-workflow-consumer | awk '{count+=$6}END{print count}'
- 仅输出 0 代表无堆积,可以立刻停止微服务
- 输出的数字大于 0 代表当前队列中有工作流消息待消费
- 如果在队列中有未消费的数据时停止了微服务,在做完数据迁移,新环境会有某些工作流一直显示排队数字不消失,这些显示排队的流程不会继续消费
在安装管理器所在目录执行停止微服务命令
1 | cd /home/skyinfor/mdy |
启动临时容器
单独启动挂载数据目录的容器
1 | docker run -itd --entrypoint bash --rm -v /data/mingdao/script/volume/data/:/data/ 788b6f437789 |
- 788b6f437789 为存储组件
sc的镜像ID,可通过docker images查看
进入刚启动的临时容器
1 | docker exec -it 363625b14db6 bash |
在临时容器内分别启动 mysql、mongodb、file
1 | source /entrypoint.sh && mysqlStartup & |
如果容器内运行的文件存储服务是 V2 版本,也要额外启动下 minio 服务
1 | echo "127.0.0.1 sc" >> /etc/hosts |
1. 使用 mc 迁移 bucket
在临时创建的容器内配置集群环境文件存储信息
1 | mc alias set minio_old http://127.0.0.1:9010 mdstorage eBxExGQJNhGosgv5FQJiVNqH |
- minio_old 中的地址、认证信息无需修改
- minio_new 中的IP与端口及认证信息注意替换为实际新环境的 minio 服务的访问地址与认证信息
开始迁移:
1 | mc mirror minio_old/mdmedia minio_new/you_bucketName |
十、常见问题排查
1. 报错:lookup bucket.ip on 127.0.0.11 no such host
例如:
1 | lookup jsmdy.10.250.1.162 on 127.0.0.11:53: no such host |
原因是程序使用了 virtual-host-style,把 bucket 拼到了 endpoint 前面:
1 | jsmdy.10.250.1.162 |
IP 地址不能这样解析。
解决方法是在 s3-config.json 中增加:
1 | "addressingModel": 1 |
并确保 endpoint 是:
1 | "bucketEndPoint": "http://10.250.1.162:9000" |
2. 报错:wrong version number
通常是把 HTTP 的 MinIO 配成了 HTTPS。
例如 MinIO 实际是:
1 | http://10.250.1.162:9000 |
但配置成了:
1 | https://10.250.1.162:9000 |
解决方法:没有配置 TLS 时,bucketEndPoint 使用 http://。
3. 连接失败 connection refused
检查端口是不是写错了。
MinIO 默认:
1 | 9000:S3 API |
天覆云要访问的是 S3 API 端口,不是 Console 端口。
4. AccessDenied 或 SignatureDoesNotMatch
通常是以下原因:
- access key 写错
- secret key 写错
- bucket 权限不足
- endpoint 写错
- 服务器时间偏差太大
可以先在服务器或 sc 容器内测试:
1 | curl -I http://<MINIO_SERVER_IP>:9000/minio/health/live |
再用 mc 测试账号是否能访问:
1 | mc alias set new http://<MINIO_SERVER_IP>:9000 <ACCESS_KEY> <SECRET_KEY> |
十一、生产环境建议
- 不要在公网暴露 MinIO Console,或者至少限制访问 IP。
- MinIO root 账号只用于管理,建议使用单独的 access key。
- MinIO 数据目录要做磁盘监控和备份。
- 切换 S3 前,先完整迁移历史附件。
- 切换后上传、预览、下载都验证无误,再下线旧文件存储。
- 使用 IP 访问自建 MinIO 时,一定要配置
"addressingModel": 1。 bucketEndPoint一定要写 S3 API 地址,不要写 MinIO Console 地址。
十二、最终配置示例
MinIO 使用 4 个独立 bucket 时,推荐配置如下:
1 | { |
如果 MinIO API 通过宿主机端口映射成了 5405,则写成:
1 | "bucketEndPoint": "http://<MINIO_SERVER_IP>:5405" |
记住:这里必须是 API 端口,不是 Console 端口。迁移完成后重启微服务,访问平台即可。