ServBay 與 Docker 協同工作常見問題解答 (FAQ)
在使用 ServBay 進行本機網頁開發時,你可能希望結合 Docker 一起打造容器化環境。本 FAQ 旨在解答 ServBay 與 Docker 在 macOS 上協同運作常遇到的各種疑難,特別包括 Docker 如何正確存取 ServBay 服務,以及利用 ServBay 進行容器端應用的反向代理。
Q1: 為什麼 ServBay 會修改我系統的 hosts
檔案?我能阻止嗎?
ServBay 會在系統的 hosts
檔案中加入條目(例如 mysite.servbay.demo 127.0.0.1
),讓你可以透過自訂本地域名(例如 mysite.servbay.demo
)來存取本地開發站點。這些站點其實都是跑在你的本機 127.0.0.1
上。
但因 Docker 的運作機制,會從 macOS 主機讀取 hosts 檔案,導致 mysite.servbay.demo
解析到 127.0.0.1
時,Docker 其實存取的是容器自身,進而產生服務錯誤。
核心機制說明:
- 當你在 ServBay 新增網站並指定域名(如
example.servbay.demo
)時,ServBay 會自動將該域名指向127.0.0.1
。 - 這是實現本地友善域名存取的標準作法。如果不改 hosts 檔,就只能用
http://127.0.0.1:PORT
這種方式,無法用自訂域名。
可以禁止這個行為嗎?
理論上你可手動移除 ServBay 加入的條目,但這會讓你無法用 ServBay 設定的域名存取本地站點,違背了 ServBay 提供便利本地開發體驗的初衷。ServBay 的核心特色之一就是簡化本地站台的建立與存取流程。若你不希望 ServBay 管理特定域名對應,可選擇不要為該域名在 ServBay 建立網站。
對於大多數本地開發需求,ServBay 自動維護 hosts 檔案是預期且能大幅簡化開發流的設計。
Q2: 我的 Docker 容器如何透過域名正確存取由 ServBay 管理的 macOS 主機網站(例如 mysite.servbay.demo
)?
這是很常見的需求,但得小心處理以免踩雷。當 ServBay 在你 macOS 主機打造網站(如 mysite.servbay.demo
,會解析到主機本身的 127.0.0.1
)時,Docker 容器內的 127.0.0.1
其實指向容器自己而非主機。
錯誤示範:直接用 host.docker.internal
作為網址去存取 ServBay 網站
雖然 Docker Desktop for Mac (和 Windows) 提供了特殊的 DNS 名稱 host.docker.internal
讓容器內解析到主機 IP,但強烈不建議將它直接寫在網址作為 Host 去連 ServBay 網站 (如存取 http://host.docker.internal/
期望取代 mysite.servbay.demo
)。
這是因為這樣一來,送到 ServBay Web 伺服器(如 Caddy、Nginx)的 HTTP 請求標頭 Host
會是 host.docker.internal
。ServBay 依賴 Host 標頭決定要導向哪個網站。如果 Host
為 host.docker.internal
而不是 mysite.servbay.demo
,Web 伺服器無法正確對應站台,甚至若是 HTTPS 會產生 SNI(Server Name Indication)錯誤,因 SSL 憑證只簽給 mysite.servbay.demo
,不是 host.docker.internal
。
正確解決辦法:啟動 Docker 容器時加上 extra_hosts
若要讓容器內的應用可以用原始域名(如 mysite.servbay.demo
)存取並正確送出 Host
標頭,應該在容器的 /etc/hosts
加入映射條目,把該域名指向主機 IP。這可以透過 extra_hosts
(在 docker-compose.yml
內)或 --add-host
(用 docker run
)實現,並指向 host.docker.internal
或更推薦的 host-gateway
。
用
docker run
:bashdocker run --add-host=mysite.servbay.demo:host-gateway ... your_image
1(
host-gateway
是特殊值,Docker 會自動取代成主機的內部 IP。Docker 20.10+ 通常會用這個,是host.docker.internal
的底層別名。)用
docker-compose.yml
:yamlversion: '3.8' # 或更高 services: myapp: image: your_image extra_hosts: - "mysite.servbay.demo:host-gateway" # 或 "mysite.servbay.demo:host.docker.internal" # ... 其他設定
1
2
3
4
5
6
7
設好之後,在 Docker 容器裡:
- 當應用存取
http://mysite.servbay.demo
或https://mysite.servbay.demo
,容器的/etc/hosts
會解析此域名到 macOS 主機 IP。 - 請求會送到主機上 ServBay Web 伺服器。
- HTTP
Host
標頭會正確是mysite.servbay.demo
,ServBay 可以正確對應站台、處理 SSL 憑證(若用 HTTPS)。
Q3: 我的 Docker 容器如何連接由 ServBay 管理的資料庫(如 MySQL、PostgreSQL)或其他非 HTTP 服務?
和存取網頁服務不同,當連接資料庫或不依賴 SNI 的 TCP 服務時,建議直接用 host.docker.internal
做 server 地址。
操作步驟:
- 確認 ServBay 的資料庫套件(或其他服務)已啟動 並設定允許主機存取(本機開發通常預設即可)。
- 在 Docker 容器內,設定資料庫連線資訊時:
- 主機 (Hostname/Server): 使用
host.docker.internal
- 連接埠 (Port): ServBay 中登記的該資料庫套件對應連接埠(如 MySQL 通常
3306
、PostgreSQL 是5432
) - 帳號/密碼: 使用你在 ServBay 資料庫套件設定的憑證
- 主機 (Hostname/Server): 使用
範例(連線 ServBay MySQL): 假設 ServBay 上 MySQL 在預設埠 3306
,在 Docker 容器應用內連線字串可如下:
- 主機:
host.docker.internal
- 連接埠:
3306
- 使用者:
your_db_user
- 密碼:
your_db_password
Q4: 當 Docker 容器透過域名(搭配 extra_hosts
設定)存取 ServBay 上的 HTTPS 網站(由 ServBay User CA 簽發憑證)時,如何讓容器信任此 CA?
如果你已依 Q2 的建議,用 extra_hosts
或 --add-host
映射了 secure.servbay.demo
到 host-gateway
,但 secure.servbay.demo
用的是 ServBay User CA 簽的 SSL 憑證,那一般 Docker 容器不會信任此 CA,會造成 SSL 連線失敗。
ServBay CA 憑證檔在 macOS 主機位置:
- ServBay User CA 根憑證:
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
- 含 ServBay User CA 及 Mozilla 根憑證的 PEM 檔案:
- ARM 架構 Mac:
/Applications/ServBay/package/common/openssl/3.2/cacert.pem
- Intel 架構 Mac:
/Applications/ServBay/package/common/openssl/1.1.1u/cacert.pem
- ARM 架構 Mac:
解決方法概觀:
主流做法可分為以下三種:
- 方法一:映像建構時植入系統信任(Dockerfile 方式) — 如需多處都信任此 CA 並可自訂映像,推薦此法。
- 方法二:應用層運行時信任(掛載檔案+環境變數) — 只特定應用需信任 CA,或不想修改映像時適用。
- 方法三:系統層運行時信任(掛載+客製啟動指令) — 不建映像但需系統等級信任時用。
方法一:映像建構時植入系統信任(Dockerfile 方式)
在建構映像時,將 CA 憑證整合進系統信任庫。
- 準備憑證檔: 先將
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
複製到 Docker build 資料夾(與 Dockerfile 同層)。 - Dockerfile 示例(Debian/Ubuntu):dockerfile
# Dockerfile FROM ubuntu:latest COPY ServBay-Private-CA-ECC-Root.crt /usr/local/share/ca-certificates/ServBay-User-CA.crt RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && \ update-ca-certificates && \ rm -rf /var/lib/apt/lists/*
1
2
3
4
5
6 - Dockerfile 示例(Alpine):dockerfile
# Dockerfile FROM alpine:latest COPY ServBay-Private-CA-ECC-Root.crt /usr/local/share/ca-certificates/ServBay-User-CA.crt RUN apk add --no-cache ca-certificates && update-ca-certificates
1
2
3
4 - 使用 docker-compose 建構:yaml
# docker-compose.yml version: '3.8' services: myapp: build: context: ./app_service # 夾帶 Dockerfile 和憑證 dockerfile: Dockerfile extra_hosts: ["secure.servbay.demo:host-gateway"]
1
2
3
4
5
6
7
8
方法二:應用層運行時信任(掛載憑證+環境變數)
此法將 CA 憑證掛載進容器,並針對特定應用設定相關環境變數(如 Node.js、Python 等)來信任該 CA。
docker-compose.yml
範例:yaml請參閱各應用文件確定對應環境變數。version: '3.8' services: myapp: image: some-base-image volumes: - /Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt:/etc/ssl/certs/MyCustomCA.crt:ro environment: # Node.js 範例: - NODE_EXTRA_CA_CERTS=/etc/ssl/certs/MyCustomCA.crt # Python (requests) 範例: # - REQUESTS_CA_BUNDLE=/etc/ssl/certs/MyCustomCA.crt # 通用 SSL_CERT_FILE 範例: # - SSL_CERT_FILE=/etc/ssl/certs/MyCustomCA.crt extra_hosts: ["secure.servbay.demo:host-gateway"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
方法三:系統層運行時信任(掛載憑證+自訂啟動命令)
此法結合憑證掛載與啟動時注入系統信任機制,免建映像但啟動命令較複雜。
docker-compose.yml
範例(Debian/Ubuntu Base):yaml注意:version: '3.8' services: myapp: image: ubuntu:latest # 或任何有 update-ca-certificates 的映像 volumes: # 直接掛載主機 CA 進標準目錄 - /Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt:/usr/local/share/ca-certificates/ServBay-User-CA.crt:ro # 覆蓋 command: 啟動時更新憑證,然後啟動應用 command: > sh -c " echo 'Attempting to update CA certificates...' && if command -v update-ca-certificates > /dev/null; then if [ ! -f /usr/bin/update-ca-certificates ]; then apt-get update && apt-get install -y --no-install-recommends ca-certificates; fi && update-ca-certificates && echo 'CA certificates updated.' else echo 'update-ca-certificates command not found, skipping CA update.' fi && echo 'Starting application...' && exec your_original_application_command_here # 請替換為原本的應用啟動指令 " extra_hosts: ["secure.servbay.demo:host-gateway"] # 如需 root 權限,可加 user: root 或設置 entrypoint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23- 複雜性: 覆寫
command
或entrypoint
會變複雜,尤其遇到官方映像需特知啟動流程。 - 權限:
update-ca-certificates
通常要 root。容器默認不是 root 時可能失敗,記得適當提權。 - 依賴: 必須安裝
ca-certificates
套件及指令。此腳本會自動判斷並安裝(僅適用 apt 系)。 - 啟動時間: 每次都做檢查跟安裝會拖慢啟動。
- Alpine Linux: 若 Alpine,指令為
apk add --no-cache ca-certificates && update-ca-certificates
。
- 複雜性: 覆寫
何時選哪種方式?
- 能自訂映像、需系統廣泛信任時,建議方法一。
- 不想建映像、僅特定應用需信任時,建議方法二。
- 不建映像、但需系統等級信任,選方法三。
如用公有 CA 憑證(例如 Let's Encrypt): 若 ServBay 網站用 ACME 協定取自公有 CA 憑證(如 Let's Encrypt),大多原生 Docker 映像已信任這些憑證,通常不需特別處理。
Q5: 如何用 ServBay 為運行在 Docker 容器中的應用指派域名並設置反向代理?
假設你在 Docker 容器運行應用(如 Node.js 監聽 3000 埠),希望能為它配個好記域名如 myapp.servbay.demo
並用 ServBay 幫你管理 SSL 憑證。
操作流程:
在 macOS 主機以 127.0.0.1 對映容器端口: 記得在執行 Docker 容器時,把應用監聽的端口對映到主機的
127.0.0.1
,保證只有本機可存取,阻隔外部網路。bash# 範例:容器內應用監聽 3000,對應主機 127.0.0.1:3001 docker run -d -p 127.0.0.1:3001:3000 your-docker-app-image
1
2如此容器內應用會透過主機的
http://127.0.0.1:3001
來存取。在 ServBay 新增網站並設反向代理:
- 打開 ServBay 管理介面。
- 點選「新增網站」。
- 域名: 輸入欲指定之域名,例如
myapp.servbay.demo
。 - 網站型態: 選擇「反向代理」。
- IP 地址: 輸入
127.0.0.1
。 - 連接埠: 輸入剛才容器對映到主機的端口,如
3001
。 - 按「儲存」或「新增」。
(選擇性) 啟用 SSL 憑證: 站點新增後,可進入其設定,開啟 SSL 憑證。ServBay 支援自動向 Let's Encrypt 等公有 CA 申請憑證,或選擇用 ServBay User CA/ServBay Public CA。ServBay 會做 SSL 終止,對 Docker 容器用 HTTP(即
http://127.0.0.1:3001
)。測試存取: 設好後,瀏覽器即可存取
http://myapp.servbay.demo
或(若已啟用 SSL)https://myapp.servbay.demo
。ServBay 會自動將請求代理到 Docker 容器裡的應用。
整體流程: 用戶端瀏覽器 → https://myapp.servbay.demo
→ ServBay(SSL與反代判斷)→ http://127.0.0.1:3001
(主機端口)→ 進入 Docker 容器應用。
總結
ServBay 大幅簡化 macOS 本機網頁開發。搭配 Docker 時要注意:
- 從 Docker 存取由 ServBay 托管的網站:請用
extra_hosts
或--add-host
將域名指向host-gateway
,確保Host
標頭正確避免 SNI 錯誤。 - 從 Docker 存取由 ServBay 托管的資料庫或其他非 HTTP 服務:直接用
host.docker.internal
當主機名稱最簡單有效。 - 讓 Docker 信任 ServBay User CA 自簽 SSL:需將 CA 憑證複製進映像並更新信任庫。
- 要用 ServBay 反向代理 Docker 應用:在 ServBay 選「反向代理」站點型態並對應主機的對應端口。
請確保 ServBay 的相關套件(Web 伺服器、資料庫等)與你的 Docker 容器都已正確設定並啟動。