clash-linux commited on
Commit
99187f2
·
verified ·
1 Parent(s): 704e471

Upload 13 files

Browse files
Files changed (5) hide show
  1. Dockerfile +7 -2
  2. README.md +15 -4
  3. app.py +88 -0
  4. app/sub_manager.py +2 -2
  5. entrypoint.sh +41 -6
Dockerfile CHANGED
@@ -87,8 +87,13 @@ COPY app/ ./app/
87
  COPY entrypoint.sh ./
88
  RUN chmod +x ./entrypoint.sh
89
 
90
- # 暴露单一端口 (Hugging Face Spaces要求)
91
- EXPOSE 8000
 
 
 
 
 
92
 
93
  # 使用entrypoint脚本启动应用
94
  ENTRYPOINT ["/app/entrypoint.sh"]
 
87
  COPY entrypoint.sh ./
88
  RUN chmod +x ./entrypoint.sh
89
 
90
+ # 暴露端口
91
+ # 7860: Web界面和API服务 (Hugging Face Spaces默认端口)
92
+ # 7890: Clash代理服务 (仅在本地/自托管部署时直接暴露)
93
+ # 9090: Clash内部API端口 (仅供内部服务通信使用)
94
+ EXPOSE 7860
95
+ EXPOSE 7890
96
+ # 注意:9090端口仅供内部使用,不对外暴露
97
 
98
  # 使用entrypoint脚本启动应用
99
  ENTRYPOINT ["/app/entrypoint.sh"]
README.md CHANGED
@@ -4,7 +4,7 @@ emoji: 🚀
4
  colorFrom: blue
5
  colorTo: indigo
6
  sdk: docker
7
- app_port: 8000
8
  pinned: false
9
  ---
10
 
@@ -16,7 +16,10 @@ pinned: false
16
 
17
  - 🚀 **轻量级**:基于Python Flask和Clash Core,最小化依赖
18
  - 🔄 **机场订阅支持**:自动下载并转换您的机场订阅链接
19
- - 🔌 **单端口模式**:通过路径区分API和代理流量,适合Hugging Face部署
 
 
 
20
  - 🔒 **API认证**:通过API Key保护控制API
21
  - 🔄 **动态切换节点**:通过API随时切换使用的节点
22
  - 🐳 **容器化**:完整的Docker支持,便于部署
@@ -89,6 +92,7 @@ simple-clash-relay/
89
  ```
90
  docker run -d \
91
  -p 7860:7860 \
 
92
  -e SUB_URL=你的订阅链接 \
93
  -e API_KEY=你的API密钥 \
94
  --name clash-relay \
@@ -193,14 +197,21 @@ POST /api/refresh
193
 
194
  ## 在应用中使用代理
195
 
196
- 由于使用单端口模式,您的应用需要使用以下代理配置:
197
 
 
 
 
 
 
198
  - HTTP代理: `http://your-space-name.hf.space/proxy`
199
  - SOCKS5代理: `socks5://your-space-name.hf.space/proxy`
200
 
201
  ### 在cursor-to-openai项目中配置
202
 
203
- 修改您的cursor-to-openai项目配置,设置代理地址为`http://your-space-name.hf.space/proxy`。
 
 
204
 
205
  ## 注意事项
206
 
 
4
  colorFrom: blue
5
  colorTo: indigo
6
  sdk: docker
7
+ app_port: 7860
8
  pinned: false
9
  ---
10
 
 
16
 
17
  - 🚀 **轻量级**:基于Python Flask和Clash Core,最小化依赖
18
  - 🔄 **机场订阅支持**:自动下载并转换您的机场订阅链接
19
+ - 🔌 **多端口服务**:
20
+ - **7860**: Web界面和API服务(Hugging Face默认端口)
21
+ - **7890**: Clash代理服务
22
+ - **9090**: Clash内部API服务
23
  - 🔒 **API认证**:通过API Key保护控制API
24
  - 🔄 **动态切换节点**:通过API随时切换使用的节点
25
  - 🐳 **容器化**:完整的Docker支持,便于部署
 
92
  ```
93
  docker run -d \
94
  -p 7860:7860 \
95
+ -p 7890:7890 \
96
  -e SUB_URL=你的订阅链接 \
97
  -e API_KEY=你的API密钥 \
98
  --name clash-relay \
 
197
 
198
  ## 在应用中使用代理
199
 
200
+ 您可以通过以下方式使用代理服务:
201
 
202
+ ### 标准模式
203
+ - HTTP代理: `http://your-server-ip:7890`
204
+ - SOCKS5代理: `socks5://your-server-ip:7890`
205
+
206
+ ### Hugging Face Spaces模式 (代理路径转发)
207
  - HTTP代理: `http://your-space-name.hf.space/proxy`
208
  - SOCKS5代理: `socks5://your-space-name.hf.space/proxy`
209
 
210
  ### 在cursor-to-openai项目中配置
211
 
212
+ 修改您的cursor-to-openai项目配置,设置代理地址:
213
+ - 本地部署:`http://localhost:7890`
214
+ - Hugging Face部署:`http://your-space-name.hf.space/proxy`
215
 
216
  ## 注意事项
217
 
app.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Hugging Face Spaces 启动入口
3
+ """
4
+
5
+ import os
6
+ import sys
7
+ import subprocess
8
+ import time
9
+ import signal
10
+ import atexit
11
+
12
+ def setup_environment():
13
+ """设置必要的环境变量和目录"""
14
+ # 确保数据目录存在
15
+ os.makedirs("data", exist_ok=True)
16
+
17
+ # 设置执行权限
18
+ if os.path.exists("subconverter/subconverter"):
19
+ os.chmod("subconverter/subconverter", 0o755)
20
+
21
+ if os.path.exists("clash_core/clash.meta-linux-amd64"):
22
+ os.chmod("clash_core/clash.meta-linux-amd64", 0o755)
23
+
24
+ # 设置环境变量
25
+ os.environ["FLASK_PORT"] = "7860" # HF Spaces 要求的端口
26
+
27
+ # 如果没有设置 SUB_URL 环境变量,尝试从 .env 加载
28
+ if not os.environ.get("SUB_URL") and os.path.exists(".env"):
29
+ with open(".env", "r") as f:
30
+ for line in f:
31
+ line = line.strip()
32
+ if line and not line.startswith("#"):
33
+ key, value = line.split("=", 1)
34
+ os.environ[key] = value
35
+
36
+ def start_app():
37
+ """启动应用程序"""
38
+ print("正在启动 Simple Clash Relay...")
39
+
40
+ # 使用 gunicorn 启动 Flask 应用
41
+ app_process = subprocess.Popen(
42
+ ["gunicorn", "--bind", "0.0.0.0:7860", "--workers", "2", "--threads", "4", "--timeout", "120", "app.main:app"],
43
+ stdout=subprocess.PIPE,
44
+ stderr=subprocess.STDOUT,
45
+ universal_newlines=True
46
+ )
47
+
48
+ # 注册应用程序退出时的清理函数
49
+ def cleanup():
50
+ print("正在停止应用...")
51
+ app_process.terminate()
52
+ try:
53
+ app_process.wait(timeout=5)
54
+ except subprocess.TimeoutExpired:
55
+ app_process.kill()
56
+
57
+ atexit.register(cleanup)
58
+
59
+ # 信号处理
60
+ def signal_handler(sig, frame):
61
+ print(f"接收到信号 {sig},正在退出...")
62
+ cleanup()
63
+ sys.exit(0)
64
+
65
+ signal.signal(signal.SIGINT, signal_handler)
66
+ signal.signal(signal.SIGTERM, signal_handler)
67
+
68
+ # 输出应用程序日志
69
+ while True:
70
+ output = app_process.stdout.readline()
71
+ if output:
72
+ print(output, end="")
73
+
74
+ # 如果进程已经退出,退出循环
75
+ if app_process.poll() is not None:
76
+ break
77
+
78
+ # 获取剩余输出
79
+ remaining_output, _ = app_process.communicate()
80
+ if remaining_output:
81
+ print(remaining_output, end="")
82
+
83
+ return app_process.returncode
84
+
85
+ if __name__ == "__main__":
86
+ setup_environment()
87
+ exit_code = start_app()
88
+ sys.exit(exit_code)
app/sub_manager.py CHANGED
@@ -122,8 +122,8 @@ class SubscriptionManager:
122
  cmd = [
123
  self.subconverter_path,
124
  "-g", # 生成配置文件
125
- "--target", "clash", # 输出格式为Clash (修改自 --artifact)
126
- "--input", input_file, # 输入文件
127
  "--output", self.config_path, # 输出文件
128
  "--include-remarks", ".*" # 包含所有节点
129
  ]
 
122
  cmd = [
123
  self.subconverter_path,
124
  "-g", # 生成配置文件
125
+ "--target", "clash", # 输出格式为Clash (修正为 --target)
126
+ "--url", input_file, # 修正为 --url 参数
127
  "--output", self.config_path, # 输出文件
128
  "--include-remarks", ".*" # 包含所有节点
129
  ]
entrypoint.sh CHANGED
@@ -2,6 +2,46 @@
2
  # Exit immediately if a command exits with a non-zero status.
3
  set -e
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  # 输出基本信息
6
  echo "=========================="
7
  echo " Simple Clash Relay"
@@ -17,18 +57,13 @@ echo "SUB_URL: [hidden]"
17
  echo "API_KEY: [hidden]"
18
 
19
  # 检查必要的环境变量
20
- if [ -z "$SUB_URL" ]; then
21
- echo "ERROR: Required environment variable SUB_URL is not set!"
22
- exit 1
23
- fi
24
-
25
  if [ -z "$API_KEY" ]; then
26
  echo "WARNING: API_KEY is not set. Using default value (insecure)!"
27
  export API_KEY="changeme"
28
  fi
29
 
30
  # 启动Flask应用
31
- echo "Starting Flask application on port ${FLASK_PORT:-8000}..."
32
 
33
  # 使用gunicorn启动Flask应用(生产环境推荐)
34
  # 如果WORKER_COUNT未设置,使用CPU核心数+1的worker数量
 
2
  # Exit immediately if a command exits with a non-zero status.
3
  set -e
4
 
5
+ # 设置颜色输出
6
+ RED='\033[0;31m'
7
+ GREEN='\033[0;32m'
8
+ YELLOW='\033[1;33m'
9
+ NC='\033[0m' # No Color
10
+
11
+ echo "${GREEN}Starting Simple Clash Relay...${NC}"
12
+
13
+ # 确保数据目录存在并设置权限
14
+ mkdir -p /app/data
15
+ chmod -R 777 /app/data
16
+
17
+ # 确保subconverter有执行权限
18
+ chmod +x /app/subconverter/subconverter
19
+
20
+ # 确保Clash Core有执行权限
21
+ if [ -f "/app/clash_core/clash.meta-linux-amd64" ]; then
22
+ chmod +x /app/clash_core/clash.meta-linux-amd64
23
+ echo "${GREEN}Set executable permission for Clash Meta${NC}"
24
+ else
25
+ echo "${RED}Error: Clash Core executable not found!${NC}"
26
+ exit 1
27
+ fi
28
+
29
+ # 加载环境变量
30
+ if [ -f ".env" ]; then
31
+ echo "${GREEN}Loading environment variables from .env file...${NC}"
32
+ export $(grep -v '^#' .env | xargs -d '\n')
33
+ fi
34
+
35
+ # 检查必要的环境变量
36
+ if [ -z "$SUB_URL" ]; then
37
+ echo "${RED}Error: SUB_URL environment variable is not set!${NC}"
38
+ exit 1
39
+ fi
40
+
41
+ # 设置默认端口
42
+ export FLASK_PORT=${FLASK_PORT:-7860}
43
+ echo "${GREEN}Flask will listen on port ${FLASK_PORT}${NC}"
44
+
45
  # 输出基本信息
46
  echo "=========================="
47
  echo " Simple Clash Relay"
 
57
  echo "API_KEY: [hidden]"
58
 
59
  # 检查必要的环境变量
 
 
 
 
 
60
  if [ -z "$API_KEY" ]; then
61
  echo "WARNING: API_KEY is not set. Using default value (insecure)!"
62
  export API_KEY="changeme"
63
  fi
64
 
65
  # 启动Flask应用
66
+ echo "${GREEN}Starting Flask application...${NC}"
67
 
68
  # 使用gunicorn启动Flask应用(生产环境推荐)
69
  # 如果WORKER_COUNT未设置,使用CPU核心数+1的worker数量