使用Go操作Docker上的MinIO | 青训营笔记

前言

在一个项目成员的推荐下,我们都决定采用利使用Docker的容器来连接虚拟数据库以及后端开发代码等等,队伍最近给我分配的工作---开发视频投稿API我还没什么头绪,队友今天跟我说可以在 Docker 上部署并用于存储和管理对象数据,类似于云存储服务,于是我便上网查资料,最终决定使用MinIO容器来进行这个操作。

花了我将近一天的时间,踩了无数的坑,才完成视频投稿这个功能并测试成功,现在我就来分享一下我的实践过程。

前置工作

安装Docker

如果你还没安装Docker,请先安装好Docker引擎,以便在容器中运行MinIO。

Windows:docs.docker.com/desktop/ins...

MacOS:docs.docker.com/desktop/ins...

环境搭建

想法是用docker-compose部署,简单又方便。搭建minio服务,容器可以直接从Docker Hub的官方镜像拉取。

配置docker-compose.yaml文件

在项目的根目录新建一个文件:docker-compose.yaml

yaml 复制代码
version: '3'

services:
  minio:
    image: quay.io/minio/minio
    volumes:
      - ./minio_data:/data
    ports:
      - "9000:9000"
      - "9090:9090"
    environment:
      MINIO_ROOT_USER: user
      MINIO_ROOT_PASSWORD: password
    command: server /data --console-address ":9090"

volumes:
  minio_data:

解释

  • services: 这是一个包含了你要运行的 Docker 服务的部分。这里是个名为 "minio" 的服务。
  • image: 这是要使用的 Docker 镜像的名称,使用了 MinIO 官方镜像。
  • volumes: 这里定义了卷的映射关系。将本地文件夹 ./minio_data 映射到容器内的 /data 文件夹。这样做可以使 MinIO 存储数据在主机和容器之间共享。
  • ports: 定义了端口映射关系,将容器内的端口映射到主机上。在这里,容器的 9000 端口映射到主机的 9000 端口,而容器的 9090 端口映射到主机的 9090 端口。
  • environment: 设置环境变量,这里定义了 MinIO 根用户的用户名和密码。
  • command: 定义容器启动时运行的命令。在这里,MinIO 服务器会在 /data 文件夹上启动,并监听容器内的 9090 端口用于控制台。
  • volumes: 定义了卷部分,但是省略了卷的配置。

我遇到的坑

MinIO官方的默认端口是9000,但是我的ports只设置为"9000:9000"的话始终无法打开http://localhost:9000/这个网页,问了一下队友,他就给了我这个意见,注意除了修改port还要在command一列添加--console-address ":9090",还有一个坑就是一开始我启动程序成功后没几秒钟minio服务就自动退出了,而且没有报任何错误,后来我又是在 command一列加上server /data解决了这个问题,短短一个配置文件我就遇到了两个坑,真的好难受呢。

编写代码

好了,完成上面那几个步骤之后我终于是成功的启动了minio服务并且不会自动关闭,这里贴个图:

Running Running Running

甚至还可以打开它的默认网页了:

(注意这里我输入9000或者输入9090都是这个界面,因为会自动跳转过来)

接下来开始编写代码了。

首先获取前端传来的视频数据并处理错误:

css 复制代码
videoFile, err := c.FormFile("data")

这里的坑只有一个,也算不上坑可能是我傻,就是获取data需要使用c.FormFile()

接着开始处理视频数据

  1. 将视频保存在本地文件
go 复制代码
// 创建视频存储路径---/temp/videos
storagePath := filepath.Join("temp", "videos")
os.MkdirAll(storagePath, os.ModePerm)

// 保存视频至本地
videoFilePath := filepath.Join(storagePath, videoFile.Filename)
err := c.SaveUploadedFile(videoFile, videoFilePath)
  1. 连接上MinIO服务
css 复制代码
minioClient, err := minio.New("192.168.10.10:9000", &minio.Options{
   Creds:  credentials.NewStaticV4("ROOTUSER", "CHANGEME123", ""),
   Secure: false,
})

我遇到的坑

注意第一行192.168.10.10:9000这里我填入的是自己的IP地址,我一开始用的localhost结果一直连不上,换了几个地址终于连上了,但是关于这个应该还有更优的写法,我今天累了,就不探索了。

  1. 创建存储桶
css 复制代码
// 设置存储桶名称
bucketName := "videos"
// 检查存储桶是否存在,如果不存在则创建
found, err := minioClient.BucketExists(c.Request.Context(), bucketName)
if !found {
   err := minioClient.MakeBucket(c.Request.Context(), bucketName, minio.MakeBucketOptions{})
   }
  1. 上传视频至MinIO
css 复制代码
objectName := fmt.Sprintf("%d/%s.mp4", user_id, title)
n, err := minioClient.FPutObject(c.Request.Context(), bucketName, objectName, videoFilePath, minio.PutObjectOptions{
   `ContentType`: "video/mp4",
})

这里的objectName就是我想存放视频的地址,user_idtitle决定了这个视频的唯一性,并且每个人的视频按文件夹分开存储,ContentType表示我存的数据是视频类型。

  1. 生成视频链接
css 复制代码
presignedURL, err := minioClient.PresignedGetObject(c.Request.Context(), bucketName, objectName, time.Hour*24, nil)

由于我不会获取视频存放到MinIO后的地址,所以我干脆生成一个地址来存放。

  1. 添加到数据库
css 复制代码
// 在数据库中创建新的视频记录
newVideo := models.Video{
   UserID:      user_id,
   Title:       title,
   PlayUrl:     playUrl,
   CoverUrl:    coverUrl,
   PublishTime: time.Now(),
}
db := c.MustGet("db").(*gorm.DB)
db.Create(&newVideo)

软件测试

现在就可以在抖声上运行测试了,下面是我测试的样子:

视频里是我两个室友,OK,今天的分享到此结束了。

感谢观看!!!

相关推荐
千慌百风定乾坤9 小时前
Go 语言入门指南:基础语法和常用特性解析(下) | 豆包MarsCode AI刷题
青训营笔记
FOFO9 小时前
青训营笔记 | HTML语义化的案例分析: 粗略地手绘分析juejin.cn首页 | 豆包MarsCode AI 刷题
青训营笔记
滑滑滑2 天前
后端实践-优化一个已有的 Go 程序提高其性能 | 豆包MarsCode AI刷题
青训营笔记
柠檬柠檬2 天前
Go 语言入门指南:基础语法和常用特性解析 | 豆包MarsCode AI刷题
青训营笔记
用户967136399652 天前
计算最小步长丨豆包MarsCodeAI刷题
青训营笔记
用户52975799354723 天前
字节跳动青训营刷题笔记2| 豆包MarsCode AI刷题
青训营笔记
clearcold3 天前
浅谈对LangChain中Model I/O的见解 | 豆包MarsCode AI刷题
青训营笔记
夭要7夜宵4 天前
【字节青训营】 Go 进阶语言:并发概述、Goroutine、Channel、协程池 | 豆包MarsCode AI刷题
青训营笔记
用户336901104444 天前
数字分组求和题解 | 豆包MarsCode AI刷题
青训营笔记
dnxb1234 天前
GO语言工程实践课后作业:实现思路、代码以及路径记录 | 豆包MarsCode AI刷题
青训营笔记