MinIO+Docker从零搭建一个文件存储服务

news2024/11/14 1:45:16

本文,将带你使用 MinIO + Docker 来从零搭建一个文件存储服务,并在 SpringBoot 项目中上传图片到 MinIO 中。

一.为什么要自己搭建?

对于个人来说,当然是攻击风险。第三方对象存储服务通常会收取费用,尤其随着数据量的增加,费用也会相应增加,而通过自己搭建文件存储服务器,可以有效控制成本。其实费用还好,个人小项目访问量不大花不了多少钱,最重要的是被攻击刷流量就GG了。例如:

个人小博客被攻击:

在这里插入图片描述

某知名up主被刷爆:

在这里插入图片描述

虽然个人小项目一般不会被攻击,但就问你看到-1.5w慌不慌?接下来让我们来学习一下如何使用MinIO搭建一个自己的文件存储服务器吧~

二.为什么使用MinIO?

MinIO 是一个高性能的轻量级对象存储服务器。它具有分布式,高可用性和水平扩展的特点,它非常适合用于大规模数据存储和分析。其优点包括低延迟、高吞吐量、易于部署和管理

怕很拉跨不敢用?

截止目前,MinIO 在 Github 上有 43.7k Star。

国内阿里巴巴、腾讯、百度、华为、中国移动、中国联通等企业都有在使用 MinIO,甚至不少商业公司二次开发 MinIO 来提供商业化的云存储产品。

在这里插入图片描述

三.搭建MinIO

(1) 引言

MinIO 的官方文档上介绍了多种下载方式:

在这里插入图片描述

本文我们只介绍如何使用 Docker 基于CentOS 服务器来进行服务的搭建,如果未安装Docker可以通过本文(点击跳转)来了解和安装Docker,或者在官方文档挑选自己擅长的方式进行搭建~

在这里插入图片描述

(2) 安装

  1. 首先我们要创建两个文件目录:一个用来存放 MinIO 的配置文件,一个用来存储我们上传文件数据。
mkdir -p /home/minio/config
mkdir -p /home/minio/data
  • /home/minio/config 用于存放 MinIO 的配置文件
  • /home/minio/data 用于存储上传的文件数据
  1. 接下来我们可以通过如下命令拉取最新版镜像并创建 MinIO 容器运行。如果需要下载指定版本可以点击前往DockerHub仓库选择下载。
docker run -p 9000:9000 -p 9001:9001 \
-d --restart=always \
-e "MINIO_ACCESS_KEY=admin" \
-e "MINIO_SECRET_KEY=password" \
-v /home/minio/data:/data \
-v /home/minio/config:/root/.minio \
minio/minio server \
/data \
--console-address ":9001" 

运行效果:

在这里插入图片描述

命令行解释:

  • MINIO_ACCESS_KEYMINIO_SECRET_KEY 为UI界面登录账号密码
  • -d 将容器以后台(守护进程)模式运行,并与终端分离。
  • --restart=always 选项指定容器在停止后总是自动重启。
  • /home/minio/data 挂载的存储上传文件的目录
  • /home/minio/config 挂载的配置文件
  • minio/minio server 使用MinIO 镜像并启动
  • /data 要使用的数据目录
  • --console-address 指定UI 界面的端口
  • 9000:9000 映射服务器端口
  • 9001:9001 映射UI界面端口

补充说明:

Docker的run指令会首先在本地查找指定的镜像,如果本地没有找到对应的镜像,则会自动去远程镜像仓库拉取该镜像并在本地运行。

当不带有标签(tag)的镜像名称时,Docker默认会使用latest标签来拉取最新版本的镜像。例如,如果运行docker run ubuntu,Docker会首先在本地查找名为ubuntu:latest的镜像是否存在,如果不存在,则会从默认的远程镜像仓库(如Docker Hub)拉取最新版本的ubuntu镜像,并在本地运行。

如果指定了具体的标签或版本号,例如docker run ubuntu:18.04,Docker会尝试在本地查找名为ubuntu:18.04的镜像,如果本地没有找到,则会从远程镜像仓库拉取对应的镜像。

需要注意的是,如果在远程镜像仓库中找不到指定的镜像,或者无法连接到远程镜像仓库,Docker的run指令将无法成功运行,并会报错提示找不到镜像。

  1. 最后在浏览器中访问 http://服务器IP:9001,即可访问到MinIO的控制台。

在这里插入图片描述

可以输入账号 admin,密码 password 进行登录,进入首页。

在这里插入图片描述

可以发现它的界面和我们使用的一些第三方对象存储服务非常相似,接下来我们也要进行一系列的配置~

(3) 配置

  1. 创建一个 Bucket 存储桶,用于稍后文件的上传操作。

在这里插入图片描述

  1. 前往创建用于远程操作的AccessKey 和 SecretKey.

在这里插入图片描述

  1. 创建并保存好生成Access Key 和 Secret Key.

在这里插入图片描述

  1. 默认配置下,访问存储桶是需要请求授权的。但是在实际场景下,我们往往希望允许直接访问,此时就需要添加一条 readonly 访问规则。

在这里插入图片描述

进入配置存储桶界面

在这里插入图片描述

进行配置,添加只读规则

在这里插入图片描述

至此,我们已经基本完成了MinIO的简单配置,当然如果想要更安全,同样是可以像使用第三方对象存储服务一样创建用户组,分配权限等诸如此类的操作。

(4) 测试

  1. 我们上传一张图片并访问来测试一下是否搭建成功。

在这里插入图片描述

  1. 可以看到成功上传了图片

在这里插入图片描述

  1. 接下来我们在浏览器访问 http://服务器IP:9000/{bucket存储桶名字}/{name图片后缀名} 来进行访问。例如我刚上传的文件 {bucket} 是 guanzhi,{name} 是 csdn.png,所以最终的访问路径是 http://服务器IP:9000/guanzhi/csdn.png

在这里插入图片描述

测试成功,能够正常使用,接下来我们来学习一下如何在Java项目中使用吧~

四.在项目中使用

(1) 引言

官方文档上有介绍多种语言的SDK使用指南,本篇我们只学习如何在Java的Maven项目中进行使用,其他语言的同学可以跟着官方文档尝试一下~

在这里插入图片描述

(2) 初步尝试

  1. 首先在我们创建的Maven项目中引入如下依赖
 <!-- MinIO 客户端 -->
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.5.9</version>
</dependency>
  1. 接下来我们尝试一下官方给出的demo(已经添加详细注释,可以查看下述示例代码)
@SpringBootTest
class DemoApplicationTests {

    @Test
    void demo() {
        try {
            // 1.创建MinIO客户端,与其建立连接,用于我们上传文件操作
            // Create a minioClient with the MinIO server playground, its access key and secret key.
            MinioClient minioClient = MinioClient.builder()
                    .endpoint("http://服务器ip:9000") // 地址为服务器ip+端口号
                    .credentials("1AYD2DY8qPz5vp0WmQtJ",
                            "BQeSptD5wO9vPIwtthNg5BbFswPx7WhsPh1Slp0M") // 我们配置并保存的 AccessKey 和 SecretKey
                    .build();

            // 2.创建存储桶,这一步我们可以直接在界面手动创建一次即可,因此可以省略
            // Make 'asiatrip' bucket if not exist.
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket("guanzhi").build());
            if (!found) {
                // Make a new bucket called 'asiatrip'.
                minioClient.makeBucket(MakeBucketArgs.builder().bucket("guanzhi").build());
            } else {
                System.out.println("Bucket 'guanzhi' already exists.");
            }

            // 3. 上传文件
            // Upload '/home/user/Photos/asiaphotos.zip' as object name 'asiaphotos-2015.zip' to bucket 'asiatrip'.
            minioClient.uploadObject(
                    UploadObjectArgs.builder()
                            .bucket("guanzhi") // 上传到哪个存储桶?
                            .object("pom.xml") // 上传的文件命名为什么?
                            .filename("C:\\code\\demo\\pom.xml") // 上传文件的路径?
                            .build());
            System.out.println(
                    "'C:\\code\\demo\\pom.xml' is successfully uploaded as "
                            + "object 'pom.xml\"' to bucket 'guanzhi'.");
        } catch (MinioException e) {
            System.out.println("Error occurred: " + e);
            System.out.println("HTTP trace: " + e.httpTrace());
        } catch (IOException | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException(e);
        }
    }
}
  1. 可以发现运行成功。

在这里插入图片描述

查看控制台,可以看成功上传了文件。

在这里插入图片描述

(3) 在SpringBoot中使用

我们来简单写一个文件上传功能。

  1. 项目中除了上述依赖,我们还需要引入如下依赖
        <!-- 实现对 Spring MVC 的自动化配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        </dependency>
		<!-- lombok插件-->
         <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
  1. 新建 MinIO 配置类,创建 MinioClient Bean
@Configuration
@ConfigurationProperties(prefix = "file.minio")
@Data
public class MinioConfiguration {
    
    private String accessKey;

    private String secretKey;

    private String endpoint;

    private String bucket;

    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
    }
}
  1. 在application.yml中编写配置
# 对象存储服务配置
file:
  # MinIO自搭建对象存储服务
  minio:
    endpoint: http://服务器ip:9000 #存储服务域名
    accessKey: 1AYD2DY8qPz5vp0WmQtJ 
    secretKey: BQeSptD5wO9vPIwtthNg5BbFswPx7WhsPh1Slp0M
    bucket: guanzhi   #存储桶名称
  1. 编写controller
@RestController
@RequestMapping("/file")
public class FileController {

    @Resource
    private MinioClient minioClient;

    @Resource
    private MinioConfiguration minioConfiguration;

    /**
     * 上传文件
     */
    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) throws Exception {
        // 上传
        String path = UUID.randomUUID() + file.getOriginalFilename(); // 文件名,使用 UUID 随机
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(minioConfiguration.getBucket()) // 存储桶
                .object(path) // 文件名
                .stream(file.getInputStream(), file.getSize(), -1) // 文件内容
                .contentType(file.getContentType()) // 文件类型
                .build());
        // 拼接路径
        return String.format("%s/%s/%s", minioConfiguration.getEndpoint(), minioConfiguration.getBucket(), path);
    }
}
  1. 启动SpringBoot项目,测试接口,可以看到后端正确响应了文件Url.

在这里插入图片描述

  1. 可以看到控制台存储桶中也有文件

在这里插入图片描述

  1. 在浏览器中我们也成功的通过返回的url访问到了图片

在这里插入图片描述

至此,我们已经完成了服务器的搭建,赶紧用起来吧~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1545665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[自研开源] MyData 数据集成之任务调度模式 v0.7

开源地址&#xff1a;gitee | github 详细介绍&#xff1a;MyData 基于 Web API 的数据集成平台 部署文档&#xff1a;用 Docker 部署 MyData 使用手册&#xff1a;MyData 使用手册 试用体验&#xff1a;http://demo.mydata.work 交流 Q 群&#xff1a;430089673 概述 本…

[C++]C/C++内存管理——喵喵要吃C嘎嘎5

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;大大会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

vscode 问题汇总

vscode vscode 问题汇总 一: vscode 大纲 文档中找不到符号二:vscode 找不到头文件三:级目录 一: vscode 大纲 文档中找不到符号 报错原因&#xff1a; 缺少c/c必要插件 安装插件&#xff1a;名称: C/C名称: C/C Extension Pack名称: C Intellisense名称: CMake名称: CMake To…

学习网络编程No.15【高级IO之多路转接】

引言&#xff1a; 北京时间&#xff1a;2024/3/19/11:16&#xff0c;若是说记忆有克星的话&#xff0c;那么一定是时间。若是说耐心有克星的话&#xff0c;那么一定是人的心态。连续几天睡眠问题&#xff0c;加上环境影响&#xff0c;上篇博客还有部分知识只能放在该篇博客介绍…

太牛逼了!视频号下载器手机版(工具+方法)绝了

在众多的视频号下载中&#xff0c;可以说这个工具真的是很牛逼了&#xff01;这里问大家一个问题&#xff01; 你使用视频号下载工具以及视频号下载器都会不会因时间导致而失效呢&#xff1f; 自从小编使用了这款工具后&#xff0c;就不会因为视频失效而烦恼。 很多人免费推荐…

c++进阶(c++里的多态)

文章目录 1.多态的概念1.1多态的概念 2.动态的定义及实现2.1多态的构成条件2.2虚函数2.3虚函数的重写虚函数重写的两个例外 2.4 C11 override和final2.5重载、覆盖&#xff08;重写&#xff09;、隐藏&#xff08;重定义&#xff09;的对比 3.抽象类3.1概念3.2接口继承和实现继…

记录微信小程序云开发的增删改查

目录 一、准备工作 1、创建集合添加数据 2、设置数据权限 3、小程序连接数据库 二、增删改查 1.查 1、查询单集合所有数据 2、条件查询 1、直接:相当于等于 2、调用指令 3、查询单条&#xff08;根据id查询&#xff09; 2.增 3.改 4.删 一、准备工作 1、创建集合添…

Linux--任务管理与守护进程

目录 任务管理 进程组概念 作业概念 会话概念 补充 守护进程 基本概念 守护进程的查看 守护进程的创建 自己手写守护进程 使用系统调用函数创建守护进程 任务管理 进程组概念 每一个进程除了有一个进程ID之外&#xff0c;还有一个进程组ID&#xff0c;进程组是一个或…

由浅到深认识Java语言(29):集合

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

光致发光荧光量子产率测试光纤光谱仪

光致发光荧光量子产率测试系统是一种用于测量材料发光效率的高精度设备&#xff0c;它通过光致发光方法来确定样品的发射效率。光致发光荧光量子产率测试系统不仅提供了一种高效、可靠的测量手段&#xff0c;而且对于提升科学研究和工业应用中的发光材料性能具有重要作用。通过…

Python:基础语法

一、import与from.....import 有时候我们需要使用一些第三方库或包时&#xff0c;我们就需要通过import或from.....import导入模块。 # 导入库 import sys print("hello,world") 当我们自己写了些函数&#xff0c;在其他py文件&#xff0c;我们也可以通过from.....im…

【Java程序设计】【C00361】基于Springboot的考勤管理系统(有论文)

基于Springboot的考勤管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 项目获取 &#x1f345;文末点击卡片获取源码&#x1f345; 开发环境 运行环境&#xff1a;推荐jdk1.8&#xff1b; 开发工具&#xff1a;eclipse以及idea&…

「10」文本(GDI+):添加文字,可设置背景添加移动效果

「10」文本&#xff08;GDI&#xff09;添加文字&#xff0c;可设置背景添加移动效果 在OBS软件里&#xff0c;通过来源组件「文本&#xff08;GDI&#xff09;」&#xff0c;您可以添加任意您想要呈现的文字&#xff0c;在直播窗口中显示&#xff0c;它可以是提示语、广告词、…

SQLServer SEQUENCE用法

SEQUENCE&#xff1a;数据库中的序列生成器 在数据库管理中&#xff0c;经常需要生成唯一且递增的数值序列&#xff0c;用于作为主键或其他需要唯一标识的列的值。为了实现这一功能&#xff0c;SQL Server 引入了 SEQUENCE 对象。SEQUENCE 是一个独立的数据库对象&#xff0c;用…

python.类

1.类用class定义 name等是属性 是成员变量 定义完类了要定义对象 class Student: #定义了一个Student的类nameNoneageNonegenderNonesdu1Student() #创建了一个Student类的对象 sdu1.nameleo sdu1.age20 sdu1.gendermaleprint(sdu1.name) print(sdu1.age) print(sdu1.…

Day21|二叉树part07:530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

530. *二叉搜索树的最小绝对差&#xff08;双指针题型&#xff09; 众所周知二叉搜索树的中序遍历序列是一个有序数组&#xff0c;因此最基本的方法就是遍历得到中序序列再进行计算&#xff0c;实际上可以用双指针法&#xff0c;记录中序遍历前一个指针和当前指针的差值&#…

一个bitter组织下载器样本分析

BITTER 该组织最早在2016由美国安全公司Forcepoint进行了披露&#xff0c;并且命名为“BITTER”&#xff0c;同年国内友商360也跟进发布了分析报告&#xff0c;命名为“蔓灵花” 样本分析 MD5&#xff1a;806626d6e7a283efffb53b3831d53346 vt:看文件名判断是伪装成pdf的自解…

小学生古诗文大会往届真题测一测(来自主办方)和非常详细的解析

新学期开学一眨眼已经过了一个多月了&#xff0c;有家长朋友开始关心2024年上海市小学生古诗文大会什么时候开始&#xff1f;如何准备小学生古诗文大会&#xff1f;如何激发孩子学习古诗词的兴趣&#xff1f;如何提高小学古诗词和古诗文大会的学习成绩&#xff1f;... 最近&…

YT8531调试记录

总结 还是从设备树&#xff0c;mac驱动&#xff0c;mac驱动对mdio总线的注册&#xff0c;phy驱动 &#xff0c;phy的datasheet&#xff0c;cpu的datasheet 几个方面来看来看 0.确认供电&#xff0c;以及phy的地址(一般会有多个地址&#xff0c;根据相关引脚电平可配置) 1.确…

Linux离线安装mysql,node,forever

PS:本文是基于centos7实现的,要求系统能够查看ifconfig和unzip解压命令, 实现无网络可安装运行 首先现在百度网盘的离线文件包****安装Xftp 和 Xshell 把机房压缩包传到 home目录下****解压unzip 包名.zip 获取IP先获取到 linux 主机的ip ifconfig Xftp 连接输入IP,然后按照…