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

相关推荐
小白学习日记34 分钟前
【复习】HTML常用标签<table>
前端·html
丁总学Java1 小时前
微信小程序-npm支持-如何使用npm包
前端·微信小程序·npm·node.js
姜学迁1 小时前
Rust-枚举
开发语言·后端·rust
yanlele1 小时前
前瞻 - 盘点 ES2025 已经定稿的语法规范
前端·javascript·代码规范
爱学习的小健1 小时前
MQTT--Java整合EMQX
后端
懒羊羊大王呀1 小时前
CSS——属性值计算
前端·css
北极小狐2 小时前
Java vs JavaScript:类型系统的艺术 - 从 Object 到 any,从静态到动态
后端
xgq2 小时前
使用File System Access API 直接读写本地文件
前端·javascript·面试
用户3157476081352 小时前
前端之路-了解原型和原型链
前端
永远不打烊2 小时前
librtmp 原生API做直播推流
前端