一、使用docker
安装
1、安装
docker
sudo apt update sudo apt install -y docker.io sudo systemctl enable --now docker
2、配置自己的阿里云镜像,连接地址
3、拉取镜像
sudo docker pull minio/minio
4、创建容器
sudo docker run -d \ -p 9000:9000 \ -p 9001:9001 \ -v /mnt/data:/data \ -e "MINIO_ROOT_USER=admin" \ -e "MINIO_ROOT_PASSWORD=yourpassword" \ --name minio \ minio/minio server /data --console-address ":9001"
-p 9000
: API 端口(用于客户端访问)。-p 9001
: 控制台端口(Web 管理界面)。-v /mnt/data:/data
: 将宿主机目录挂载为存储卷(确保/mnt/data
存在)。MINIO_ROOT_USER
和MINIO_ROOT_PASSWORD
: 管理员账号密码。--console-address ":9001"
: 指定控制台端口。
5、对外开启端口
二、使用源文件安装
1、下载源文件
wget https://dl.min.io/server/minio/release/linux-amd64/minio sudo chmod +x minio sudo mv minio /usr/local/bin/
2、创建存储目录
sudo mkdir /mnt/data sudo chown -R $USER:$USER /mnt/data
3、启动
minio
服务export MINIO_ROOT_USER=admin export MINIO_ROOT_PASSWORD=yourpassword minio server /mnt/data --console-address ":9001"
4、守护进程的方式启动
nohup minio server /mnt/data --console-address ":9001" > minio.log 2>&1 &
5、设置成系统服务(可选)
[Unit] Description=MinIO After=network.target [Service] User=root Environment="MINIO_ROOT_USER=admin" Environment="MINIO_ROOT_PASSWORD=yourpassword" ExecStart=/usr/local/bin/minio server /mnt/data --console-address ":9001" [Install] WantedBy=multi-user.target
启用并启动服务
sudo systemctl enable --now minio
三、在gin
中集成minio
文件存储
1、在
minio
可视化界面创建一个Buckets
用于文件存储2、创建
AccessKeyID
和SecretAccessKey
3、安装依赖包
go get github.com/minio/minio-go/v7
4、下面实现上传、下载文件、生成文件地址的方式
package main import ( "context" "fmt" "io" "log" "net/http" "path/filepath" "time" "github.com/gin-gonic/gin" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" ) // MinIO 配置 const ( minioEndpoint = "123.xx.229:9000" // 替换为你的 MinIO 地址 minioAccessKeyID = "HZKH0JJxx8NRRASWVT" // 替换为你的 Access Key minioSecretAccessKey = "YASffM8CLzoq6zxgZjDS1N2Av4o" // 替换为你的 Secret Key minioUseSSL = false minioBucketName = "test1" // 替换为你的 Bucket 名称 ) var minioClient *minio.Client func init() { // 初始化 MinIO 客户端 var err error minioClient, err = minio.New(minioEndpoint, &minio.Options{ Creds: credentials.NewStaticV4(minioAccessKeyID, minioSecretAccessKey, ""), Secure: minioUseSSL, }) if err != nil { log.Fatalf("Failed to initialize MinIO client: %v", err) } // 检查并创建存储桶 ctx := context.Background() exists, err := minioClient.BucketExists(ctx, minioBucketName) if err != nil { log.Fatalf("Failed to check bucket existence: %v", err) } if !exists { err = minioClient.MakeBucket(ctx, minioBucketName, minio.MakeBucketOptions{}) if err != nil { log.Fatalf("Failed to create bucket: %v", err) } log.Printf("Bucket %s created successfully", minioBucketName) } } func main() { r := gin.Default() // 上传图片接口 r.POST("/upload", uploadImage) // 下载图片接口 r.GET("/download/:filename", downloadImage) // 生成30天有效的临时链接 objectName := "trailer.mp4" url, err := minioClient.PresignedGetObject(context.Background(), minioBucketName, objectName, 7*24*time.Hour, nil) if err != nil { log.Fatalf("生成链接失败: %v", err) } fmt.Println("地址", url.String()) // 启动服务 r.Run(":8080") } // 上传图片处理函数 func uploadImage(c *gin.Context) { // 从表单中获取文件 file, err := c.FormFile("file") if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // 打开文件 fileReader, err := file.Open() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } defer fileReader.Close() // 上传到 MinIO ctx := context.Background() objectName := fmt.Sprintf("%d-%s", time.Now().Unix(), file.Filename) contentType := "application/octet-stream" if filepath.Ext(file.Filename) == ".jpg" || filepath.Ext(file.Filename) == ".jpeg" { contentType = "image/jpeg" } else if filepath.Ext(file.Filename) == ".png" { contentType = "image/png" } _, err = minioClient.PutObject(ctx, minioBucketName, objectName, fileReader, file.Size, minio.PutObjectOptions{ ContentType: contentType, }) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{ "message": "Image uploaded successfully", "objectName": objectName, }) } // 下载图片处理函数 func downloadImage(c *gin.Context) { filename := c.Param("filename") // 从 MinIO 获取对象 ctx := context.Background() object, err := minioClient.GetObject(ctx, minioBucketName, filename, minio.GetObjectOptions{}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } defer object.Close() // 获取对象信息 objInfo, err := object.Stat() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // 设置响应头 c.Header("Content-Disposition", "attachment; filename="+filename) c.Header("Content-Type", objInfo.ContentType) c.Header("Content-Length", fmt.Sprintf("%d", objInfo.Size)) // 流式传输文件内容 c.Stream(func(w io.Writer) bool { _, err := io.Copy(w, object) if err != nil { return false } return true }) }