在 Ubuntu 上搭建 MinIO 服务器

embedded/2024/12/29 9:57:47/

本文首发于博客园,原文链接:https://www.cnblogs.com/spcodhu/p/18635554
原文与本文的作者系同一人,因此投稿原创文章。


在日常开发时,如果有文件上传下载的需求(比如用户头像),但是又不想使用对象存储,那么自己搭建一个 MinIO 服务器是一个比较简单的解决方案。

MinIO 是一个基于 Apache License v2.0 开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从 几kb 到最大 5T 不等。

MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。


MinIO 中文网站:https://www.minio.org.cn/docs/minio/linux/operations/installation.html

部署 MinIO 并修改 minioadmin 的账户密码

本文主要介绍在 Ububtu 上单节点单硬盘部署 MinIO,步骤如下:

下载 MinIO 服务器

wget https://dl.min.io/server/minio/release/linux-amd64/minio

MinIO 二进制文件添加执行权限

chmod +x minio

在合适的位置创建一个文件夹,用于存储 MinIO 上传的文件数据

# 在根目录创建 minio-data 文件夹,存储 MinIO 上传的文件数据
mkdir ~/minio-data

安装 MinIO。将 MinIO 的二进制文件移到 /usr/local/bin/目录下,以使其全局可用

sudo mv minio /usr/local/bin/

使用持久化环境变量作为 MinIO console 的登录账户和密码。

编辑 .bashrc文件,这里使用 nano。

nano ~/.bashrc

在文件的最后加上环境变量

export MINIO_ROOT_USER=newrootuser
export MINIO_ROOT_PASSWORD=newrootpassword

重新加载.bashrc以使更改生效

source ~/.bashrc

启动 MinIO

nohup minio server --secure ~/minio-data

这里使用nohup确保会话关闭之后 MinIO 不会停止,也可以使用screen等会话技术,或者将 MinIO 作为一个服务启动。这里不做过多介绍。

启动 MinIO 之后,在浏览器访问 ip+9000 端口即可访问 MinIO 的 Web 控制台。如果访问不了,请先检查 MinIO 的两个端口是否已经开放,一个是 MinIO 的 WebUI 端口,这个是随机的;一个是 MinIO 的 API 端口,这个固定是 9000。

在浏览器访问 ip+9000 实际会跳转到 WebUI 的端口。但是在使用 API 上传下载文件需要使用 9000 端口。


MinIO 配置域名

如果不想直接暴露 MinIO 的地址和端口,则可以使用 Nginx 给 MinIO 配置域名访问。

在此之前,您需要先准备一个已备案的域名并解析到当前服务器。

步骤如下:

先安装 Nginx (如果没有的话)

sudo apt-get update
sudo apt-get install nginx

一般不建议直接更改位于/etc/nginx/nginx.conf的 nginx 主配置文件。采用如下的配置方式:

/etc/nginx/sites-available/创建新的配置文件,可以直接以当前配置的域名未文件名。我这里由于需要配置多个域名,文件名叫做minio.conf

cd /etc/nginx/sites-available/
touch minio.conf

书写配置文件

nano minio.conf

配置文件示例

# WebUI 配置
server {listen 80;server_name yourdomain.com; # 替换为您的域名location / {proxy_pass http://localhost:44366;  # 替换为实际的端口proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
}# API 配置
server {listen 80;server_name api.yourdomain.com; # 替换为您的API域名location / {proxy_pass http://localhost:9000;   # 替换为实际的端口proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
}

启用新创建的配置文件。将/etc/nginx/sites-available/minio.conf链接到/etc/nginx/sites-enabled/目录

sudo ln -s /etc/nginx/sites-available/minio.conf /etc/nginx/sites-enabled/

可以先检查一下 nginx,确认没有语法错误

nginx -t

重启 nginx 服务

sudo systemctl restart nginx

此时,在本机浏览器上应该可以用域名访问 Minio console 了。


MinIO 调用示例

在 SpringBoot 中调用

先添加依赖
<dependencies><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.3</version></dependency>
</dependencies>

然后创建一个服务类来实现文件的上传下载

import io.minio.*;
import io.minio.messages.Item;import java.io.InputStream;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.UUID;@Service
public class MinIOService {private final MinioClient minioClient;public MinIOService() {try {// 配置更改成自己的,建议写在配置文件中this.minioClient = MinioClient.builder().endpoint("http://localhost:9000").credentials("minioadmin", "minioadmin").build();} catch (MinioException e) {throw new RuntimeException("Failed to create MinioClient", e);}}public String uploadFile(String bucketName, String objectName, InputStream stream, long size) {try {minioClient.putObject(bucketName, objectName, stream, size);return "File uploaded successfully.";} catch (MinioException | IOException e) {throw new RuntimeException("File upload failed.", e);}}public InputStream downloadFile(String bucketName, String objectName) {try {return minioClient.getObject(bucketName, objectName);} catch (MinioException | IOException e) {throw new RuntimeException("File download failed.", e);}}
}

并为其书写对应的 Controller

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;@RestController
@RequestMapping("/minio")
public class MinIOController {@Autowiredprivate MinIOService minIOService;@PostMapping("/upload")public String uploadFile(@RequestParam("file") MultipartFile file) {String bucketName = "my-bucket";String objectName = UUID.randomUUID().toString();try (InputStream stream = file.getInputStream()) {return minIOService.uploadFile(bucketName, objectName, stream, file.getSize());} catch (IOException e) {return "Failed to upload file.";}}@GetMapping("/download/{objectName}")public ResponseEntity<Resource> downloadFile(@PathVariable String objectName) {String bucketName = "my-bucket";InputStream stream = minIOService.downloadFile(bucketName, objectName);return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + objectName + "\"").body(new InputStreamResource(stream));}
}

在 Flask 中调用

下载依赖
pip install minio

然后创建一个 Flask 来集成 MinIO

from flask import Flask, request, send_file, jsonify
from minio import Minio
from minio.error import S3Errorapp = Flask(__name__)# MinIO配置
minio_client = Minio(# 更改成自己的"localhost:9000",access_key="minioadmin",secret_key="minioadmin",secure=False
)@app.route('/upload', methods=['POST'])
def upload_file():file = request.files['file']bucket_name = 'my-bucket'object_name = file.filenametry:with open('/tmp/' + object_name, 'wb') as f:f.write(file.read())minio_client.fput_object(bucket_name, object_name, '/tmp/' + object_name)return jsonify({'message': 'File uploaded successfully'}), 200except S3Error as exc:return jsonify({'error': str(exc)}), 500@app.route('/download/<object_name>', methods=['GET'])
def download_file(object_name):bucket_name = 'my-bucket'try:response = minio_client.get_object(bucket_name, object_name)return send_file(response.stream,as_attachment=True,attachment_filename=object_name,mimetype=response.headers['content-type'])except S3Error as exc:return jsonify({'error': str(exc)}), 500if __name__ == '__main__':app.run(debug=True)

推荐阅读

MinIO Plus:https://mp.weixin.qq.com/s/kSkC3X-SQqo5GzXt-H66xw

http://www.ppmy.cn/embedded/149705.html

相关文章

win10系统上打包electron,实现在win7系统运行

降低版本&#xff0c;win7上能运行的版本是&#xff1a; node: 14.17.0 node 链接地址&#xff1a;Index of /download/release/v14.17.0/ electron: "^13.6.9" &#xff08;压缩包在百度网盘&#xff09; electron-builder: "^22.14.13" 链接: https://pa…

ESP-NETIF L2 TAP 接口-物联网嵌入式开发应用

ESP-NETIF L2 TAP 概述 ESP-NETIF L2 TAP 接口是 ESP-IDF 访问用户应用程序中的数据链路层&#xff08;OSI/ISO 中的 L2&#xff09;以进行帧接收和传输的机制。在嵌入式开发中&#xff0c;它通常用于实现非 IP 相关协议&#xff0c;如 PTP 和 Wake on LAN 等。 Tips : 目前…

Kubernetes# Helm工具使用

目录 概念 核心组件 Helm客户端 Tiller Chart Repository Release Helm安装 Helm使用 创建Helm Chart 定义Chart元数据 定义Template模板 定义values参数 打包和部署 Helm Chart 推送到远程仓库 Helm常用命令 概念 Helm 是一个 Kubernetes 的包管理工具&#…

lxml 解析xml\html

from lxml import etree# XML文档示例 xml_doc """ <root><book><title>Python编程指南</title><author>张三</author></book><book><title>Python高级编程</title><author>李四</autho…

大数据平台开发学习路线及技能

背景 最近项目涉及这方面&#xff0c;特地整理学习路线方便后续学习。 必备技能 一、编程语言 Java&#xff1a;大数据开发的基础语言&#xff0c;具有跨平台能力&#xff0c;可用于编写各种应用。 Python&#xff1a;机器学习和数据分析领域广泛使用的语言&#xff0c;易于…

【ES6复习笔记】Promise对象详解(12)

1. 什么是 Promise&#xff1f; Promise 是 JavaScript 中处理异步操作的一种机制&#xff0c;它可以让异步操作更加容易管理和控制。Promise 对象代表一个异步操作的最终完成或失败&#xff0c;并提供了一种方式来处理操作的结果。 2. Promise 的基本语法 Promise 对象有三…

【AI学习】DeepSeek-V3 技术报告学习:总体架构

翻了一下DeepSeek-V3 技术报告学习&#xff0c;太长&#xff0c;只是大概翻了一下&#xff0c;其中Multi-Token Prediction的技术就很亮眼。 摘要 本文介绍了DeepSeek-V3&#xff0c;这是一个拥有671B总参数的强大混合专家&#xff08;MoE&#xff09;语言模型&#xff0c;每…

sql group by 多个字段例子

有表如下&#xff1b; 获取某年份、某地区、某产品的销售总额&#xff0c; 或者根据需要把字段顺序换一下&#xff1b; insert into sales (product, year, region, amount) values (飞机,2000,东部,5); insert into sales (product, year, region, amount) values (飞机,2001,…