From ac9c04166379d0a508a928c1663adf262206385f Mon Sep 17 00:00:00 2001 From: qyg2297248353 Date: Sat, 12 Jul 2025 03:19:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=91=E5=B8=83=20RustFS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/README.md | 1 + README.md | 1 + apps/rustfs/README.md | 37 ++++++++++++ apps/rustfs/data.yml | 15 +++++ apps/rustfs/latest/data.yml | 71 ++++++++++++++++++++++++ apps/rustfs/latest/docker-compose.yml | 26 +++++++++ apps/rustfs/latest/envs/default.env | 2 + apps/rustfs/latest/envs/global.env | 2 + apps/rustfs/latest/scripts/init.sh | 17 ++++++ apps/rustfs/latest/scripts/uninstall.sh | 10 ++++ apps/rustfs/latest/scripts/upgrade.sh | 17 ++++++ apps/rustfs/logo.png | Bin 0 -> 23262 bytes apps/rustfs/logo.svg | 15 +++++ 13 files changed, 214 insertions(+) create mode 100644 apps/rustfs/README.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/latest/envs/default.env create mode 100644 apps/rustfs/latest/envs/global.env create mode 100644 apps/rustfs/latest/scripts/init.sh create mode 100644 apps/rustfs/latest/scripts/uninstall.sh create mode 100644 apps/rustfs/latest/scripts/upgrade.sh create mode 100644 apps/rustfs/logo.png create mode 100644 apps/rustfs/logo.svg diff --git a/.github/README.md b/.github/README.md index dba6dc73d..77f5144c0 100644 --- a/.github/README.md +++ b/.github/README.md @@ -147,6 +147,7 @@ | 🟢 | | Redis | https://redis.io/ | 从世界上最快的内存数据库创建者那里获取该数据库 | | | 🟢 | | RssHub | https://rsshub.app/ | 从任何内容生成 RSS/Atom/JSON 订阅源 | | | 🟢 | | RustDesk API | https://github.com/lejianwen/rustdesk-api/ | RustDesk 的 API 管理平台 | RustDesk衍生 | +| 🟢 | | RustFS | https://rustfs.com/ | 分布式存储系统 | | | 🟢 | | Sentinel | https://sentinelguard.io/ | 面向分布式、多语言异构化服务架构的流量治理组件 | | | 🟢 | | Shiori | https://github.com/go-shiori/shiori | 简单书签管理器,旨在作为 Pocket 的简单克隆 | | | 🟢 | | 思源笔记 | https://b3log.org/siyuan/ | 【思源笔记】一款隐私优先、自托管、完全开源的个人知识管理软件 | | diff --git a/README.md b/README.md index abef74c76..17504ecf7 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ | 🟢 | | Redis | https://redis.io/ | 从世界上最快的内存数据库创建者那里获取该数据库 | | | 🟢 | | RssHub | https://rsshub.app/ | 从任何内容生成 RSS/Atom/JSON 订阅源 | | | 🟢 | | RustDesk API | https://github.com/lejianwen/rustdesk-api/ | RustDesk 的 API 管理平台 | RustDesk衍生 | +| 🟢 | | RustFS | https://rustfs.com/ | 分布式存储系统 | | | 🟢 | | Sentinel | https://sentinelguard.io/ | 面向分布式、多语言异构化服务架构的流量治理组件 | | | 🟢 | | Shiori | https://github.com/go-shiori/shiori | 简单书签管理器,旨在作为 Pocket 的简单克隆 | | | 🟢 | | 思源笔记 | https://b3log.org/siyuan/ | 【思源笔记】一款隐私优先、自托管、完全开源的个人知识管理软件 | | diff --git a/apps/rustfs/README.md b/apps/rustfs/README.md new file mode 100644 index 000000000..7ea296a27 --- /dev/null +++ b/apps/rustfs/README.md @@ -0,0 +1,37 @@ +# RustFS + +Rust驱动的S3兼容分布式存储系统 + +![RustFS](https://file.lifebus.top/imgs/rustfs_cover.png) + +![](https://img.shields.io/badge/%E6%96%B0%E7%96%86%E8%90%8C%E6%A3%AE%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91%E5%B7%A5%E4%BD%9C%E5%AE%A4-%E6%8F%90%E4%BE%9B%E6%8A%80%E6%9C%AF%E6%94%AF%E6%8C%81-blue) + +## 简介 + +RustFS 用热门安全的 Rust 语言开发,兼容 S3 协议。适用于 AI/ML 及海量数据存储、大数据、互联网、工业和保密存储等全部场景。近乎免费使用。遵循 +Apache 2 协议,支持国产保密设备和系统。 + +## 特性 + +### 跨云支持 +RustFS 利用分布式架构和对象存储功能,为AI和高级分析工作负载提供卓越性能,支持从TB到EB级别的数据扩展。 + +### 安全可靠 +RustFS 与 RustyVault 集成,提供高性能的对象存储安全加密,支持多种加密模式,确保数据安全性和透明度。 + +### 版本控制 +对象存储版本控制功能,为每个对象版本分配唯一标识符,用户可通过API或管理界面访问和管理历史版本。 + +### 无限扩容 +RustFS系统自动平衡节点负载,确保数据均匀分布,支持根据存储需求动态添加或移除资源,实现无限扩容。 + +### 对象只读 +支持对象锁定模式,实现WORM(写一次读多次)功能,防止数据在指定时间范围内被修改或删除,确保数据完整性。 + +### 主动复制 +对象写入时自动创建多个副本并分布到不同节点,支持同步和异步复制模式,提供高可用性和灾难恢复能力。 + + +--- + +![Ms Studio](https://file.lifebus.top/imgs/ms_blank_001.png) diff --git a/apps/rustfs/data.yml b/apps/rustfs/data.yml new file mode 100644 index 000000000..55bef0615 --- /dev/null +++ b/apps/rustfs/data.yml @@ -0,0 +1,15 @@ +additionalProperties: + key: rustfs + name: RustFS + tags: + - WebSite + - Storage + - Local + shortDescZh: 分布式存储系统 + shortDescEn: Distributed Storage System + type: website + crossVersionUpdate: true + limit: 0 + website: https://rustfs.com/ + github: https://github.com/rustfs/rustfs/ + document: https://rustfs.com/ diff --git a/apps/rustfs/latest/data.yml b/apps/rustfs/latest/data.yml new file mode 100644 index 000000000..f21457320 --- /dev/null +++ b/apps/rustfs/latest/data.yml @@ -0,0 +1,71 @@ +additionalProperties: + formFields: + - default: "/home/rustfs" + edit: true + envKey: RUSTFS_ROOT_PATH + labelZh: 数据持久化路径 + labelEn: Data persistence path + required: true + type: text + - default: 9000 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelZh: WebUI 端口 + labelEn: WebUI port + required: true + rule: paramPort + type: number + - default: "rustfsadmin" + edit: true + envKey: RUSTFS_ACCESS_KEY + labelZh: 管理员账号 + labelEn: Access Key + required: true + type: text + - default: "rustfsadmin" + edit: true + envKey: RUSTFS_SECRET_KEY + labelZh: 管理员密码 + labelEn: Secret Key + required: true + type: text + - default: "127.0.0.1:9000" + edit: true + envKey: RUSTFS_SERVER_DOMAINS + labelZh: 域名 + labelEn: Domains + required: false + type: text + - default: "true" + edit: true + envKey: RUSTFS_CONSOLE_ENABLE + labelZh: 启用控制台 + labelEn: Enable Console + required: true + type: select + values: + - label: 启用 + value: "true" + - label: 禁用 + value: "false" + - default: "" + edit: true + envKey: CUSTOM_MOUNT_DIRECTORY_1 + labelEn: Custom mount directory 1 + labelZh: 自定义挂载目录 1 + required: false + type: text + - default: "" + edit: true + envKey: CUSTOM_MOUNT_DIRECTORY_2 + labelEn: Custom mount directory 2 + labelZh: 自定义挂载目录 2 + required: false + type: text + - default: "" + edit: true + envKey: CUSTOM_MOUNT_DIRECTORY_3 + labelEn: Custom mount directory 3 + labelZh: 自定义挂载目录 3 + required: false + type: text diff --git a/apps/rustfs/latest/docker-compose.yml b/apps/rustfs/latest/docker-compose.yml new file mode 100644 index 000000000..bf4915ddd --- /dev/null +++ b/apps/rustfs/latest/docker-compose.yml @@ -0,0 +1,26 @@ +networks: + 1panel-network: + external: true + +services: + rustfs: + image: rustfs/rustfs:latest + container_name: ${CONTAINER_NAME} + labels: + createdBy: "Apps" + restart: always + networks: + - 1panel-network + ports: + - ${PANEL_APP_PORT_HTTP}:9000 + env_file: + - ${GLOBAL_ENV_FILE:-/etc/1panel/envs/global.env} + - ${ENV_FILE:-/etc/1panel/envs/default.env} + volumes: + - ${RUSTFS_ROOT_PATH}/data:/etc/rustfs + - ${CUSTOM_MOUNT_DIRECTORY_1:-./default_mount_1}:${CUSTOM_MOUNT_DIRECTORY_1:-/default_mount_1} + - ${CUSTOM_MOUNT_DIRECTORY_2:-./default_mount_2}:${CUSTOM_MOUNT_DIRECTORY_2:-/default_mount_2} + - ${CUSTOM_MOUNT_DIRECTORY_3:-./default_mount_3}:${CUSTOM_MOUNT_DIRECTORY_3:-/default_mount_3} + environment: + - TZ=Asia/Shanghai + - RUSTFS_ADDRESS=:9000 diff --git a/apps/rustfs/latest/envs/default.env b/apps/rustfs/latest/envs/default.env new file mode 100644 index 000000000..cd05f46e6 --- /dev/null +++ b/apps/rustfs/latest/envs/default.env @@ -0,0 +1,2 @@ +# copyright© 2024 XinJiang Ms Studio +ENV_FILE=.env diff --git a/apps/rustfs/latest/envs/global.env b/apps/rustfs/latest/envs/global.env new file mode 100644 index 000000000..e10989fe4 --- /dev/null +++ b/apps/rustfs/latest/envs/global.env @@ -0,0 +1,2 @@ +# copyright© 2024 XinJiang Ms Studio +TZ=Asia/Shanghai diff --git a/apps/rustfs/latest/scripts/init.sh b/apps/rustfs/latest/scripts/init.sh new file mode 100644 index 000000000..07fb8c3fe --- /dev/null +++ b/apps/rustfs/latest/scripts/init.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +if [ -f .env ]; then + source .env + + # setup-1 add default values + CURRENT_DIR=$(pwd) + sed -i '/^ENV_FILE=/d' .env + sed -i '/^GLOBAL_ENV_FILE=/d' .env + echo "ENV_FILE=${CURRENT_DIR}/.env" >> .env + echo "GLOBAL_ENV_FILE=${CURRENT_DIR}/envs/global.env" >> .env + + echo "Check Finish." + +else + echo "Error: .env file not found." +fi diff --git a/apps/rustfs/latest/scripts/uninstall.sh b/apps/rustfs/latest/scripts/uninstall.sh new file mode 100644 index 000000000..c86c4fbca --- /dev/null +++ b/apps/rustfs/latest/scripts/uninstall.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [ -f .env ]; then + source .env + + echo "Check Finish." + +else + echo "Error: .env file not found." +fi diff --git a/apps/rustfs/latest/scripts/upgrade.sh b/apps/rustfs/latest/scripts/upgrade.sh new file mode 100644 index 000000000..07fb8c3fe --- /dev/null +++ b/apps/rustfs/latest/scripts/upgrade.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +if [ -f .env ]; then + source .env + + # setup-1 add default values + CURRENT_DIR=$(pwd) + sed -i '/^ENV_FILE=/d' .env + sed -i '/^GLOBAL_ENV_FILE=/d' .env + echo "ENV_FILE=${CURRENT_DIR}/.env" >> .env + echo "GLOBAL_ENV_FILE=${CURRENT_DIR}/envs/global.env" >> .env + + echo "Check Finish." + +else + echo "Error: .env file not found." +fi diff --git a/apps/rustfs/logo.png b/apps/rustfs/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..68d8d93902ebabba057aa9b3024f7117229096eb GIT binary patch literal 23262 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 gdCMP( + + + + + + + + + + + + + +