一、Minio 简介
Minio 是一个开源(AGPL v3.0)的对象存储出服务器,使用 Minio 可以轻松搭建与 Amazon S3 API 兼容的存储对象。
二、Minio 技术架构
基于 GoLang 的 Minio 采用分布式架构设计。轻量、高性能,可以在单个或者多个分布式集群上运行。
三、Minio 资源
四、支持多种安装方式
- 🍀docker(padman)
- 🍀本地安装(linux)
- 🍀源码安装
- 🍀客户端(Java)
- 🍀...
五、使用 docker 构建 Minio 服务
sh
docker pull minio/minio
docker run -p 9000:9000 \
-p 9001:9001 \
-e "MINIO_ROOT_USER=your_username" \
-e "MINIO_ROOT_PASSWORD=your_password" \
-e "MINIO_ACCESS_KEY=your_access_key" \
-e "MINIO_SECRET_KEY=your_secret_key" \
-v /path/to/local/directory:/data \
--name minio_server \
minio/minio server /data
-p
指定端口9000/9001
两个对外暴露的端口-e
指定环境变量access_key
和secret_key
以及根用户
的用户名和密码-v
指定卷地址与本地进行映射(很有必要)--name
指定容器名字minio/minio server /data
指定启动时运行的命令,和数据挂载地址
六、Minio 管理端
七、界面
以下是 Minio 的界面,还没有使用 Minio 可以更加直观感受:
- 版本:
本文使用最近的 latest 版本,也可以在 minio 下更加自己需要的 tag 进行选择。
- 登录
- browser
- Access Keys 管理
- Bucket 管理
- 指标
八、mc 命令行
mc 处理提供 HTTP 服务外,也提供了 Cli 命令行工具,大多也是对bucket、object 等相关的操作:
九、Minio 客户端
在配置好了之后,开发者关注的就是其实更多应该是客户端。
9.1) 以 JavaScript 客户端
sh
npm install --save minio
js
import * as Minio from 'minio'
const minioClient = new Minio.Client({
endPoint: 'play.min.io',
port: 9000,
useSSL: true,
accessKey: 'your_accessKey',
secretKey: 'your_secretKey',
})
9.2) 客户端操作类型
类别 | 英文名 | 操作 |
---|---|---|
桶操作 | Bucket operations | 创建桶,删除桶,列出桶,获取桶属性,设置桶权限,修改桶策略,配置桶通知 |
对象操作 | Object operations | 上传对象,下载对象,复制对象,删除对象,列出对象,获取对象属性,设置对象权限 |
预先指定的操作 | Presigned operations | 生成预签名 URL 用于临时下载/上传访问私有对象 |
存储桶策略和通知操作 | Bucket Policy & Notification operations | 配置存储桶策略,设置桶通知,配置事件触发器 |
自定义设置 | Custom Settings | 自定义存储桶设置,如日志记录,版本控制,静态网站托管等配置 |
当然我们常用的是对象操作,如果是初学者,这些名字还是需要理解一下,因为他与 API 的设计相关联。
9.3) 上传、下载和删除
功能 | api | 描述 |
---|---|---|
上传 | putObject | 使用流或者 buffer 进行上传 |
上传 | fPutObject | 按照文件名进行上传 |
删除 | removeObject | 按照文件名删除 |
删除 | removeObjects | 删除列表 |
... | ... | ... |
十、API 应用场景分析
场景 | 方案 |
---|---|
前端直接上传 | 后端配合生成 linux api |
上传到后端,后端上传到 minio | 使用各种客户端配合与前端节后 |
cli | 使用 mc 命令进行操作 |
十一、在 Node.js 中使用
以 Express 为示例,完成上传和访问上传的图片:
- 初始化项目并安装依赖:
sh
cd your_dir
pnpm init
pnpm add express ejs multer minio # 安装依赖
mkdir views uploads # 创建视图文件夹和上传文件夹
touch index.mjs minio.js && cd views && index.ejs
- minio.js 处理上传 minio
ts
import * as minio from "minio";
const minioClient = new minio.Client({
endPoint: "localhost",
port: 9000,
useSSL: false,
accessKey: "user_name",
secretKey: "password",
});
export const uploadToMinio = async (filename) => {
const sourceFile = "./uploads/" + filename;
const bucket = "test";
const destinationObject = filename;
var metaData = {
// "Content-Type": "image/png",
// "X-Amz-Meta-Testing": 1234,
// example: 5678,
};
// Check if the bucket exists
// If it doesn't, create it
let exists;
try {
exists = await minioClient.bucketExists(bucket);
} catch (error) {
console.log("error exists", exists);
}
if (exists) {
console.log("Bucket " + bucket + " exists.");
} else {
await minioClient.makeBucket(bucket);
console.log("Bucket " + bucket + ' created in "test".');
}
let result;
try {
result = await minioClient.fPutObject(
bucket,
destinationObject,
sourceFile,
metaData
);
} catch (error) {
console.error(error);
return null;
}
console.log("result", result); // undefined 是 void 类型
return result;
};
需要注意的是: accessKey 和 secretKey docker 创建时的用户名和密码。
- index.mjs
ts
import express from 'express'
import multer from 'multer'
import { uploadToMinio } from './minio.mjs';
const app = express()
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
console.log('file', file)
cb(null, file.fieldname + '-' + Date.now() + '-' + file.originalname)
}
})
const upload = multer({ storage: storage })
app.set('view engine', 'ejs')
app.set('views', './views');
app.get('/', (req, res) => {
res.render('index')
})
app.use('/upload', upload.single('file'), async (req, res) => {
console.log(req.file);
const result = await uploadToMinio(req.file.filename)
res.json({
code: 0,
message: 'success',
data: result
})
})
app.listen(3000, () => {
console.log("server on: http://localhost:3000")
})
- /uploads/index.ejs
ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<form action="/upload" method="post" enctype="multipart/form-data">
<div>
<input type="file" name="file" id="" />
</div>
<button type="submit">上传</button>
</form>
</div>
</body>
</html>
11.1) 上传成功列表
当我们上传成功之后,我们就能在 browser/${bucket_name}
中查看并阅览。
11.2) 预览
使用 fPutObject
上传的方式,可以直接在 http://localhost:9000/${bucket_name}/{filename.ext}
访问。当然你不想被外界访问到了可以关闭访问权限:
十二、备份数据
- 🌻使用
mc cp
命令进行备份 - 🌻使用
MinIO
客户端 api 进行编程备份 - 🌻与
Amazon S3
使用 Reclone 等工具进行备份 - 🌻如果是集群,在集权之间进行复制
- 🌻快照和版本控制
到此为止一个 Minio 的前后端基本功能就跑通了。你可将其当作自己的私有的文件管理工具。你的博客图片就可以自己部署到服务器,管理自己的图片或者其他的文件了。
十三、小结
本文主要介绍了 Minio 如何如部署以及基本使用,并且使用 Node.js Express 构建一个简单的 Web 服务跑通了整个流程。最后希望能够帮助到大家。