From e6164b17da7af2727d1ccae7e5a95a8acfb36e5b Mon Sep 17 00:00:00 2001 From: okxlin Date: Sun, 4 Aug 2024 01:07:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0clouddrive=E5=88=B0?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/clouddrive/0.7.10/.env.sample | 8 +++ apps/clouddrive/0.7.10/data.yml | 57 ++++++++++++++++++++++ apps/clouddrive/0.7.10/docker-compose.yml | 26 ++++++++++ apps/clouddrive/README.md | 4 ++ apps/clouddrive/data.yml | 19 ++++++++ apps/clouddrive/latest/.env.sample | 8 +++ apps/clouddrive/latest/data.yml | 57 ++++++++++++++++++++++ apps/clouddrive/latest/docker-compose.yml | 26 ++++++++++ apps/clouddrive/logo.png | Bin 0 -> 9334 bytes 9 files changed, 205 insertions(+) create mode 100644 apps/clouddrive/0.7.10/.env.sample create mode 100644 apps/clouddrive/0.7.10/data.yml create mode 100644 apps/clouddrive/0.7.10/docker-compose.yml create mode 100644 apps/clouddrive/README.md create mode 100644 apps/clouddrive/data.yml create mode 100644 apps/clouddrive/latest/.env.sample create mode 100644 apps/clouddrive/latest/data.yml create mode 100644 apps/clouddrive/latest/docker-compose.yml create mode 100644 apps/clouddrive/logo.png diff --git a/apps/clouddrive/0.7.10/.env.sample b/apps/clouddrive/0.7.10/.env.sample new file mode 100644 index 00000000..7f895d0a --- /dev/null +++ b/apps/clouddrive/0.7.10/.env.sample @@ -0,0 +1,8 @@ +APP_DATA_PATH="./data/Config" +CLOUDDRIVE_HOME="/Config" +CLOUD_MOUNTS_PATH="./data/CloudNAS" +CONTAINER_NAME="clouddrive" +PANEL_APP_PORT_HTTP=40275 +PRIVILEGED_MODE="true" +SHARED_MEDIA_PATH="./data/media" +TZ="Asia/Shanghai" diff --git a/apps/clouddrive/0.7.10/data.yml b/apps/clouddrive/0.7.10/data.yml new file mode 100644 index 00000000..b6dcee04 --- /dev/null +++ b/apps/clouddrive/0.7.10/data.yml @@ -0,0 +1,57 @@ +additionalProperties: + formFields: + - default: "40275" + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: "Asia/Shanghai" + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + required: true + type: text + - default: "/Config" + disabled: true + envKey: CLOUDDRIVE_HOME + labelEn: CloudDrive Home + labelZh: CloudDrive 根目录 + required: true + type: text + - default: "./data/CloudNAS" + edit: true + envKey: CLOUD_MOUNTS_PATH + labelEn: Cloud Mounts Path + labelZh: 云挂载路径 + required: true + type: text + - default: "./data/Config" + edit: true + envKey: APP_DATA_PATH + labelEn: App Data Path + labelZh: 应用数据路径 + required: true + type: text + - default: "./data/media" + edit: true + envKey: SHARED_MEDIA_PATH + labelEn: Shared Media Path + labelZh: 共享媒体路径 + required: true + type: text + - default: "true" + edit: true + envKey: PRIVILEGED_MODE + labelEn: Privileged Mode + labelZh: 特权模式 + required: true + type: select + values: + - label: "True" + value: "true" + - label: "False" + value: "false" diff --git a/apps/clouddrive/0.7.10/docker-compose.yml b/apps/clouddrive/0.7.10/docker-compose.yml new file mode 100644 index 00000000..a242c93a --- /dev/null +++ b/apps/clouddrive/0.7.10/docker-compose.yml @@ -0,0 +1,26 @@ +services: + clouddrive: + image: "cloudnas/clouddrive2:0.7.10" + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:19798" + environment: + - TZ=${TZ} + - CLOUDDRIVE_HOME=${CLOUDDRIVE_HOME} + volumes: + - ${CLOUD_MOUNTS_PATH}:/CloudNAS:shared + - ${APP_DATA_PATH}:${CLOUDDRIVE_HOME} + - ${SHARED_MEDIA_PATH}:/media:shared + devices: + - /dev/fuse:/dev/fuse + pid: "host" + privileged: ${PRIVILEGED_MODE} + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/clouddrive/README.md b/apps/clouddrive/README.md new file mode 100644 index 00000000..92e4ca88 --- /dev/null +++ b/apps/clouddrive/README.md @@ -0,0 +1,4 @@ +CloudDrive - 解锁云存储的无限可能 +======================= + +CloudDrive是一个强大的多云盘管理工具,为用户提供包含云盘本地挂载的一站式的多云盘解决方案。 diff --git a/apps/clouddrive/data.yml b/apps/clouddrive/data.yml new file mode 100644 index 00000000..4a152519 --- /dev/null +++ b/apps/clouddrive/data.yml @@ -0,0 +1,19 @@ +name: CloudDrive +tags: + - 云存储 +title: 一个强大的多云盘管理工具 +description: 一个强大的多云盘管理工具 +additionalProperties: + key: clouddrive + name: CloudDrive + tags: + - Storage + shortDescZh: 一个强大的多云盘管理工具 + shortDescEn: A powerful multi-cloud drive management tool + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://www.clouddrive2.com + github: https://hub.docker.com/r/cloudnas/clouddrive2 + document: https://www.clouddrive2.com diff --git a/apps/clouddrive/latest/.env.sample b/apps/clouddrive/latest/.env.sample new file mode 100644 index 00000000..7f895d0a --- /dev/null +++ b/apps/clouddrive/latest/.env.sample @@ -0,0 +1,8 @@ +APP_DATA_PATH="./data/Config" +CLOUDDRIVE_HOME="/Config" +CLOUD_MOUNTS_PATH="./data/CloudNAS" +CONTAINER_NAME="clouddrive" +PANEL_APP_PORT_HTTP=40275 +PRIVILEGED_MODE="true" +SHARED_MEDIA_PATH="./data/media" +TZ="Asia/Shanghai" diff --git a/apps/clouddrive/latest/data.yml b/apps/clouddrive/latest/data.yml new file mode 100644 index 00000000..b6dcee04 --- /dev/null +++ b/apps/clouddrive/latest/data.yml @@ -0,0 +1,57 @@ +additionalProperties: + formFields: + - default: "40275" + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: "Asia/Shanghai" + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + required: true + type: text + - default: "/Config" + disabled: true + envKey: CLOUDDRIVE_HOME + labelEn: CloudDrive Home + labelZh: CloudDrive 根目录 + required: true + type: text + - default: "./data/CloudNAS" + edit: true + envKey: CLOUD_MOUNTS_PATH + labelEn: Cloud Mounts Path + labelZh: 云挂载路径 + required: true + type: text + - default: "./data/Config" + edit: true + envKey: APP_DATA_PATH + labelEn: App Data Path + labelZh: 应用数据路径 + required: true + type: text + - default: "./data/media" + edit: true + envKey: SHARED_MEDIA_PATH + labelEn: Shared Media Path + labelZh: 共享媒体路径 + required: true + type: text + - default: "true" + edit: true + envKey: PRIVILEGED_MODE + labelEn: Privileged Mode + labelZh: 特权模式 + required: true + type: select + values: + - label: "True" + value: "true" + - label: "False" + value: "false" diff --git a/apps/clouddrive/latest/docker-compose.yml b/apps/clouddrive/latest/docker-compose.yml new file mode 100644 index 00000000..622c9d9a --- /dev/null +++ b/apps/clouddrive/latest/docker-compose.yml @@ -0,0 +1,26 @@ +services: + clouddrive: + image: "cloudnas/clouddrive2:latest" + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:19798" + environment: + - TZ=${TZ} + - CLOUDDRIVE_HOME=${CLOUDDRIVE_HOME} + volumes: + - ${CLOUD_MOUNTS_PATH}:/CloudNAS:shared + - ${APP_DATA_PATH}:${CLOUDDRIVE_HOME} + - ${SHARED_MEDIA_PATH}:/media:shared + devices: + - /dev/fuse:/dev/fuse + pid: "host" + privileged: ${PRIVILEGED_MODE} + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/clouddrive/logo.png b/apps/clouddrive/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2be2aef7de493d5227421e4743d97390a6cd114a GIT binary patch literal 9334 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 kfl@$cM4oIf2jZ%K0WSXK3