在 Ubuntu 上搭建 MinIO 服务器
在日常开发时,如果有文件上传下载的需求(比如用户头像),但是又不想使用对象存储,那么自己搭建一个 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 {
@Autowired
private 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 S3Error
app = 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.filename
try:
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'}), 200
except 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)}), 500
if __name__ == '__main__':
app.run(debug=True)
推荐阅读
MinIO Plus:> 在日常开发时,如果有文件上传下载的需求(比如用户头像),但是又不想使用对象存储,那么自己搭建一个 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 {
@Autowired
private 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 S3Error
app = 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.filename
try:
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'}), 200
except 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)}), 500
if __name__ == '__main__':
app.run(debug=True)
推荐阅读
MinIO Plus:https://mp.weixin.qq.com/s/kSkC3X-SQqo5GzXt-H66xw
在 Ubuntu 上搭建 MinIO 服务器的更多相关文章
- Ubuntu上搭建Git服务器
下面我们就看看,如何在Ubuntu上搭建Git服务器.我们使用VMware虚拟机安装两台Ubantu系统,分别命名为gitServer和gitClient_01. 1.安装OpenSSH并配置SSH无 ...
- Ubuntu上搭建GPU服务器
1.安装显卡驱动 2.安装CUDA 3.安装cuDNN 下载: 根据显卡类型以及操作系统,选定CUDA版本和语言设置,下载对应的显卡驱动. 驱动下载地址 安装 $ sudo ./NVIDIA-Linu ...
- Ubuntu 上搭建 Samba 服务器
由于经常要接收同事发送的一些文件,U盘拷来拷去的很麻烦. 在本机Ubuntu上搭了各Samba服务器,过程中遇到点小问题,记录一下 sudo apt-get install samba 创建一个共享目 ...
- 【转载】如何在Ubuntu上安装LAMP服务器系统?
转载自:http://os.51cto.com/art/201307/405333.htm [2013年7月25日 51CTO外电头条]为何应该在Ubuntu上安装LAMP服务器?从事Web开发工作时 ...
- [转载]如何在Ubuntu上安装LAMP服务器系统
[2013年7月25日 51CTO外电头条]为何应该在Ubuntu上安装LAMP服务器?从事Web开发工作时,我更偏爱在不受干扰的情况下,在我那台计算机上的开发环境下进行开发.我宁愿所犯的错误大部分是 ...
- 在Ubuntu下搭建FTP服务器的方法
由于整个学校相当于一个大型局域网,相互之间传送数据非常快,比如要共享个电影,传点资料什么的. 所以我们可以选择搭建一个FTP服务器来共享文件. 那么问题来了,有的同学会问,我们既然在一个局域网内,直接 ...
- 在Ubuntu中搭建KMS服务器
介绍 基于vlmcsd搭建的KMS服务器. 根据github上的说明,这个工具是用C写的,没有任何依赖,可以直接运行.而且它横跨几乎现在所有的系统平台,如Android, FreeBSD, Solar ...
- Ubuntu上搭建Hadoop环境(单机模式+伪分布模式) (转载)
Hadoop在处理海量数据分析方面具有独天优势.今天花了在自己的Linux上搭建了伪分布模式,期间经历很多曲折,现在将经验总结如下. 首先,了解Hadoop的三种安装模式: 1. 单机模式. 单机模式 ...
- 本地虚拟机在ubuntu系统搭建nexus服务器
本地虚拟机在ubuntu系统上搭建nexus服务器 本地虚拟机在ubuntu系统上搭建nexus服务器所需软件: 虚拟机:VM或者Oracle VM VirtualBox 系统:ubuntu-14.0 ...
- Mac上搭建直播服务器Nginx+rtmp
简介 nginx是非常优秀的开源服务器,用它来做hls或者rtmp流媒体服务器是非常不错的选择,本人在网上整理了安装流程,分享给大家并且作备忘. 步骤安装 1.安装Homebrow Homebrew简 ...
随机推荐
- iOS Xcode真机调试包下载地址
下载地址 https://github.com/iGhibli/iOS-DeviceSupport/tree/master/DeviceSupport 本地安装路径 /Applications/Xco ...
- Nginx UI:全新的 Nginx 在线管理平台
前言 Nginx在程序部署中扮演着至关重要的角色,其高性能.高安全性.易于配置和管理的特点,使得它成为现代Web应用部署中不可或缺的一部分.今天大姚给大家分享一款实用的 Nginx Web UI 工具 ...
- 鸿蒙Flutter实战:01-搭建开发环境
鸿蒙Flutter实战:01-搭建开发环境 准备工作 1.安装 DevEco Studio NEXT IDE, 注意版本应该是 Next,当前最新的是 Beta3 2.安装Git, 如果要同时适配安卓 ...
- linux 基础(3)基本文件操作
目录的基本操作 在 linux 文件系统里,以斜杠 / 开头的路径是绝对路径,从根目录开始寻找:其他的路径则都是相对路径,从当前目录(working directory)开始寻找. 相对目录中常用的符 ...
- manim边做边学--复数平面
所谓复数平面,就是一种二维坐标系统,用于几何表示复数的场景,其中横轴代表实部,纵轴代表虚部. 每个点对应一个唯一的复数,反之亦然,这种表示方法使得复数的加法.乘法等运算可以通过直观的图形变换来理解. ...
- JS 绘制 Cardinal 样条曲线
Cardinal 曲线 根据定义,给定点集 \(\{ \mathbf {P}_{k-1}, \mathbf {P}_k, \mathbf {P}_{k+1}, \mathbf {P}_{k+2} \} ...
- Next.js 深度教程:服务端渲染、静态生成到增量静态再生 | 2024最新版
优化字体和图像 书接上回,我们学习了如何设计Next.js应用程序,让我们继续优化主页和添加自定义字体.图像. 在网站设计中,字体扮演着关键角色,然而,若需获取并加载字体文件,项目中引入自定义字体可能 ...
- spring基础配置原则
spring框架本身有四大原则:1.使用pojo进行轻量级和最小侵入式开发2.通过依赖注入和基于接口编程实现松耦合3.通过AOP和默认习惯进行声明式编程4.使用AOP和模板减少模式化代码spring ...
- Java创建数组、赋值的四种方式,声明+创建+初始化 详解
@ 目录 一.创建数组的四种方式 二.详解 三.数组存储的弊端 一.创建数组的四种方式 以int数据类型为例 @Test public void testNewArray() { //创建数组 //法 ...
- Codeforces 2023/2024 A-H
题面 A B C D E F G H 难度:红 橙 黄 绿 蓝 紫 黑 黑 题解 A 题目大意: 输入 \(a\),\(b\),解不等式 \(b - 2x \le a - x (0 \le x \le ...