前言

Caddy 本身是一個非常好用的工具, 最常見的用途應該是用來做 Reverse Proxy 使服務端口不暴露在公網之下並且可以透過內建的工具進行 Let’s Encrypt SSL 證書申請, 然而 Caddy 本身的安裝涉及到 Go 語言的安裝和 xcaddy 安裝並編譯自己需要的 caddy 程式, 因此單獨寫一篇教學使步驟更加詳細完整。

而 Sub-Store 則是一個管理節點訂閱非常方便的工具, 但是其部署架設相對比較複雜一點, 網路上常見的教學都是使用 Nginx 進行反代, 其設定檔較 Caddy 複雜很多時候新手並不容易上手, 且其部署過程中的參數較多透過 docker run 執行時也較為麻煩, 容易漏掉參數, 若我們可以透過 docker compose 寫好每次啟動所需要用到的參數, 則可以更加方便的使用這套工具。

Sub-Store 主要維護者之一 @xream 的交流群: 折騰啥

📖

sub-store-org/Sub-Store

Advanced Subscription Manager for QX, Loon, Surge, Stash, Egern and Shadowrocket!

⭐ 9810 Stars 🍴 1176 Forks Language: JavaScript

Golang 安裝

要安裝 go-lang, 首先要確認目前最新的版本和自己電腦/伺服器的系統類型及處理器類型(X86、Arm等), 以我要部署的環境(Raspberry Pi 4b), 他跑的是 PiOS, 一個基於 Debian 的 Linux 系統, 而他的處理器則是 Armv8, 所以我需要找到 Go 的 Linux Arm64 版本, 我們可以在 Go 的官方下載頁找到最新的發行版檔案, 以我寫這篇的時間, 目前最新的版本是 Go 1.22.0, 因此我們要把這個壓縮包下載到自己的伺服器上, 下載的連結可以在對應版本上右鍵->複製連結找到, 或是直接替換成你需要版本的檔名:

//格式: 
wget Go的安裝包URL

wget https://go.dev/dl/(包的名稱)
//以我的為例:
wget https://go.dev/dl/go1.22.0.linux-arm64.tar.gz

之後將下載下來的檔案解壓縮在安裝目錄下(官方建議是 /usr/local):

sudo tar -C /usr/local -xzf go1.22.0.linux-arm64.tar.gz

(檔案名稱根據安裝版本自行替換)
之後在 /etc/profile 檔案最下方新增這行並重啟機器( sudo reboot ):

export PATH=$PATH:/usr/local/go/bin

之後可以輸入這段指令檢查是否正確安裝:

go version

應該會有類似的輸出, 務必檢查是否安裝到正確的版本以及是否對應正確的系統與處理器類型:

go version go1.22.0 linux/arm64

What is Caddy?

Caddy伺服器(或稱Caddy Web)是一個開源的, 使用 Golang 編寫, 支援 HTTP/2 的 Web 伺服器端。它使用 Golang 標準庫提供 HTTP 功能。 (來自維基百科)

我們將會需要使用 Caddy 作為反代伺服器 (Reverse-Proxy), 並且會使用 xcaddy 安裝 cloudflare 插件

xcaddy 安裝

📖

caddyserver/xcaddy

Build Caddy with plugins

⭐ 1463 Stars 🍴 145 Forks Language: Go

xcaddy 是一套讓使用者更方便編譯包含插件 Caddy 的程式, 我們需要他來編譯包含 CloudFlare 網域證書申請的插件, 安裝方式如下:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key' sudo gpg --dearmor -o /usr/share/keyrings/caddy-xcaddy-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/debian.deb.txt' sudo tee /etc/apt/sources.list.d/caddy-xcaddy.list
sudo apt update
sudo apt install xcaddy

編譯 Caddy

接下來編譯你要的 Caddy 程式(以下是以 Caddy 並包含 CloudFlare 自動申請 SSL 插件):

📖

caddy-dns/cloudflare

Caddy module: dns.providers.cloudflare

⭐ 938 Stars 🍴 114 Forks Language: Go
xcaddy build latest --with github.com/caddy-dns/cloudflare

上面的指令會編譯最新的 Caddy 發行版並包含 CloudFlare 插件, 他會在你終端機當前在的目錄編譯出包含插件的 Caddy, 而 Caddy 放在這邊是無法使用的, 我們需要把他放到正確的目錄下:

sudo mv caddy /usr/bin

最後檢查是否安裝成功:

//輸入
caddy version
//根據當前最新版本會有不同輸出
v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=

使 Caddy 作為 Service 運行

可以參考官方文檔:

sudo groupadd --system caddy
sudo useradd --system \
--gid caddy \
--create-home \
--home-dir /var/lib/caddy \
--shell /usr/sbin/nologin \
--comment "Caddy web server" \
caddy

創建 Caddy 設定檔

sudo nano /etc/caddy/Caddyfile

Caddy 設定檔格式 (以 sub-store 為例):

你想要的網址(例如sub-store.xxx.com)(要是你擁有的網域) {
reverse_proxy http://127.0.0.1:3001
tls 自動申請SSL證書用的信箱 {
dns cloudflare CloudFlare的API Token
}
}

如果你有多個服務都需要反代:

sub-store.xxx.com{
reverse_proxy http://127.0.0.1:3001
tls [email protected] {
dns cloudflare CloudFlare-API-Token-of-xxx.com
}
}
another-service.yyy.com{
reverse_proxy localhost:the-port
tls [email protected] {
dns cloudflare CloudFlare-API-Token-of-yyy.com
}
}

之後存儲並退出(ctrl+s 儲存, ctrl+x 退出)

(申請 CloudFlare API Token 的方法可以看這裡)

之後根據 Caddy 官方文檔執行系統服務
第一次執行:

sudo systemctl daemon-reload
sudo systemctl enable --now caddy

檢查狀態:

systemctl status caddy

開始、停止、重新載入設定檔:

sudo systemctl start caddy
sudo systemctl stop caddy
sudo systemctl reload caddy

Caddy 的安裝就到這邊。

Sub-Store 的安裝

首先要安裝 Docker, 安裝方法基本上只要照著 Docker 官網的步驟, 非常詳細, 左邊可以找到你的系統, 按照系統版本進行安裝就好。

之後創建一個 compose.yml:

nano compose.yml

然後裡面填入以下內容並儲存:

version: "3.8"
services:
sub-store:
image: xream/sub-store:latest
container_name: sub-store
restart: always
volumes:
- /root/sub-store-data:/opt/app/data
environment:
- SUB_STORE_FRONTEND_BACKEND_PATH=/20位英數大小寫混和隨機字串作為後端加密
ports:
- 127.0.0.1:3001:3001
stdin_open: true
tty: true

其中 /root/sub-store-data 可以替換成你想儲存 sub-store 數據的地方, 例如我自己放在 ./docker-data/sub-store-data 內 (./ 代表你當前所在的目錄, 由於我不是用 root 登入, 因此他就會在 /home/myusername 這個路徑內)。

而記得在防火牆開啟 80 與 443 端口:

sudo ufw allow 80 comment "Http"
sudo ufw allow 443 comment "Https"
sudo ufw reload

之後執行命令如下:

//拉取映像(images)
docker compose pull

//停止正在運作的容器(container)(僅限透過docker compose執行的, 所以你原本有跑的要手動關閉)(透過 docker stop 和 docker rm)
docker compose down

//啟動
docker compose up -d

//刪除已經過時的容器和映像
docker system prune -f

之後若是需要更新 Sub-Store, 則只需要按步驟執行以下指令就可以更新:

docker compose pull
docker compose down
docker compose up -d
docker system prune -f

最後你開啟 Sub-Store 的網址應該是:

https://你Sub-Store的網址?api=https://你Sub-Store的網址/20位英數大小寫加密字串

或者你也可以開啟 https://你Sub-Store的網址 後到 設定->後端設定->已保存的後端列表 並且在裡面手動添加 https://你Sub-Store的網址/20位英數大小寫加密字串

到這邊為止你應該就能成功透過網址存取 Sub-Store 服務了。