在VPS上部署Sub-Store (Docker Compose + Caddy)

Sub-Store是一个高级订阅管理工具,适用于Loon、Surge、Quantumult X、Shadowrocket和Clash等多种客户端。本教程将指导您如何使用Docker Compose同时部署Caddy和Sub-Store服务。

1. 创建完整的Docker Compose文件

创建一个包含Caddy和Sub-Store的Docker Compose文件:

1
nano docker-compose.yml

将以下内容粘贴进去:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
version: '3.8'

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config
    networks:
      - app_network
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
  
  sub-store:
    image: xream/sub-store:latest
    container_name: sub-store
    restart: always
    volumes:
      - sub_store_data:/opt/app/data
    environment:
      - SUB_STORE_BACKEND_API_PORT=3001
      - SUB_STORE_BACKEND_PREFIX=true
      - SUB_STORE_FRONTEND_BACKEND_PATH=/sEcUrEpaThExaMpLe98765
    expose:
      - "3001"
    networks:
      - app_network
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

networks:
  app_network:
    driver: bridge

volumes:
  caddy_data:
  caddy_config:
  sub_store_data:

注意:

  1. SUB_STORE_FRONTEND_BACKEND_PATH应替换为随机字符串,用于API访问安全
  2. 上述配置使用了一个名为app_network的桥接网络,无需外部网络
  3. Caddy容器会将80和443端口映射到主机,确保这些端口未被占用

2. 可选的环境变量配置

您可以根据需要添加以下可选的环境变量:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
environment:
  # 基础配置
  - SUB_STORE_FRONTEND_HOST=0.0.0.0       # 前端监听地址
  - SUB_STORE_FRONTEND_PORT=3001          # 前端监听端口
  
  # 自动同步和备份配置
  - SUB_STORE_BACKEND_SYNC_CRON=0 0 * * * # 每天0点自动同步订阅
  - SUB_STORE_BACKEND_UPLOAD_CRON=0 1 * * * # 每天1点自动备份配置
  - SUB_STORE_BACKEND_DOWNLOAD_CRON=30 2 * * 0 # 每周日2:30恢复配置
  
  # GitHub备份配置(可选)
  - GITHUB_USERNAME=your_github_username_here
  - GITHUB_TOKEN=your_github_token_here
  
  # 推送服务配置(可选)
  - SUB_STORE_PUSH_SERVICE=https://api.day.app/XXX/[推送标题]/[推送内容]?sound=shake

3. 创建Caddyfile配置

创建Caddyfile配置文件:

1
nano Caddyfile

添加以下配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# Sub-Store配置
sub.您的域名.com {
    reverse_proxy sub-store:3001
    encode gzip
    header {
        # 安全头部
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-XSS-Protection "1; mode=block"
        X-Content-Type-Options "nosniff"
        -Server
    }
}

# 如果有其他服务,可以添加在这里
# 例如: 
# n8n.您的域名.com {
#     reverse_proxy n8n:5678
#     encode gzip
# }

请将sub.您的域名.com替换为您实际使用的域名。

4. 启动所有服务

使用Docker Compose启动所有服务:

1
docker compose up -d

5. 验证服务运行状态

检查容器是否正常运行:

1
docker ps

查看各服务日志:

1
2
3
4
5
# 查看Sub-Store日志
docker logs sub-store

# 查看Caddy日志
docker logs caddy

6. 重新加载Caddy配置(如需修改配置)

如果后续需要修改Caddyfile,可以在编辑完成后重新加载配置:

1
docker exec -w /etc/caddy caddy caddy reload

7. 访问Sub-Store

在浏览器中访问:https://sub.您的域名.com

Sub-Store的API地址为:https://sub.您的域名.com/sEcUrEpaThExaMpLe98765

8. 订阅链接格式

使用订阅的格式为:

1
https://sub.您的域名.com/subs?api=https://sub.您的域名.com/sEcUrEpaThExaMpLe98765

如果使用默认端口和API路径,则完整访问地址为:

1
https://sub.您的域名.com/?api=https://sub.您的域名.com/sEcUrEpaThExaMpLe98765

9. 更新服务

当需要更新服务时,可以使用以下命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 拉取最新镜像
docker compose pull

# 更新所有服务
docker compose up -d

# 只更新Sub-Store
docker compose up -d --no-deps --build sub-store

# 清理无用镜像(可选)
docker system prune -f

安全建议

  1. 确保您的VPS防火墙开放了80和443端口
  2. SUB_STORE_FRONTEND_BACKEND_PATH的值应是随机生成的,不要使用简单或默认值
  3. 建议配置Caddy的HTTPS,保证数据传输安全
  4. 配置了安全的HTTP头信息,增强了访问安全性
  5. 考虑为Sub-Store添加访问认证,防止未授权访问

常见问题排查

如果遇到问题,可以查看容器日志:

1
docker logs sub-store

检查Caddy的日志:

1
docker logs caddy

如果无法访问,检查以下几点:

  • 确认容器是否正常运行:docker ps
  • 确认网络配置是否正确:docker network inspect app_network
  • 确认防火墙是否开放了必要的端口
  • 确认域名DNS是否正确配置指向您的服务器IP

与其他部署方式的对比

本教程使用Docker Compose同时部署Caddy和Sub-Store,相比其他方法有以下优势:

  1. 一体化配置:一个Docker Compose文件管理所有相关服务
  2. Docker隔离:使用Docker容器部署更安全,避免依赖冲突
  3. Caddy自动HTTPS:Caddy会自动申请和更新SSL证书,无需手动配置
  4. 易于维护:使用Compose文件管理服务,更新和备份更简便
  5. 高可靠性:容器自动重启策略确保服务持续运行
  6. 灵活性:可以轻松添加更多服务到同一环境中

进阶配置

为Sub-Store前端添加HTTP基本认证

如需添加基本认证,可以修改Caddyfile:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
sub.您的域名.com {
    reverse_proxy sub-store:3001
    encode gzip
    
    # 基本认证配置
    basicauth {
        用户名 加密密码
    }
    
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-XSS-Protection "1; mode=block"
        X-Content-Type-Options "nosniff"
        -Server
    }
}

要生成加密密码,可以使用:

1
docker exec -it caddy caddy hash-password

添加多个服务

如果您想在同一环境中添加更多服务(如RSSHub、N8N等),只需在docker-compose.yml中添加新的服务定义,并在Caddyfile中配置相应的反向代理规则即可。

IP访问限制

如需限制只允许特定IP访问,可以修改Caddyfile:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
sub.您的域名.com {
    @allowed_ips {
        remote_ip 192.168.1.0/24 10.0.0.0/8
    }
    handle @allowed_ips {
        reverse_proxy sub-store:3001
    }
    handle {
        respond "Access denied" 403
    }
    
    encode gzip
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-XSS-Protection "1; mode=block"
        X-Content-Type-Options "nosniff"
        -Server
    }
}

通过以上步骤,您已经成功在VPS上部署了自己的Sub-Store服务,可以开始享受便捷的订阅管理体验了!

Sub-Store 网页端使用指南

基础设置

1. 访问Sub-Store网页端

使用浏览器访问您部署的Sub-Store地址:

1
https://sub.您的域名.com

如果使用默认端口和API路径,则完整访问地址为:

1
https://sub.您的域名.com/?api=https://sub.您的域名.com/sEcUrEpaThExaMpLe98765

2. 配置后端

首次进入Sub-Store网页界面时,需要配置后端地址:

  1. 点击右上角的设置图标
  2. 在"后端设置"中填入您的API地址:https://sub.您的域名.com/sEcUrEpaThExaMpLe98765
  3. 点击"保存"

添加订阅

Sub-Store可以管理三种类型的订阅:

1. 添加机场订阅

  1. 点击左侧导航栏的"订阅"
  2. 点击右下角的"+“按钮
  3. 选择"添加订阅”
  4. 填写表单:
    • 名称:为订阅取一个易识别的名称
    • URL:粘贴您的机场订阅链接
    • 类型:选择"订阅"
  5. 点击"保存"

2. 添加个人节点

  1. 点击"+“按钮后选择"添加节点”
  2. 填写节点信息:
    • 名称:为节点命名
    • 类型:选择协议类型(如Shadowsocks、VMess、Trojan等)
    • 填写对应的服务器信息、端口、密码等
  3. 点击"保存"

3. 创建组合订阅

  1. 点击"+“按钮后选择"添加组合”
  2. 填写组合信息:
    • 名称:为组合订阅命名
    • 选择要包含的订阅或节点
  3. 点击"保存"

节点管理

1. 节点编辑与操作

选择一个已添加的订阅,进入订阅编辑页面,您可以进行以下操作:

基础操作

  • 过滤器:勾选以启用节点过滤功能
  • 排序:根据关键词对节点进行排序
  • 添加国旗:在节点名称前自动添加国家/地区旗帜
  • UDP转发:启用UDP流量转发
  • TCP Fast Open:启用TFO功能
  • 跳过证书验证:关闭TLS证书验证

节点重命名

使用正则表达式对节点进行重命名,格式为:正则表达式@替换内容

例如:

  • 去除国旗:[\uD83C][\uDDE6-\uDDFF][\uD83C][\uDDE6-\uDDFF] @
  • 添加前缀:(.*)@[NA] $1(在每个节点前添加"[NA] “前缀)
  • 使用计数器:.*@节点$count(01)(将所有节点重命名为"节点01”、“节点02"等)

2. 使用JS脚本进行高级操作

Sub-Store支持使用JavaScript脚本对节点进行更复杂的操作:

  1. 在订阅编辑页面,点击"脚本操作”
  2. 选择"本地脚本"或"远程脚本"
  3. 填写脚本内容或URL
    • 节点重命名脚本:https://raw.githubusercontent.com/Keywos/rule/refs/heads/main/rename.js 我只用这个
    • 节点测活脚本:https://raw.githubusercontent.com/xream/scripts/main/surge/modules/is-node-alive/index.js
    • 解锁检测脚本:https://raw.githubusercontent.com/Keywos/rule/main/script/notion.js
  4. 参数设置
    1. 对于 dlercloud blkey ; iplc+gpt+NF+IPLC+IEPL+[Air]+[Std]+[Pro] name ; dler |
    2. 对应 TAG blkey ; 1x+2x+3x+5x+10x name ; TAG |

导出订阅

编辑完成后,您可以将订阅导出为各种格式:

  1. 点击订阅右侧的"复制"按钮
  2. 选择目标平台(Surge、QX、Clash等)
  3. 复制生成的订阅链接

生成的订阅链接格式为:

1
https://sub.您的域名.com/download/[订阅名称]?target=[平台]

但是这部到出来的规则是没有分流规则的

使用文件管理创建规则

Sub-Store支持通过文件管理功能创建完整的代理规则配置:

1. Surge规则文件

  1. 点击左侧的"文件管理"
  2. 点击"+“按钮创建新文件
  3. 名称填写为:surge-config.conf
  4. 内容示例:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[General]
loglevel = notify
bypass-system = true
dns-server = system, 223.5.5.5, 119.29.29.29
skip-proxy = 127.0.0.1, 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, localhost, *.local

[Proxy Group]
Proxy = select, policy-path=https://sub.您的域名.com/download/MySubscription?target=Surge

[Rule]
RULE-SET,https://raw.githubusercontent.com/DivineEngine/Profiles/master/Surge/Ruleset/Global.list,Proxy
FINAL,DIRECT

surge 配置文件里面会包含节点地址,这些就不展示了

2. Mihomo (Clash Meta) 规则文件

  1. 创建新文件,名称为:mihomo-config.yaml
  2. 内容示例:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
port: 7890
socks-port: 7891
allow-lan: true
mode: rule
log-level: info

proxies: {}

proxy-providers:
  MySubscription:
    type: http
    url: https://sub.您的域名.com/download/MySubscription?target=ClashMeta
    interval: 3600
    path: ./proxies/myprovider.yaml
    health-check:
      enable: true
      interval: 300
      url: http://www.gstatic.com/generate_204

proxy-groups:
  - name: 🚀 节点选择
    type: select
    proxies:
      - ♻️ 自动选择
      - DIRECT
    use:
      - MySubscription

  - name: ♻️ 自动选择
    type: url-test
    use:
      - MySubscription
    url: http://www.gstatic.com/generate_204
    interval: 300

rules:
  - DOMAIN-SUFFIX,google.com,🚀 节点选择
  - DOMAIN-KEYWORD,google,🚀 节点选择
  - MATCH,DIRECT

这里可以 Override(JavaScript/YAML) is supported

这边可以自己维护一个适合自己的 js 文件,比如我用的就是我自己的 https://raw.githubusercontent.com/geekhuashan/Substore-rules/refs/heads/main/Mihomo/override.js

3. Sing-box 规则文件

  1. 创建新文件,名称为:sing-box-config.json
  2. 内容示例:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
{
  "dns": {
    "servers": [
      {
        "tag": "dns_proxy",
        "address": "https://1.1.1.1/dns-query",
        "address_resolver": "dns_resolver",
        "strategy": "ipv4_only",
        "detour": "proxy"
      },
      {
        "tag": "dns_direct",
        "address": "https://223.5.5.5/dns-query",
        "address_resolver": "dns_resolver",
        "strategy": "ipv4_only",
        "detour": "direct"
      },
      {
        "tag": "dns_resolver",
        "address": "223.5.5.5",
        "strategy": "ipv4_only",
        "detour": "direct"
      }
    ],
    "rules": [
      {
        "domain": ["geosite:google"],
        "server": "dns_proxy"
      }
    ]
  },
  "inbounds": [
    {
      "type": "mixed",
      "tag": "mixed-in",
      "listen": "::",
      "listen_port": 7890
    }
  ],
  "outbounds": [
    {
      "type": "selector",
      "tag": "proxy",
      "outbounds": ["auto", "all"]
    },
    {
      "type": "urltest",
      "tag": "auto",
      "outbounds": ["all"],
      "url": "https://www.gstatic.com/generate_204",
      "interval": "1m"
    },
    {
      "type": "remote",
      "tag": "all",
      "path": "https://sub.您的域名.com/download/MySubscription?target=SingBox",
      "cache_file": "./cache/remote.json",
      "download_detour": "direct"
    },
    {
      "type": "direct",
      "tag": "direct"
    },
    {
      "type": "block",
      "tag": "block"
    },
    {
      "type": "dns",
      "tag": "dns-out"
    }
  ],
  "route": {
    "rules": [
      {
        "domain": ["geosite:google"],
        "outbound": "proxy"
      },
      {
        "domain_suffix": [".cn"],
        "outbound": "direct"
      }
    ]
  }
}

sinbox 需要两个文件,一个js 用来处理节点的信息,一个json 文件,用来定义自己的分流规则,这些我也是自定义的,可以网上找找修改成自己想要的,不会的话,用cursor 这种很容易 vibe coding 修改下,我就是这么干的

使用示例:Sub-Store与Mihomo Party集成

如果您使用Mihomo Party客户端,可以按照以下步骤集成Sub-Store:

  1. 在Mihomo Party中,进入"订阅管理” > “Sub-Store”
  2. 点击"添加"按钮
  3. 输入您的Sub-Store后端地址:https://sub.您的域名.com/sEcUrEpaThExaMpLe98765
  4. 在下拉菜单中选择您创建的订阅
  5. 点击"保存"

现在,您可以直接在Mihomo Party中使用Sub-Store管理的订阅了。

高级技巧

1. 使用GitHub同步配置

Sub-Store支持通过GitHub Gist同步您的配置:

  1. GitHub上创建一个Personal Access Token
  2. 在Sub-Store的设置 > 同步中填入Token
  3. 点击"上传"即可创建备份
  4. 在其他设备上,填入相同Token并点击"下载"即可恢复配置

2. 定时自动同步订阅

在某些代理工具中,可以设置定时任务自动同步您的订阅:

  • Surge: 添加定时任务模块
  • Quantumult X: 添加定时任务
  • Loon: 配置定时脚本

常见问题解决

1. 网页无法访问

  • 检查Caddy配置是否正确
  • 确认端口80和443是否开放
  • 验证域名DNS记录是否正确指向您的服务器

2. 节点不生效

  • 检查订阅URL是否正确
  • 确认代理工具是否正确导入了订阅
  • 验证节点信息是否完整

3. 自动同步失败

  • 检查GitHub Token权限是否正确
  • 确认是否有网络连接问题
  • 验证Sub-Store服务是否正常运行

通过本指南,您应该能够充分利用Sub-Store的强大功能,管理您的代理节点和订阅。如需更多帮助,可以访问Sub-Store的GitHub仓库获取更多信息。