基于 Minio 部署一个自己的文件存储库

一、Minio 简介

Minio 是一个开源(AGPL v3.0)的对象存储出服务器,使用 Minio 可以轻松搭建与 Amazon S3 API 兼容的存储对象。

二、Minio 技术架构

基于 GoLang 的 Minio 采用分布式架构设计。轻量、高性能,可以在单个或者多个分布式集群上运行。

三、Minio 资源

四、支持多种安装方式

五、使用 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_keysecret_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 服务跑通了整个流程。最后希望能够帮助到大家。

相关推荐
web182854825125 分钟前
ctfshow-web 151-170-文件上传
前端·状态模式
豌豆花下猫8 分钟前
Python 潮流周刊#83:uv 的使用技巧(摘要)
后端·python·ai
轻口味10 分钟前
【每日学点鸿蒙知识】Web请求支持Http、PDF展示、APP上架应用搜索问题、APP备案不通过问题、滚动列表问题
前端·http·harmonyos
凡人的AI工具箱15 分钟前
每天40分玩转Django:Django部署概述
开发语言·数据库·后端·python·django
一棵开花的树,枝芽无限靠近你19 分钟前
【PPTist】表格功能
前端·笔记·学习·编辑器·ppt·pptist
SomeB1oody37 分钟前
【Rust自学】7.2. 路径(Path)Pt.1:相对路径、绝对路径与pub关键字
开发语言·后端·rust
SomeB1oody39 分钟前
【Rust自学】7.3. 路径(Path)Pt.2:访问父级模块、pub关键字在结构体和枚举类型上的使用
开发语言·后端·rust
马船长1 小时前
RCE-PLUS (学习记录)
java·linux·前端
学前端的小朱1 小时前
修改输出资源的名称和路径、自动清空上次打包资源
前端·webpack·打包工具
Bony-1 小时前
Go语言反射从入门到进阶
开发语言·后端·golang