Softhub软件下载站实战开发(七):集成MinIO实现文件存储功能 🚀
本篇将详细介绍如何为Softhub软件下载站集成MinIO对象存储,实现软件文件的安全高效管理!
1. 引言
在软件下载站开发中,文件存储管理是核心功能之一。上一篇文章我们实现了软件配置面板,现在我们需要一个强大的存储解决方案来管理软件安装包。本文将展示如何集成MinIO对象存储到Softhub项目中!
为什么选择MinIO?
- ✅ 高性能对象存储
- ✅ 开源且兼容S3 API
- ✅ 简单易用的管理界面
- ✅ 支持分布式部署
2. MinIO配置详解
首先在 manifest/config/config.yaml
中添加MinIO配置:
minio:
# MinIO服务器地址
endpoint: "127.0.0.1:9000"
# 访问密钥
accessKey: "minioadmin"
# 密钥
secretKey: "12345678"
# 存储桶名称
bucket: "softhub"
# 是否使用SSL
useSSL: false
# 基础路径
basePath: "/"
3. MinIO客户端初始化
在 internal/utils/storage/minio_utils.go
中实现MinIO客户端初始化:
package storage
import (
"context"
"io"
"mime"
"path/filepath"
"strings"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/os/gtime"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/tiger1103/gfast/v3/internal/app/admin/common/config"
"github.com/tiger1103/gfast/v3/internal/app/admin/common/global"
)
// MinioDrive minio对象存储驱动
type MinioDrive struct{}
// GetClient 获取MinIO客户端(单例模式)
func (d *MinioDrive) GetClient() (*minio.Client, error) {
if global.Client != nil {
return global.Client, nil
}
client, err := minio.New(config.MINIO_ENDPOINT, &minio.Options{
Creds: credentials.NewStaticV4(
config.MINIO_ACCESS_KEY,
config.MINIO_SECRET_KEY,
""),
Secure: config.MINIO_USE_SSL,
})
global.Client = client
return global.Client, err
}
4. 文件上传实现
4.1 基础上传方法
// Upload 上传文件到MinIO
func (d *MinioDrive) Upload(ctx context.Context, file *ghttp.UploadFile) (fullPath string, md5 string, err error) {
client, err := d.GetClient()
if err != nil {
return "", "", err
}
// 计算文件MD5
md5, _ = gmd5.Encrypt(file)
ext := gfile.Ext(file.Filename)
fileName := strings.ToLower(md5 + ext)
// 按日期组织目录结构
fullPath = config.MINIO_BASE_PATH + gtime.Date() + "/" + fileName
reader, err := file.Open()
if err != nil {
return "", "", err
}
defer reader.Close()
// 设置内容类型
opts := minio.PutObjectOptions{
ContentType: mime.TypeByExtension(filepath.Ext(file.Filename)),
}
if opts.ContentType == "" {
opts.ContentType = "application/octet-stream"
}
// 执行上传
_, err = client.PutObject(
ctx,
config.MINIO_BUCKET,
fullPath,
reader,
file.Size,
opts)
return fullPath, md5, err
}
4.2 指定路径上传
// UploadWithPath 按指定路径上传文件
func (d *MinioDrive) UploadWithPath(ctx context.Context, file *ghttp.UploadFile, savePath string) error {
client, err := d.GetClient()
if err != nil {
return err
}
reader, err := file.Open()
if err != nil {
return err
}
opts := minio.PutObjectOptions{
ContentType: mime.TypeByExtension(filepath.Ext(file.Filename)),
}
if opts.ContentType == "" {
opts.ContentType = "application/octet-stream"
}
_, err = client.PutObject(
ctx,
config.MINIO_BUCKET,
savePath,
reader,
file.Size,
opts)
return err
}
5. 文件下载与删除
5.1 文件下载实现
// GetObject 获取MinIO中的文件内容
func (d *MinioDrive) GetObject(ctx context.Context, fullPath string) ([]byte, error) {
client, err := d.GetClient()
if err != nil {
return nil, err
}
obj, err := client.GetObject(
ctx,
config.MINIO_BUCKET,
fullPath,
minio.GetObjectOptions{})
if err != nil {
return nil, err
}
defer obj.Close()
data, err := io.ReadAll(obj)
if err != nil {
return nil, err
}
return data, nil
}
5.2 文件删除实现
// Remove 删除MinIO中的文件
func (d *MinioDrive) Remove(ctx context.Context, fullPath string) error {
client, err := d.GetClient()
if err != nil {
return err
}
err = client.RemoveObject(
ctx,
config.MINIO_BUCKET,
fullPath,
minio.RemoveObjectOptions{})
return err
}
6. 配置加载与初始化
在 internal/cmd/cmd.go
中添加配置加载逻辑:
func readConfig(ctx context.Context) {
// 读取MinIO配置
endpoint, _ := g.Cfg().Get(ctx, "minio.endpoint")
accessKey, _ := g.Cfg().Get(ctx, "minio.accessKey")
secretKey, _ := g.Cfg().Get(ctx, "minio.secretKey")
bucket, _ := g.Cfg().Get(ctx, "minio.bucket")
useSSL, _ := g.Cfg().Get(ctx, "minio.useSSL")
basePath, _ := g.Cfg().Get(ctx, "minio.basePath")
// 设置全局配置
config.MINIO_ENDPOINT = endpoint.String()
config.MINIO_ACCESS_KEY = accessKey.String()
config.MINIO_SECRET_KEY = secretKey.String()
config.MINIO_BUCKET = bucket.String()
config.MINIO_USE_SSL = useSSL.Bool()
config.MINIO_BASE_PATH = basePath.String()
// 确保基础路径以/结尾
if config.MINIO_BASE_PATH != "" &&
config.MINIO_BASE_PATH[len(config.MINIO_BASE_PATH)-1:] != "/" {
config.MINIO_BASE_PATH += "/"
}
}
8. 部署MinIO的Docker指南
详细minio部署方案参考docker部署MinIO对象存储实践:含控制台功能恢复方案
使用Docker快速部署MinIO:
# 创建MinIO容器
docker run -d \
-p 9000:9000 \
-p 9090:9090 \
--name minio \
-v /mnt/data:/data \
-e "MINIO_ROOT_USER=minioadmin" \
-e "MINIO_ROOT_PASSWORD=12345678" \
minio/minio server /data --console-address ":9001"
访问管理界面:http://localhost:9001
创建softhub的bucket,用于存储软件相关数据
11. 总结
通过本文,我们完成了:
- ✅ MinIO集成 - 配置并初始化MinIO客户端
- ✅ 文件上传 - 实现文件上传到MinIO存储桶
- ✅ 文件管理 - 实现文件的下载和删除
- ✅ 部署指南 - Docker快速部署MinIO服务
MinIO的集成大大提升了Softhub的文件管理能力,为后续实现软件版本管理、下载统计等功能奠定了基础。
softhub系列往期文章