返回上一頁

Caddy 反向代理完整教程 — Debian/Ubuntu 從安裝、HTTPS 證書到多站點與內網反代

Caddy 反向代理完整教程 — Debian/Ubuntu 從安裝、HTTPS 證書到多站點與內網反代

Caddy 是一套用 Go 編寫、預設自動申請並續期 HTTPS 證書的 Web 伺服器與反向代理工具。本教程面向零基礎新手,從準備域名、放行埠、安裝 Caddy,一路講到反向代理、自動申請證書、多站點配置,以及反代區域網(內網)中其他服務的寫法,照做即可搭好。


目錄

  1. 為什麼選 Caddy
  2. 一、準備工作
  3. 二、配置域名解析(DNS)
  4. 三、放行防火牆埠
  5. 四、安裝 Caddy
  6. 五、寫配置檔案(Caddyfile)
  7. 六、啟動並申請證書
  8. 七、驗證結果
  9. 八、日後修改配置的正確流程
  10. 九、反向代理多個網站
  11. 十、反代區域網中的其他裝置
  12. 十一、常用進階配置
  13. 十二、完整示例
  14. 十三、常見問題排查
  15. 十四、備份與維護
  16. 結語

為什麼選 Caddy

在 2 核 2GB 的 VPS 上,一般推薦 Caddy,除非你有特定需求必須用 Nginx。

  • 記憶體佔用:Nginx 大約 5-15MB,Caddy 大約 20-40MB。對 2GB 記憶體來說兩者都微不足道,差距可忽略。
  • 自動 HTTPS:Caddy 內建 Let’s Encrypt 自動申請與續期證書,零配置。Nginx 需要搭配 certbot 並手動處理續期,運維成本高。
  • 配置簡潔:Caddy 兩三行就能反代,Nginx 需要寫 server/location 塊並理解 proxy_set_header 等細節。
  • HTTP/3、自動壓縮:Caddy 預設開啟;Nginx 需要額外編譯或配置。

什麼時候選 Nginx:需要極高併發或靜態資源效能、已有成熟的 Nginx 配置或團隊熟悉 Nginx、需要 Caddy 不擅長的高階模組(如複雜 WAF、四層代理調優)。

結論:個人專案、小站、圖省事選 Caddy;追求極致效能或已有 Nginx 生態選 Nginx。2GB 記憶體不是決定性因素。


一、準備工作

假設你已經買好 VPS、有一個域名、會用 SSH 登入。

1. 確認系統版本(Debian 11/12 或 Ubuntu 20.04/22.04/24.04 均可):

cat /etc/os-release

2. 拿到 VPS 公網 IP:

curl -4 ifconfig.me

記下輸出,例如 123.45.67.89。

3. 登入 VPS(在你自己的電腦終端執行):

ssh root@123.45.67.89

如果不是 root 使用者,命令前都要加 sudo。本教程假設你用 root,或者手動給每條命令加 sudo。


二、配置域名解析(DNS)

去你買域名的網站(阿里雲、騰訊雲、Cloudflare、Namesilo 等),找到 DNS 解析 / DNS Records,新增兩條記錄:

型別 主機記錄 記錄值 TTL
A @ 123.45.67.89 預設
A www 123.45.67.89 預設

@ 代表根域名 example.com,www 代表 www.example.com。把 123.45.67.89 換成你自己的 IP,example.com 換成你自己的域名。

驗證解析是否生效(在你本地電腦執行,需要等 1-10 分鐘):

ping example.com

能 ping 到你的 VPS IP 就說明生效了。這一步必須成功,否則後面證書申請一定失敗。


三、放行防火牆埠

1. 如果你用的是雲服務商的「安全組」(阿里雲、騰訊雲、AWS 等):在網頁控制檯裡,給這臺伺服器放行入方向埠 22、80、443。

2. 伺服器內部的防火牆(ufw):

apt update
apt install -y ufw
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

提示 Command may disrupt existing ssh connections. Proceed? 時輸入 y 回車。

檢視狀態:

ufw status

應該看到 22、80、443 都是 ALLOW。

80 和 443 必須放行,Caddy 申請證書和對外服務都靠它們。


四、安裝 Caddy

Debian/Ubuntu 官方推薦用 Cloudsmith 倉庫安裝,逐條執行:

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

驗證安裝成功:

caddy version

能輸出版本號即成功。安裝過程會自動建立一個 caddy 系統使用者,並註冊開機自啟服務。


五、寫配置檔案(Caddyfile)

Caddy 的主配置檔名固定是 Caddyfile,路徑 /etc/caddy/Caddyfile。

先備份原檔案:

cp /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak

場景 A:反代到你本機執行的程式(如 Node、Python、Docker 應用)

假設你的程式監聽 localhost:3000。用 nano 編輯:

nano /etc/caddy/Caddyfile

全選刪除裡面原來的內容(nano 裡 Ctrl+K 可刪行),貼上以下內容:

example.com {
    reverse_proxy localhost:3000
}

把 example.com 換成你的域名。www 也想要的話寫成:

example.com, www.example.com {
    reverse_proxy localhost:3000
}

場景 B:部署純靜態網站(HTML/CSS/JS)

example.com {
    root * /var/www/html
    file_server
}

場景 C:只反代、不想要 HTTPS(不推薦,僅除錯用)

http://example.com {
    reverse_proxy localhost:3000
}

注意:Caddy 只要看到裸域名(不帶 http://)就會自動申請並啟用 HTTPS,無需你做任何事。這是它最大的優點。

儲存退出 nano:按 Ctrl+O 回車,再按 Ctrl+X。

語法檢查(強烈建議,能提前發現寫錯):

caddy validate --config /etc/caddy/Caddyfile

看到 Valid configuration 就對了。


六、啟動並申請證書

過載配置:

systemctl reload caddy

檢視執行狀態:

systemctl status caddy

看到綠色的 active (running) 即正常(按 q 退出)。

即時看日誌(證書申請過程都在這裡):

journalctl -u caddy --no-pager | tail -n 40

正常會看到類似 certificate obtained successfully 的輸出。

Caddy 會自動向 Let’s Encrypt 申請證書,並自動配置每 60 天續期一次,你什麼都不用做。


七、驗證結果

在你本地電腦瀏覽器開啟:

https://example.com
  • 位址列出現小鎖圖示,即證書成功。
  • 訪問 http://example.com 會自動跳轉到 https://。

命令列驗證:

curl -I https://example.com

返回 HTTP/2 200 或 HTTP/2 302 即成功。

檢視證書資訊:

curl -vI https://example.com 2>&1 | grep -i "subject\|issuer\|expire"

八、日後修改配置的正確流程

每次改完 /etc/caddy/Caddyfile 後:

caddy validate --config /etc/caddy/Caddyfile   # 1. 檢查語法
systemctl reload caddy                          # 2. 熱過載,不中斷服務
systemctl status caddy                          # 3. 確認沒報錯

不要用 systemctl restart(會短暫中斷服務),用 reload。


九、反向代理多個網站

方式 1:多個域名 / 子域名(最常用)

每個站點寫一個塊,Caddy 會為每個域名分別自動申請證書:

a.example.com {
    reverse_proxy localhost:3000
}

b.example.com {
    reverse_proxy localhost:3001
}

shop.example.com {
    reverse_proxy localhost:8080
}

前提:a.example.com、b.example.com、shop.example.com 都要在 DNS 里加 A 記錄指向你 VPS 的 IP。域名之間互不影響,各自獨立證書。

方式 2:主域名 + 多個子域名

example.com, www.example.com {
    reverse_proxy localhost:3000
}

api.example.com {
    reverse_proxy localhost:4000
}

admin.example.com {
    reverse_proxy localhost:5000
}

同一行用逗號分隔的多個域名,會共用一張證書(SAN 證書)。

方式 3:同一個域名,按路徑區分(一個證書,多後端)

適合沒有多餘子域名的場景:

example.com {
    handle /app/* {
        reverse_proxy localhost:3000
    }

    handle /api/* {
        reverse_proxy localhost:4000
    }

    handle {
        reverse_proxy localhost:8080
    }
}

說明:

  • handle 按路徑匹配,從上往下第一個匹配的生效。
  • 最後的 handle { }(無路徑)是兜底,處理其他所有請求。
  • 路徑字首會讓後端收到的路徑也帶 /app/。若後端不帶字首,用 handle_path:
example.com {
    handle_path /app/* {
        reverse_proxy localhost:3000
    }
}

handle_path 會自動去掉 /app 字首再轉發。


十、反代區域網中的其他裝置

只要你的 VPS 能透過內網訪問那臺裝置,寫法和本機幾乎一樣,把 localhost:埠 換成 內網IP:埠 即可。

1. 基本寫法

假設局域網裡有一臺 NAS/軟路由/內網伺服器,IP 是 192.168.1.50,服務監聽 8080:

nas.example.com {
    reverse_proxy 192.168.1.50:8080
}

前提條件:

  • VPS 與 192.168.1.50 在同一內網(或透過 VPN 互通,見下文)。
  • 那臺裝置的服務若監聽 127.0.0.1:8080,需改成監聽 0.0.0.0:8080,否則外部連不進去。
  • 那臺裝置的防火牆要放行 8080(例如 sudo ufw allow from 192.168.1.0/24 to any port 8080)。

2. 先測試 VPS 能否連通後端

改配置前,在 VPS 上先驗證:

curl -v http://192.168.1.50:8080

能返回內容(哪怕是 404 頁面)就說明網路通。若報 Connection refused 或 timeout,先解決網路、監聽、防火牆問題,再改 Caddy。

3. 後端是 HTTPS 的情況

如果內網服務本身走 HTTPS(比如自帶證書、自簽名證書):

nas.example.com {
    reverse_proxy https://192.168.1.50:5001
}

若後端是自簽名證書,Caddy 驗證會失敗,需跳過校驗:

nas.example.com {
    reverse_proxy https://192.168.1.50:5001 {
        transport http {
            tls_insecure_skip_verify
        }
    }
}

tls_insecure_skip_verify 僅用於內網可信裝置,不要用於公網後端。

4. 後端需要保留原始 Host

大部分場景不需要動。若後端需要保留原始 Host:

nas.example.com {
    reverse_proxy 192.168.1.50:8080 {
        header_up Host {upstream_hostport}
    }
}

5. 跨網路:VPS 和區域網裝置不在同一網段

這是最常見的真實情況(VPS 在公網,服務在你家內網)。Caddy 本身不會打洞,你需要先建立隧道,再讓 Caddy 反代隧道出口。常用方案:

  • WireGuard / Tailscale:把 VPS 和家裡裝置組進同一虛擬內網。組好後,家裡裝置的虛擬 IP(Tailscale 通常是 100.x.x.x)就直接可用:
home.example.com {
    reverse_proxy 100.64.1.23:8080
}
  • frp / rathole:家裡裝置做客戶端,把埠對映到 VPS 的 127.0.0.1:某埠,然後:
home.example.com {
    reverse_proxy 127.0.0.1:18080
}

只要隧道打通,對 Caddy 來說後端就是「本機或內網的一個埠」,配置完全一樣。

注意:Caddy 配置裡不要暴露未知公網地址做反代,否則可能變成開放代理、被濫用。只反代你明確擁有的後端。


十一、常用進階配置

1. 傳遞真實客戶端 IP

Caddy 預設自動加 X-Forwarded-For、X-Forwarded-Proto、X-Forwarded-Host,後端一般無需額外配置即可拿到真實 IP。若後端要 X-Real-IP:

app.example.com {
    reverse_proxy localhost:3000 {
        header_up X-Real-IP {remote_host}
    }
}

{remote_host} 是發起請求的客戶端 IP。若前面還套了一層 CDN/Cloudflare,需配合 trusted_proxies 才能取到真實 IP。

2. 子域名太多,用萬用字元證書

有幾十個子域名逐個申請證書很麻煩,可在 DNS 服務商(Cloudflare、阿里雲等)用 DNS 驗證申請 *.example.com。以 Cloudflare 為例:

*.example.com {
    tls {
        dns cloudflare {env.CLOUDFLARE_API_TOKEN}
    }
    @app host app.example.com
    handle @app {
        reverse_proxy localhost:3000
    }
}
  • 需要先安裝對應 DNS 外掛版 Caddy(官方 apt 包預設不含,需從 Caddy 官網下載帶外掛的版本)。
  • 在 /etc/systemd/system/caddy.service 裡用 Environment=CLOUDFLARE_API_TOKEN=xxx 注入 token,或在 /etc/caddy/caddy.env 裡配置。

新手建議:子域名少於 5 個就別折騰萬用字元,逐個寫塊更簡單。

3. 給後端加超時(後端慢時避免 502)

app.example.com {
    reverse_proxy localhost:3000 {
        transport http {
            dial_timeout 10s
            read_timeout 60s
        }
    }
}

十二、完整示例

以下是一份同時包含 3 個站點與 1 個區域網服務的配置:

example.com, www.example.com {
    reverse_proxy localhost:3000
}

api.example.com {
    reverse_proxy localhost:4000
}

shop.example.com {
    reverse_proxy 192.168.1.88:8080
}

nas.example.com {
    reverse_proxy https://192.168.1.50:5001 {
        transport http {
            tls_insecure_skip_verify
        }
    }
}

十三、常見問題排查

1. 證書申請失敗 / 網站打不開

依次檢查:

  • ping example.com 是否指向你的 VPS IP(DNS 問題佔 90%)。
  • 雲安全組和 ufw 是否都放行了 80、443。
  • 埠有沒有被別的程式佔用:
ss -tlnp | grep -E ':80|:443'

應該只有 caddy 在監聽。

2. 看詳細錯誤日誌

journalctl -u caddy -f

然後瀏覽器重新整理一次網頁,終端裡會即時列印錯誤原因。常見提示:

  • no such host:DNS 沒配好或沒生效。
  • timeout / connection refused:80/443 被防火牆攔。
  • address already in use:80/443 被 nginx/apache 佔了,先 systemctl stop nginx 並 systemctl disable nginx。

3. 免費域名 / 測試時頻繁失敗被 Let’s Encrypt 限流

改用 Let’s Encrypt 測試環境(申請的是假證書,僅用於驗證配置):

{
    acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}
example.com {
    reverse_proxy localhost:3000
}

除錯成功後,把 acme_ca 那幾行刪掉,再 systemctl reload caddy 重新申請正式證書。

4. 過載報錯,配置改壞了

cp /etc/caddy/Caddyfile.bak /etc/caddy/Caddyfile
systemctl reload caddy

十四、備份與維護

  • 配置檔案位置:/etc/caddy/Caddyfile
  • 證書和資料位置:/var/lib/caddy/.local/share/caddy/
  • 檢視磁碟、證書狀態等一般無需你干預,Caddy 全自動。

結語

只要 DNS 正確、80/443 放行,你在 Caddyfile 裡寫一行域名加一行 reverse_proxy,儲存後 systemctl reload caddy,證書和 HTTPS 就自動搞定。多站點、內網反代也不過是在這個基礎上多加幾個配置塊,這是所有反代工具裡最省心的方案。