From f1a6b3c00cf5da57d59321db18cfdab2f6ccf03a Mon Sep 17 00:00:00 2001 From: arch3rPro <30855883+arch3rPro@users.noreply.github.com> Date: Wed, 20 Aug 2025 12:13:59 +0800 Subject: [PATCH] feat: add app rustfs --- README.md | 9 +++++++ apps/rustfs/README.md | 37 ++++++++++++++++++++++++++ apps/rustfs/README_en.md | 36 +++++++++++++++++++++++++ apps/rustfs/data.yml | 26 ++++++++++++++++++ apps/rustfs/latest/data.yml | 12 +++++++++ apps/rustfs/latest/docker-compose.yml | 35 ++++++++++++++++++++++++ apps/rustfs/logo.png | Bin 0 -> 8583 bytes 7 files changed, 155 insertions(+) create mode 100644 apps/rustfs/README.md create mode 100644 apps/rustfs/README_en.md create mode 100644 apps/rustfs/data.yml create mode 100644 apps/rustfs/latest/data.yml create mode 100644 apps/rustfs/latest/docker-compose.yml create mode 100644 apps/rustfs/logo.png diff --git a/README.md b/README.md index 77bf6af..f4d861c 100644 --- a/README.md +++ b/README.md @@ -355,6 +355,15 @@ AI驱动的开源代码知识库与文档协作平台,支持多模型、多数 + +RustFS +
RustFS +
+ +高性能Rust对象存储系统,提供S3兼容API + +latest • [官网链接](https://github.com/rustfs/rustfs) + diff --git a/apps/rustfs/README.md b/apps/rustfs/README.md new file mode 100644 index 0000000..7f4fcf9 --- /dev/null +++ b/apps/rustfs/README.md @@ -0,0 +1,37 @@ +# RustFS + +RustFS 是一个用 Rust 编写的高性能分布式对象存储系统,提供 S3 兼容的 API,用于存储和检索对象。它是 MinIO 的替代品,专为高性能、安全性和可靠性而设计。 + +![](https://cdn.jsdelivr.net/gh/xiaoY233/PicList@main/public/assets/RustFS.png) + +![](https://img.shields.io/badge/Copyright-arch3rPro-ff9800?style=flat&logo=github&logoColor=white) + +RustFS 是一款简单、高效、分布式的对象存储。 同时,也是一种高效、开源、自由的对象存储解决方案。它 100% 兼容 S3 协议,使用 Apache2 许可证发行的开源软件。RustFS 使用目前全世界最受欢迎的、内存安全的语言 Rust 语言编写。 它是由全世界优秀的工程师参与并贡献的一款对于商用友好的分布式对象存储产品,RustFS 可以平替非常多非友好开源协议的对象存储产品。 + + +### RustFS 的特征 +- S3 兼容: 100% 兼容 S3 协议,优秀的兼容性与大数据、数据湖、备份软件、图像处理软件、工业生产软件兼容; +- 分布式: RustFS 是一个分布式的对象存储,因此,RustFS 可以满足各种需求; +- 商用友好: RustFS 是 100% 的开源软件,并且使用 Apache v2.0 许可证发行,因此,RustFS 是商用友好的; +- 快速: Rust 这一门开发语言的性能无限接近于 C 语言的速度。因此,RustFS 的性能非常强劲; +- 安全: RustFS 使用内存安全的语言 Rust 编写,因此,RustFS 是 100% 安全的; +- 跨平台: RustFS works on Windows, macOS, and Linux; +- 可扩展: RustFS 支持自定义插件,因此,RustFS 可以满足各种需求; +- 可定制: 由于开源的特性,你可以自定义各种插件插件,因此,RustFS 可以满足各种需求; +- 云原生: RustFS 支持 Docker 等方式部署,可快速在云原生环境下快速部署。 + +### 使用介绍 + +默认账号密码为rustfsadmin,请登录管理后台及时修改密码! + +### 开源社区 + +RustFS 采用 Apache 2.0 许可证,鼓励社区贡献和透明度,拥有活跃的开发者社区支持。 + +## 适用场景: + +- **云原生应用**:为现代云原生应用提供高效的数据存储和检索 +- **大数据和 AI 工作负载**:优化了对数据湖、AI 和大数据处理的支持 +- **企业级存储**:支持多租户管理、可观测性等企业级功能 +- **备份和归档**:可靠的长期数据存储解决方案 +- **内容分发**:高性能的内容存储和分发平台 \ No newline at end of file diff --git a/apps/rustfs/README_en.md b/apps/rustfs/README_en.md new file mode 100644 index 0000000..e22ccc9 --- /dev/null +++ b/apps/rustfs/README_en.md @@ -0,0 +1,36 @@ +# RustFS + +RustFS is a high-performance distributed object storage system written in Rust, providing S3-compatible APIs for storing and retrieving objects. It serves as an alternative to MinIO, designed specifically for high performance, security, and reliability. + +![](https://cdn.jsdelivr.net/gh/xiaoY233/PicList@main/public/assets/RustFS.png) + +![](https://img.shields.io/badge/Copyright-arch3rPro-ff9800?style=flat&logo=github&logoColor=white) + +RustFS is a simple, efficient, and distributed object storage solution. It is also an efficient, open-source, and free object storage solution. It is 100% compatible with the S3 protocol and is released under the Apache2 license. RustFS is written in Rust, currently the world's most popular memory-safe language. It is a commercially friendly distributed object storage product contributed by excellent engineers from around the world. RustFS can replace many object storage products with non-friendly open source licenses. + +### Features of RustFS +- S3 Compatible: 100% compatible with S3 protocol, excellent compatibility with big data, data lakes, backup software, image processing software, and industrial production software; +- Distributed: RustFS is a distributed object storage, therefore, RustFS can meet various requirements; +- Commercial Friendly: RustFS is 100% open source software and is released under the Apache v2.0 license, making it commercially friendly; +- Fast: The performance of Rust as a development language is infinitely close to the speed of C language. Therefore, RustFS performance is very powerful; +- Secure: RustFS is written in the memory-safe language Rust, therefore, RustFS is 100% secure; +- Cross-platform: RustFS works on Windows, macOS, and Linux; +- Extensible: RustFS supports custom plugins, therefore, RustFS can meet various requirements; +- Customizable: Due to its open-source nature, you can customize various plugins, therefore, RustFS can meet various requirements; +- Cloud Native: RustFS supports deployment via Docker and other methods, enabling quick deployment in cloud-native environments. + +### Usage Guide + +The default username and password are rustfsadmin. Please log in to the admin panel and change the password promptly! + +### Open Source Community + +RustFS is licensed under Apache 2.0, encouraging community contributions and transparency, with an active developer community for support. + +## Use Cases: + +- **Cloud Native Applications**: Provides efficient data storage and retrieval for modern cloud-native applications +- **Big Data and AI Workloads**: Optimized support for data lakes, AI, and big data processing +- **Enterprise Storage**: Supports multi-tenant management, observability, and other enterprise-grade features +- **Backup and Archiving**: Reliable long-term data storage solution +- **Content Distribution**: High-performance platform for content storage and distribution \ No newline at end of file diff --git a/apps/rustfs/data.yml b/apps/rustfs/data.yml new file mode 100644 index 0000000..594235b --- /dev/null +++ b/apps/rustfs/data.yml @@ -0,0 +1,26 @@ +name: RustFS +tags: + - 云存储 +title: 高性能Rust对象存储系统 +description: 用Rust编写的高性能分布式对象存储系统,提供S3兼容API +additionalProperties: + key: rustfs + name: RustFS + tags: + - Storage + shortDescZh: 高性能Rust对象存储系统 + shortDescEn: High-performance Rust object storage system + description: + en: High-performance distributed object storage system written in Rust with S3 compatible API + zh: 用Rust编写的高性能分布式对象存储系统,提供S3兼容API + type: website + crossVersionUpdate: true + limit: 1 + recommend: 0 + website: https://github.com/rustfs/rustfs + github: https://github.com/rustfs/rustfs + document: https://github.com/rustfs/rustfs/wiki + memoryRequired: 2048 + architectures: + - arm64 + - amd64 \ No newline at end of file diff --git a/apps/rustfs/latest/data.yml b/apps/rustfs/latest/data.yml new file mode 100644 index 0000000..f7fc6f3 --- /dev/null +++ b/apps/rustfs/latest/data.yml @@ -0,0 +1,12 @@ +additionalProperties: + formFields: + - default: 9000 + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + label: + en: Port + zh: 端口 \ No newline at end of file diff --git a/apps/rustfs/latest/docker-compose.yml b/apps/rustfs/latest/docker-compose.yml new file mode 100644 index 0000000..f8b7832 --- /dev/null +++ b/apps/rustfs/latest/docker-compose.yml @@ -0,0 +1,35 @@ + +services: + rustfs: + image: rustfs/rustfs:latest + container_name: ${CONTAINER_NAME} + ports: + - "${PANEL_APP_PORT_HTTP}:9000" # S3 API port + environment: + - RUSTFS_CONSOLE_ENABLE=true + - RUSTFS_LOG_LEVEL=info + volumes: + - ./data:/data + - ./logs:/logs + networks: + - 1panel-network + restart: always + healthcheck: + test: + [ + "CMD", + "wget", + "--no-verbose", + "--tries=1", + "--spider", + "http://localhost:9000/health", + ] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + labels: + createdBy: "Apps" +networks: + 1panel-network: + external: true diff --git a/apps/rustfs/logo.png b/apps/rustfs/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2efadd5a8564b96e1bcedf30641ee5573cc0782a GIT binary patch literal 8583 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 g3QuGR2v1K9pEvc6(HAkm8!Ql16}1$q