前言
在一个项目成员的推荐下,我们都决定采用利使用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()
。
接着开始处理视频数据
- 将视频保存在本地文件
go
// 创建视频存储路径---/temp/videos
storagePath := filepath.Join("temp", "videos")
os.MkdirAll(storagePath, os.ModePerm)
// 保存视频至本地
videoFilePath := filepath.Join(storagePath, videoFile.Filename)
err := c.SaveUploadedFile(videoFile, videoFilePath)
- 连接上
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
结果一直连不上,换了几个地址终于连上了,但是关于这个应该还有更优的写法,我今天累了,就不探索了。
- 创建存储桶
css
// 设置存储桶名称
bucketName := "videos"
// 检查存储桶是否存在,如果不存在则创建
found, err := minioClient.BucketExists(c.Request.Context(), bucketName)
if !found {
err := minioClient.MakeBucket(c.Request.Context(), bucketName, minio.MakeBucketOptions{})
}
- 上传视频至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_id
和title
决定了这个视频的唯一性,并且每个人的视频按文件夹分开存储,ContentType
表示我存的数据是视频类型。
- 生成视频链接
css
presignedURL, err := minioClient.PresignedGetObject(c.Request.Context(), bucketName, objectName, time.Hour*24, nil)
由于我不会获取视频存放到MinIO后的地址,所以我干脆生成一个地址来存放。
- 添加到数据库
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,今天的分享到此结束了。