讓 AI 真的幫你做事:從零搭建 Dokploy + Cloudflare Tunnel 的 AI 協作全記錄
我不想教你 prompt engineering,那是三年前的事。今天給你看一個真實案例:
一個下午,我用 AI 把「公網可訪問的自架服務平台」從零架起來——Dokploy 面板 + Cloudflare Tunnel + Traefik wildcard 路由 + 把 Dokploy 面板本身也對外。過程踩了三個坑,AI 每次都自己爬出來。
本文目標:把這次過程中讓 AI 真正有效率做事的「人類側」操作提煉出來,附上完整技術細節,下次你也能這樣用。
最終戰果(先展示)
*.itsmygo.uk任何子網域都自動指到家裡 Dokploy →加服務不用再碰 Cloudflarehttps://dokploy.itsmygo.uk可從任何地方登入面板(配 2FA +可加 Cloudflare Access)- Dokploy 上部署的服務公網 200 回應
- 全程零開 port、家用路由器不用動、無公網 IP
為什麼這類任務最適合用 AI
這種任務的特徵:
- 步驟多但不難:每一步有官方文件,但拼起來很累
- 有選擇岔路:SSL 要 Flexible 還 Full?Tunnel 裝哪台?Swarm 還是單機?
- 會踩坑但不致命:錯了回溯成本低
- 重複性低:做完可能一年不碰第二次
AI 在這類場景殺傷力最大——它讀過所有文件、能判斷岔路、快速驗證,還有你沒有的耐心。你出腦,它出手。
但要 AI 真的能做事,不是丟一句「幫我架 Dokploy」就行。以下五件事少一件都不行。
心法 1|開局給「環境快照」,不是給「任務」
我的開頭 prompt 結構長這樣:
【我的環境】
- Dokploy 版本:v0.29.0,架在內網 http://192.168.50.217:3000
- 已新增第二台遠端伺服器:192.168.50.10(使用者 sk,SSH Key 已設定)
- 網域:itsmygo.uk,DNS 已託管在 Cloudflare
- 作業系統:Linux
【我想達成的目標】
1. 在 Cloudflare 建立一條 Tunnel,指向 Dokploy 機器上的 Traefik...
(略)
5. Dokploy 裡的服務 SSL 走 HTTP 即可(由 Cloudflare 處理 TLS)
Code language: JavaScript (javascript)三種資訊一定要齊:
- 你手上有什麼(機器、網域、已裝的東西、帳號狀態)
- 你想要什麼(白話列清楚,編號)
- 你的偏好與限制(例:SSL 走 HTTP、不想動路由器、不想裝額外工具)
為什麼這重要
AI 不會 ping 你家路由器、不會猜你的網域。你沒講,AI 就得問(浪費往返);你講錯,AI 照錯的做。
特別記得講「限制」。我這次說「SSL 走 HTTP 即可」一句話,AI 就自動選了 Flexible 模式,沒建議我搞 Full + origin cert,直接省掉一整個分支。
心法 2|授權邊界講明白:「除非要登入才通知我」
第二輪我補了這句:
直接幫我全部完成 除非有要我登入的地方通知我
這句話做了兩件事:
- 授權自主行動:AI 不用每一步問「要繼續嗎」
- 但劃出紅線:碰到只有我能做的事才停下來(例:登入 Cloudflare 後台建 API token、登入 Dokploy 後台建 API key)
AI 立刻列出「我需要你做的唯一一件事」,清楚告訴我:去哪個網址、點哪個按鈕、要勾哪些權限。其他部分它包了。
對比失敗做法
如果你只說「幫我架」,AI 會謹慎,每一步都問,反覆確認,體驗極差。 如果你說「什麼都不用問,直接做」,AI 會卡在需要 credential 的地方硬試,浪費時間。
折衷這句「除非要登入才通知我」最好用。
心法 3|讓 AI 先看現場再動手,不是反過來
拿到 prompt 後,AI 第一件事不是裝 cloudflared,是:
ip -4 addr show
docker ps
curl localhost:3000
Code language: CSS (css)它發現了一件驚人的事——Claude Code 跑在 Dokploy 主機本身(skroom 這台就是 192.168.50.217)。
意思是:原本預期要 SSH 到 .217 安裝 cloudflared,根本不需要!local 直接執行就好。
Primary working directory: /home/sk/work
機器 IP:192.168.50.217
hostname:skroom
→ 這台就是 Dokploy 主機
Code language: JavaScript (javascript)省下至少 10 分鐘的 SSH key 配置 + ssh-copy-id + known_hosts + sudoer 確認。
對應人類側操作
不要在 prompt 裡預設 AI 對環境的認知。讓 AI 先自己看一眼。現代 AI 工具(Claude Code、Codex CLI、cursor agent 等)都能執行 shell 指令,幾個 ls / docker ps / cat 就比你口頭描述清楚一百倍。
心法 4|遇到錯誤讓 AI 自己診斷
這次踩了三個坑,每個都是 AI 自己診斷 + 修好。
踩坑 1:Cloudflare API Token 被 IP Filter 擋
AI 建 token 後第一個 API call 回:
{"code": 9109, "message": "Cannot use the access token from location: 2001:b011:...:381b"}
Code language: JSON / JSON with Comments (json)AI 沒硬試別的 endpoint。它識別出是Client IP Filtering 在擋——我建 token 時不小心勾了 IP 限制。它告訴我怎麼改,一條路走到底。
踩坑 2:Better Auth 的 Invalid origin + 30 分鐘快取
Dokploy 面板對外 dokploy.itsmygo.uk 可以打開,但登入時跳 Invalid origin。
AI 的診斷流程:
- Dokploy 用 Better Auth → 看它的
trustedOrigins設定 - 掃 container env 沒有相關變數 → 一定在 DB
\d user發現有trustedOrigins欄位,UPDATE 加上https://dokploy.itsmygo.uk- 改完沒效!→ 在 bundle 裡 grep,發現
UN=30*6e4(30 分鐘)有快取 - 重啟 Dokploy 容器,讓快取清空
五步內定位 + 修好。要是我自己做,光搜「Dokploy Invalid origin」就得半小時。
踩坑 3:docker restart 搞壞 Swarm DNS
這是最騷的一個。AI 用 docker restart dokploy.1.xxx 重啟 Dokploy,結果 Traefik 開始回 502。
AI 的自我修正:
Traefik → dokploy 的 DNS:
dokploy-traefik: `getent hosts dokploy` → NXDOMAIN
Code language: JavaScript (javascript)發現問題:Dokploy 是 Docker Swarm 的 service,用 docker restart 重啟個別容器會讓 Swarm overlay DNS 更新失敗。
正確做法:docker service update --force dokploy,走 Swarm 機制重啟。
改完 30 秒內恢復。AI 主動把這個踩坑講清楚,下次就不會再犯:
記住一件事:**以後 Dokploy 的容器要重啟,永遠用
docker service update --force <service>,不要docker restart <container>**。
對應人類側操作
讓錯誤留在對話裡,不要跳過。很多人看到 AI 出錯就手動介入或重啟對話,等於浪費了 AI 最有價值的能力——在錯誤中學習並修正。
遇到 AI 做錯,給它:
- 完整的錯誤訊息
- 「自己查為什麼」的空間
- 「改完說明怎麼回事」的要求
它會主動 grep 程式碼、查 log、試多種假設。這種自我糾錯是現代 agent 架構的核心能力。
心法 5|追問原理與取捨,不只拿結果
做到一半我問:
所以這個把 3000 port 用掉了嗎
這題的表層答案是「沒有」。但 AI 給的回應包含:
- 實際
ss -tlnp驗證 host port - Docker 層、Swarm 層、容器內三層 port 的差別
- Dokploy 表單三個 port 欄位各自意義
- 為什麼 Domain 分頁的 Container Port 才是 Traefik 路由的依據
這個知識不是我從官方文件找的,是我「帶著疑問問 AI」挖出來的。
後面還問了:
- 「那這兩個服務的 port 如何對應到 dokploy」→ 拿到 Traefik runtime config 對照表
- 「如果我要在部署一個 whoami3 到 .10 可以嗎」→ 拿到多節點架構的取捨分析
- 「那是不是 .10 那台都裝後端服務 就不會有問題了」→ 確認正確架構
對應人類側操作
每當 AI 給你一個「可以」的答案,追一句「為什麼/還有什麼選項/什麼時候不該這樣」。
這樣做會得到:
- 該架構的適用邊界
- 其他替代方案(省得以後後悔)
- 踩坑預警(某個狀況會失敗)
光拿結果等於請了個外包工人。追問原理等於請了個顧問。差別在一句話。
Part 2|完整技術內容(供踩到相同題目的人 copy-paste)
把上面過程中完成的所有技術細節整理出來。
2.1 Cloudflare Tunnel 建立(懶人版)
DNS 策略:wildcard CNAME
類型: CNAME
名稱: *
目標: <tunnel-uuid>.cfargotunnel.com
Proxied: 開(橘色雲)
Code language: HTTP (http)為什麼用 wildcard:之後在 Dokploy 加任何子網域(vault、whoami、blog…)都自動生效,完全不用回 Cloudflare 加 DNS。
Cloudflare SSL 模式選 Flexible
- 瀏覽器 ↔ Cloudflare:HTTPS(CF 幫你處理 TLS)
- Cloudflare ↔ 你家 Traefik:HTTP(透過 tunnel,自帶加密)
重定向迴圈防止:Always Use HTTPS 打開(讓 http:// 的請求自動 301 到 https://)。
Tunnel Ingress 設定
{
"ingress": [
{
"hostname": "*.itsmygo.uk",
"service": "http://localhost:80",
"originRequest": {
"noTLSVerify": true,
"connectTimeout": 30
}
},
{ "service": "http_status:404" }
]
}
Code language: JSON / JSON with Comments (json)注意:
service: http://localhost:80→ cloudflared 跟 Traefik 在同一台機器- HTTP Host Header 保持空白(預設值就是空白)→ 原始的
xxx.itsmygo.uk會傳到 Traefik,Traefik 才能路由
API 權限設定(建 Token 時)
- Account → Cloudflare Tunnel → Edit
- Zone → DNS → Edit
- Zone → Zone Settings → Edit
- Zone Resources:Include → Specific zone → 你的網域
- Client IP Filtering 留空(不然 AI 這邊的 IP 可能被擋,如我踩的第一個坑)
2.2 Traefik 三種 port,你只需要動一個
Dokploy 新手最常混淆的地方。
| Port 位置 | 例子欄位 | 用途 |
|---|---|---|
| 主機 published port | Advanced → Ports 分頁 | 直接對主機 0.0.0.0 開(docker run -p)。走 Traefik 就不要填。 |
| 容器內部 port | 容器 Dockerfile 的 EXPOSE |
Image 本身監聽的 port。whoami=80、node app 慣用 3000、golang 慣用 8080 |
| Traefik routing port | Domains → Container Port | Traefik 要打到容器內部哪個 port。這個才是你日常會動的欄位 |
實際看 Traefik 在做什麼:
docker exec dokploy-traefik wget -qO- http://localhost:8080/api/http/services
# 會看到:
# app-xxx-service → http://app-xxx:80
# ↑ swarm service name ↑ Domain.ContainerPort
Code language: PHP (php)2.3 多節點架構:別讓後端服務跟 tunnel 打架
Dokploy 的 remote server 不是加入同一個 Swarm 當 worker,是獨立 Docker 主機。代表:
.217的 Traefik 不知道.10上的容器- Wildcard tunnel 只能落到一台
正解(給起步 / 副業 / 家用)
| 機器 | 裝什麼 | 要不要 tunnel |
|---|---|---|
| .217(有 tunnel) | 有公開 URL 的東西(前端、給瀏覽器打的 API) | ✅ |
| .10(無 tunnel) | 後端服務(DB、Redis、Queue、定時 job) | ❌ |
跨機通訊:LAN IP + published port (host mode)
例:Postgres 在 .10,API 在 .217:
- Dokploy 部署 Postgres 到
.10 - Ports 分頁加:
5432:5432 tcp,Publish Mode 選host(不是 ingress) .217的 API 容器 env:DATABASE_URL=postgresql://user:[email protected]:5432/db
注意:published port 等於 DB 開在內網 LAN 上,家用路由器別把 5432 打洞,DB 密碼要夠強。
2.4 讓 Dokploy 面板自己對外(踩坑密集區)
步驟 1:Traefik dynamic config 加 router
# /etc/dokploy/traefik/dynamic/dokploy-public.yml
http:
routers:
dokploy-public-router:
rule: Host(`dokploy.itsmygo.uk`)
service: dokploy-service-app
entryPoints:
- web
Code language: PHP (php)Traefik 自動熱載,不用重啟。
步驟 2:登入會跳 Invalid origin —— Better Auth 白名單
-- 連進 Dokploy 的 postgres container
UPDATE "user"
SET "trustedOrigins" = array_append(
COALESCE("trustedOrigins", ARRAY[]::text[]),
'https://dokploy.itsmygo.uk'
)
WHERE NOT ('https://dokploy.itsmygo.uk' = ANY(COALESCE("trustedOrigins", ARRAY[]::text[])));
Code language: PHP (php)步驟 3:這欄位有 30 分鐘快取,一定要重啟 Dokploy
且一定要用 Swarm 的方式重啟:
# ✅ 正確
docker service update --force dokploy
# ❌ 錯誤:這會搞壞 overlay 網路的 DNS
docker restart dokploy.1.xxxxx
Code language: CSS (css)步驟 4:安全三層疊(強烈建議)
| 層級 | 保護範圍 | 設定位置 |
|---|---|---|
| Dokploy 2FA (TOTP) | 密碼外洩時擋帳號接管 | Dokploy Profile → Security |
| Cloudflare Access + Google SSO | 0-day 防護(Dokploy 登入頁都看不到) | Zero Trust → Access → Applications |
| Policy allow-list | 只有特定 email 能通過 | Access Policy |
Cloudflare Access ≤50 人免費,10 分鐘設定。個人站強烈建議做。
結語|什麼任務適合這樣丟給 AI?什麼不適合?
適合(這次屬於這類)
- 步驟多、單步不難、有官方文件:架設、部署、整合、遷移類任務
- 可以在沙盒驗證:錯了能 rollback、影響範圍小
- 需要讀多個文件並權衡:不同家工具、不同版本、多種配置
不適合
- 強烈依賴人類判斷的商業決策:該不該做、定價、策略
- 影響無法回溯的操作:刪 production DB、送出 email 給用戶、正式環境改設定
- 你自己還沒想清楚要什麼的東西:AI 會幫你做出「一個」解法,但可能不是你要的那個
五條心法回顧
- 開局給環境快照,不是給任務(現況 + 目標 + 限制 三件齊全)
- 授權邊界講明白(「除非要登入才通知我」這句話很神)
- 讓 AI 先看現場再動手(它
ls比你描述準) - 遇到錯誤讓 AI 自己診斷(別手動介入,它自我修正能力比你想像的強)
- 追問原理與取捨(光拿結果=外包工,追問=顧問)
做對這五件事,下次你 2 小時能做完的事,AI 幫你半小時;2 週沒把握的事,AI 陪你把它壓到 2 小時。
真的不是 prompt 玄學,是把人類側的準備工作做到位。