在 Docker 中管理宿主機 Nginx
當 Nginx UI 執行在 Docker 中,並需要管理同一宿主機上原生安裝的 nginx 時,可按本文完成設定。
前置條件
- 透過 systemd 執行 nginx 的 Linux 宿主機,或透過
brew services執行 nginx 的 macOS 宿主機 - 同一宿主機上已安裝 Docker
- Linux:一個專用於 Nginx UI 的非特權使用者(範例中使用
nginxui) - macOS:擁有 Homebrew nginx 服務的登入使用者
- Nginx UI 管理員已啟用多重因素驗證:設定精靈需要已驗證的雙因素工作階段,否則會顯示需要多重因素驗證
在 macOS 上,請在精靈的偵測平台步驟中選擇 macOS (Homebrew)。Apple Silicon 預設使用 /opt/homebrew。在該步驟中,精靈會透過 SSH 查詢 Homebrew 並解析 nginx -V,自動識別已安裝的 nginx 版本以及實際的執行檔、設定、日誌、PID 和 Docroot 路徑;這也能識別位於 /usr/local 的 Intel Homebrew。繼續前請確認服務已載入:
brew services info nginx步驟 1:建立非特權使用者(僅 Linux)
sudo useradd -r -s /bin/bash -m -G adm nginxui-G adm 授予該使用者讀取 /var/log 檔案(包括 nginx 日誌)的權限。
macOS 應使用執行 brew services 的現有登入使用者,不要建立單獨的服務使用者。
步驟 2:SSH 目標——透過 Nginx UI 產生金鑰對
開啟偏好設定 → Nginx → Nginx 控制模式 → 編輯,選擇透過 SSH 管理宿主機,然後點擊開啟 SSH 設定精靈。變更控制模式需要已驗證的雙因素工作階段。
精靈共有五個步驟:SSH 目標、信任與測試、偵測平台、存取與安裝與驗證。以下步驟依同樣的順序說明。
在 SSH 目標中選擇私鑰來源:
| 來源 | 行為 |
|---|---|
| 產生 | Nginx UI 在受管理路徑 /etc/nginx-ui/host_key 建立 ed25519 金鑰對。 |
| 既有路徑 | Nginx UI 讀取容器內已存在的金鑰,路徑由你輸入。 |
| 貼上或上傳 | 你貼上金鑰或選擇檔案,Nginx UI 以 0600 權限存放於受管理路徑。 |
所選來源會保存為 host_key_source 設定。不支援加密的私鑰。
產生流程請點擊產生金鑰對。
複製顯示的公鑰,格式如下:
ssh-ed25519 AAAAC3...generated nginx-ui@generated將其附加到宿主機使用者的 authorized_keys 檔案:
sudo mkdir -p /home/nginxui/.ssh
echo 'ssh-ed25519 AAAA...' | sudo tee -a /home/nginxui/.ssh/authorized_keys
sudo chown -R nginxui:nginxui /home/nginxui/.ssh
sudo chmod 700 /home/nginxui/.ssh
sudo chmod 600 /home/nginxui/.ssh/authorized_keys主機金鑰驗證
宿主機 SSH 模式需要使用 known_hosts 允許清單。精靈顯示新指紋時,請先在宿主機或其他可信管道確認,再信任該金鑰。
步驟 3:信任與測試——信任主機身分
開啟精靈的信任與測試步驟,點擊掃描主機金鑰。精靈會將 SSH 服務端提供的主機金鑰與已設定的 known_hosts 檔案進行比較。
信任前請先驗證
只有在透過可信來源比對指紋後,才應信任金鑰。這個檢查用於避免在首次設定或金鑰輪換時連線到錯誤的主機。
可使用以下可信來源:
- 宿主機控制台或服務商控制面板
- 伺服器資產清單中已有的指紋記錄
- 在宿主機上直接執行指令,例如:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubssh-keyscan -p 22 host.docker.internal手動掃描備用方式
如果自動掃描不可用,請在可信終端中執行精靈顯示的 ssh-keyscan 指令。將輸出貼到貼上 ssh-keyscan 輸出,比對指紋後再信任金鑰。
主機金鑰狀態
- unknown_host:目前還沒有為該主機信任任何金鑰。
- new_algorithm:該主機已有可信金鑰,但掃描到了另一種演算法。
- changed:同一演算法的已信任金鑰不再匹配。請按安全敏感事件處理。
- trusted:掃描到的金鑰與
known_hosts匹配。
信任所有掃描到的金鑰後,點擊測試 SSH 連線。連線成功後精靈才允許繼續。
步驟 4:偵測平台
在偵測平台步驟中選擇服務管理器(Linux (systemd) 或 macOS (Homebrew))。精靈會透過 SSH 執行 nginx -V,並填入 nginx 執行檔、設定、日誌與 PID 路徑。
每個路徑欄位在與宿主機回報的值一致時標示為自動偵測,被你改動後則標示為手動覆寫。被覆寫的欄位會顯示偵測到的值,並提供還原偵測值動作。變更 nginx 執行檔路徑後,可使用依此執行檔重新偵測路徑再次執行 nginx -V,以重新整理設定檔、日誌與 PID 路徑。
nginx 執行檔路徑會保存為 sbin_path。若留空,Nginx UI 會回退到服務管理器的預設值(systemd 為 /usr/sbin/nginx,launchd 為 /opt/homebrew/opt/nginx/bin/nginx),並在儲存設定時寫入該預設值。下一步產生的 sudoers 允許清單會精確比對這個解析後的路徑。
步驟 5:存取與安裝——選擇檔案存取模式
存取與安裝步驟首先是檔案存取模式:
| 模式 | 行為 |
|---|---|
| 相容模式(SFTP) | Nginx UI 完全透過 SSH 與 SFTP 讀寫宿主機的 nginx 設定與日誌。不會把宿主機目錄掛載到容器中。 |
| 高效能模式(掛載) | Nginx UI 從綁定掛載的宿主機目錄讀取設定與日誌。速度更快,但必須依產生的掛載設定重建容器。 |
所選模式會保存為 host_access_mode 設定。
SFTP 模式涵蓋的範圍
- 設定檔、日誌檔,以及憑證簽發或續期時寫出的憑證檔案,都透過 SFTP 在宿主機上讀寫。
- 容器無法透過 SFTP 監聽宿主機檔案變化,因此設定索引與憑證探索會改為每 30 秒重新掃描一次。在宿主機上繞過 Nginx UI 所做的修改最多需要 30 秒才會顯示在介面中。
- 共用設定目錄自我檢查會被跳過,因為容器與宿主機之間沒有共用目錄。
- 已知限制:憑證目錄中可匯入憑證的掃描仍然讀取容器檔案系統,因此無法發現只存在於宿主機上的憑證。如果依賴該掃描,請在 Nginx UI 中簽發或續期憑證,或改用掛載模式。
步驟 6:存取與安裝——安裝 sudoers 項目(僅 Linux)
1. 在 nginx 主機上頁籤會顯示一段 sudoers 設定片段。複製後透過以下指令安裝:
sudo visudo -f /etc/sudoers.d/nginx-ui貼上設定片段後儲存並退出。如果語法有誤,visudo 會拒絕儲存該檔案。
Homebrew launchd 服務執行於登入使用者域中,不需要 sudoers 項目。
步驟 7:存取與安裝——設定檔案權限
選用 ACL 指令
如果 nginxui 使用者為非 root 使用者,請授予其對 /etc/nginx 的寫入權限:
sudo setfacl -R -m u:nginxui:rwx /etc/nginx
sudo setfacl -dR -m u:nginxui:rwx /etc/nginx在 macOS 上,精靈會輸出 Homebrew 設定與日誌路徑的讀寫檢查,而不是 Linux ACL 指令。
步驟 8:存取與安裝——更新容器
2. 在 Nginx UI 容器上頁籤會顯示 compose 設定片段、完整的 override 檔案與 docker run 指令。該頁籤只在容器需要變更時出現:使用掛載模式,或者 Linux Docker Engine 需要為 host.docker.internal 加入 host-gateway 對應。將片段合併到現有的 docker-compose.yml 中。
產生的片段會設定 NGINX_UI_DISABLE_BUNDLED_NGINX=true,避免容器在控制宿主機 nginx 時繼續啟動內建 nginx 服務。
在掛載模式下,片段也會綁定掛載已設定的設定、日誌與 PID 目錄。在 Linux 與 macOS 預設之間切換後,請重建容器以套用新路徑。SFTP 模式下不會加入任何目錄掛載。
如果驗證偵測到的路徑與初始預設不同,請返回容器頁籤重新產生 compose 片段,重建容器後再執行驗證。
持久化 Nginx UI 資料
請透過 Docker volume 或 bind mount 持久化 /etc/nginx-ui。宿主機金鑰允許清單預設保存在 /etc/nginx-ui/known_hosts,它應在映像升級和容器重建後繼續存在。
docker compose up -d --force-recreate nginx-ui宿主機與容器的變更都套用後,執行該步驟底部的設定檢查。它會執行下一步列出的平台與權限檢查。
步驟 9:驗證設定
開啟驗證,點擊執行驗證。主要檢查項應通過:
預期驗證結果
驗證步驟只執行 nginx 檢查:
- ✓ ssh_connect: 透過 SSH 執行 echo ok 成功
- ✓ nginx_test: 設定檔檢查通過
平台和權限檢查屬於存取與安裝步驟中的設定檢查,套用片段後你已經執行過:
- ✓ host_platform: Linux host matches systemd
- ✓ systemctl_is_active: 執行中
- ✓ unit_has_execreload: ExecReload 已宣告
- ✓ config_dir_writable: /etc/nginx 可存取
- ✓ log_dir_readable: /var/log/nginx/access.log 可讀
- ✓ pid_file_present: /var/run/nginx.pid 存在
- ✓ sudo_available: sudo -n true 執行成功
- ✓ sudoers_coverage: 所有必要項目均已設定
same_host 和 known_hosts_persistence 屬於連線檢查組,只有在命令列執行 nginx-ui host-setup test 時才會執行。
macOS 上,host_platform 會回報 Darwin,launchctl_service_loaded 取代兩個 systemd 檢查,sudo 檢查會顯示不需要 sudo。設定、日誌與 PID 檢查預設使用 /opt/homebrew 路徑。
如果 known_hosts_persistence 顯示為 warning,請檢查 Docker volume 或 bind mount。該警告不會阻止儲存,但如果 /etc/nginx-ui 未被持久化,容器重建後可信主機金鑰可能會遺失。
所有檢查通過後,點擊儲存設定。
自訂控制指令
如果在 Nginx 設定中設定了 TestConfigCmd、ReloadCmd 或 RestartCmd,Nginx UI 會以 SSH 使用者身分透過 /bin/sh -c 在宿主機上執行這些指令,而不是內建的 systemd 或 launchd 指令。除非產生的 sudoers 項目涵蓋了這些指令所呼叫的程式,否則請保持為空。
疑難排解
sudo_available 報錯 "sudo: a password is required"
- 檢查 sudoers 檔案中是否包含
NOPASSWD:,而不僅僅是(root)。 - 檢查檔案中行末續行符(
\)是否正確。
ssh_connect 報錯 "permission denied (publickey)"
- 驗證 authorized_keys 檔案中的公鑰內容、檔案擁有者及權限是否正確。
- 檢查 sshd_config 中是否啟用了
PubkeyAuthentication yes。
宿主機 SSH 金鑰變更後 ssh_connect 失敗
主機金鑰變更可能是正常操作,例如重建宿主機或輪換 SSH 金鑰;也可能表示目標主機錯誤或存在中間人攻擊。只有在確認新指紋後,才替換已信任的金鑰。
- 開啟信任與測試步驟。
- 重新掃描主機金鑰。
- 比對精靈顯示的舊指紋和新指紋。
- 在宿主機上或透過服務商控制面板驗證新指紋。
- 勾選確認框,然後點擊取代已信任金鑰。
僅在確認不再使用對應 known_hosts 項目後,才使用進階清理清理。
same_host 警告 "remote host detected"
您的 host_address 解析到了不同的機器。SSH 模式不支援跨主機使用;請參閱 使用叢集節點管理多主機 Nginx。
CLI 參考
產生宿主機 SSH 使用的金鑰對:
nginx-ui host-setup keygen --out /etc/nginx-ui/host_key輸出全部設定片段(--access-mode 為必填):
nginx-ui host-setup print --host-address host.docker.internal:22 --host-user nginxui --access-mode sftp只輸出 Docker 或宿主機側片段:
nginx-ui host-setup print --host-address host.docker.internal:22 --host-user nginxui --access-mode sftp --compose
nginx-ui host-setup print --host-address host.docker.internal:22 --host-user nginxui --access-mode sftp --host需要機器可讀輸出、完整 compose override 或 docker run 指令時,可以使用 --json、--override 或 --docker-run。
基於目前設定執行驗證:
nginx-ui host-setup test與精靈不同,test 會執行全部檢查組:連線、平台、權限與 nginx。