From 0689f83f289cc983d1ed6f4c16e2c1af5d452382 Mon Sep 17 00:00:00 2001 From: Meng Sen Date: Tue, 5 Aug 2025 11:04:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=91=E5=B8=83=E5=BA=94=E7=94=A8=20KSpeeder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Meng Sen --- apps/kspeeder/0.3.0/data.yml | 25 ++++++++++++++ apps/kspeeder/0.3.0/docker-compose.yml | 24 +++++++++++++ apps/kspeeder/0.3.0/envs/default.env | 2 ++ apps/kspeeder/0.3.0/envs/global.env | 2 ++ apps/kspeeder/0.3.0/scripts/init.sh | 17 ++++++++++ apps/kspeeder/0.3.0/scripts/uninstall.sh | 10 ++++++ apps/kspeeder/0.3.0/scripts/upgrade.sh | 17 ++++++++++ apps/kspeeder/README.md | 41 +++++++++++++++++++++++ apps/kspeeder/data.yml | 14 ++++++++ apps/kspeeder/logo.png | Bin 0 -> 13127 bytes apps/kspeeder/logo.svg | 5 +++ 11 files changed, 157 insertions(+) create mode 100644 apps/kspeeder/0.3.0/data.yml create mode 100644 apps/kspeeder/0.3.0/docker-compose.yml create mode 100644 apps/kspeeder/0.3.0/envs/default.env create mode 100644 apps/kspeeder/0.3.0/envs/global.env create mode 100644 apps/kspeeder/0.3.0/scripts/init.sh create mode 100644 apps/kspeeder/0.3.0/scripts/uninstall.sh create mode 100644 apps/kspeeder/0.3.0/scripts/upgrade.sh create mode 100644 apps/kspeeder/README.md create mode 100644 apps/kspeeder/data.yml create mode 100644 apps/kspeeder/logo.png create mode 100644 apps/kspeeder/logo.svg diff --git a/apps/kspeeder/0.3.0/data.yml b/apps/kspeeder/0.3.0/data.yml new file mode 100644 index 000000000..2806d8b15 --- /dev/null +++ b/apps/kspeeder/0.3.0/data.yml @@ -0,0 +1,25 @@ +additionalProperties: + formFields: + - default: "/home/kspeeder" + edit: true + envKey: KSPEEDER_ROOT_PATH + labelZh: 数据持久化路径 + labelEn: Data persistence path + required: true + type: text + - default: 5003 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelZh: WebUI 管理监控 + labelEn: WebUI Manage Monitoring + required: true + rule: paramPort + type: number + - default: 5443 + edit: true + envKey: PANEL_APP_PORT_API + labelZh: 主服务端口 + labelEn: Primary Service Port + required: true + rule: paramPort + type: number diff --git a/apps/kspeeder/0.3.0/docker-compose.yml b/apps/kspeeder/0.3.0/docker-compose.yml new file mode 100644 index 000000000..8cbeea00a --- /dev/null +++ b/apps/kspeeder/0.3.0/docker-compose.yml @@ -0,0 +1,24 @@ +networks: + 1panel-network: + external: true + +services: + kspeeder: + image: linkease/kspeeder:0.3.0 + container_name: ${CONTAINER_NAME} + labels: + createdBy: "Apps" + restart: always + networks: + - 1panel-network + ports: + - ${PANEL_APP_PORT_HTTP}:5003 + - ${PANEL_APP_PORT_API}:5443 + env_file: + - ${GLOBAL_ENV_FILE:-/etc/1panel/envs/global.env} + - ${ENV_FILE:-/etc/1panel/envs/default.env} + volumes: + - ${KSPEEDER_ROOT_PATH}/data:/kspeeder-data + - ${KSPEEDER_ROOT_PATH}/config:/kspeeder-config + environment: + - TZ=Asia/Shanghai diff --git a/apps/kspeeder/0.3.0/envs/default.env b/apps/kspeeder/0.3.0/envs/default.env new file mode 100644 index 000000000..cd05f46e6 --- /dev/null +++ b/apps/kspeeder/0.3.0/envs/default.env @@ -0,0 +1,2 @@ +# copyright© 2024 XinJiang Ms Studio +ENV_FILE=.env diff --git a/apps/kspeeder/0.3.0/envs/global.env b/apps/kspeeder/0.3.0/envs/global.env new file mode 100644 index 000000000..e10989fe4 --- /dev/null +++ b/apps/kspeeder/0.3.0/envs/global.env @@ -0,0 +1,2 @@ +# copyright© 2024 XinJiang Ms Studio +TZ=Asia/Shanghai diff --git a/apps/kspeeder/0.3.0/scripts/init.sh b/apps/kspeeder/0.3.0/scripts/init.sh new file mode 100644 index 000000000..07fb8c3fe --- /dev/null +++ b/apps/kspeeder/0.3.0/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/kspeeder/0.3.0/scripts/uninstall.sh b/apps/kspeeder/0.3.0/scripts/uninstall.sh new file mode 100644 index 000000000..c86c4fbca --- /dev/null +++ b/apps/kspeeder/0.3.0/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/kspeeder/0.3.0/scripts/upgrade.sh b/apps/kspeeder/0.3.0/scripts/upgrade.sh new file mode 100644 index 000000000..07fb8c3fe --- /dev/null +++ b/apps/kspeeder/0.3.0/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/kspeeder/README.md b/apps/kspeeder/README.md new file mode 100644 index 000000000..12666901d --- /dev/null +++ b/apps/kspeeder/README.md @@ -0,0 +1,41 @@ +# KSpeeder + +Docker镜像加速专家 多镜像并发下载,动态负载均衡,断点续传支持,Docker镜像代理服务 + +![KSpeeder](https://file.lifebus.top/imgs/kspeeder_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) + +## 简介 + +Docker KSpeeder 是一个基于 Alpine Linux 的 KSpeeder 容器化部署方案。KSpeeder 是一个用于优化 Docker +镜像仓库访问的工具,它提供了智能镜像源选择、下载加速、状态监控等功能。本项目提供了多架构支持,可以在不同的硬件平台上运行。 + +## 软件特性 + +### Docker 镜像仓库代理服务 + ++ 支持 HTTPS 协议 ++ 自动配置 Docker 镜像源 ++ 支持证书自动获取和缓存 ++ 支持多架构(AMD64/ARM64/ARM) ++ 智能镜像源选择和自动切换 ++ 实时下载速度监控 ++ 可视化状态监控界面 + +### 限速文件服务器 + ++ 支持可配置的带宽限制 ++ 基于目录的文件服务 ++ HTTP 协议支持 + +### 网络优化 + ++ 支持 HTTP/2 协议 ++ 支持自定义超时设置 ++ 内置连接池管理 ++ 异步读取优化 + +--- + +![Ms Studio](https://file.lifebus.top/imgs/ms_blank_001.png) diff --git a/apps/kspeeder/data.yml b/apps/kspeeder/data.yml new file mode 100644 index 000000000..d45ba630e --- /dev/null +++ b/apps/kspeeder/data.yml @@ -0,0 +1,14 @@ +additionalProperties: + key: kspeeder + name: KSpeeder + tags: + - WebSite + - Local + shortDescZh: Docker镜像加速专家 + shortDescEn: Docker Image Accelerator Expert + type: website + crossVersionUpdate: true + limit: 0 + website: https://kspeeder.istoreos.com/ + github: https://github.com/linkease/docker_kspeeder/ + document: https://kspeeder.istoreos.com/ diff --git a/apps/kspeeder/logo.png b/apps/kspeeder/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..10bd02829ce048733552ba1db3905a529f000e2e GIT binary patch literal 13127 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 + + + +