Nginx 很強,但設定檔學習曲線陡、調整一個 virtual host 得改檔案再 reload、Let’s Encrypt 憑證還要額外裝 Certbot 並確保 renewal 正常跑。對於需要管理多個服務但不想把時間花在維護反代設定的人,Nginx Proxy Manager(NPM)是另一條路。
NPM 是一個跑在 Docker 裡的網頁介面,底層仍然是 Nginx,但所有設定都透過 GUI 完成:新增 proxy host、申請 Let’s Encrypt 憑證、設定存取控制,全部點幾下就好。
它的受眾很明確:自架服務的開發者、需要讓同事也能操作反代設定的小團隊、或是純粹不想記 Nginx 語法的人。如果你需要細粒度的 Nginx 調校或複雜的條件路由,手寫設定檔或 Caddy 才是適合的工具。
部署:五分鐘跑起來
NPM 只需要一個 SQLite 或 MariaDB 資料庫,官方提供了兩種設定。對大多數情況,直接用內建 SQLite 就夠,省掉管理一個額外資料庫容器的麻煩:
1 | # /opt/npm/compose.yaml |
1 | cd /opt/npm |
啟動後約 30 秒,開啟 http://你的IP:81 就能看到登入頁面。
預設帳號密碼:
- Email:
[email protected] - Password:
changeme
第一次登入會立即要求更換,這個步驟不能跳過。
./data 和 ./letsencrypt 是需要 persist 的兩個目錄。前者存放 NPM 的設定資料庫,後者存放 Let’s Encrypt 憑證。這兩個目錄如果消失,所有設定和憑證都得重來。
管理介面的核心功能
NPM 的介面分成幾個主要區塊:
Proxy Hosts:這是最常用的功能,設定「哪個網域要代理到哪個服務」。每條規則可以獨立設定 SSL、WebSocket 支援、自訂 headers。
SSL Certificates:集中管理憑證,可以看到所有已申請的 Let’s Encrypt 憑證和到期時間。NPM 會自動在到期前 30 天更新。
Access Lists:設定 IP 白名單或基本 HTTP 認證。對不想對外公開的管理介面(Portainer、監控 dashboard 等)很實用。
Streams:TCP/UDP 層的代理,適合非 HTTP 服務,例如 MySQL、遊戲伺服器。
新增 Proxy Host 並申請 HTTPS 憑證
以一個跑在本機 3000 port 的應用為例:
Step 1:進入 Proxy Hosts,點擊「Add Proxy Host」
Step 2:Details 分頁填入:
- Domain Names:
app.yourdomain.com - Scheme:
http - Forward Hostname / IP:
172.17.0.1(Docker bridge 的 host IP)或服務的容器名稱 - Forward Port:
3000 - 勾選「Websockets Support」(大多數現代應用都需要)
Step 3:切換到 SSL 分頁:
- SSL Certificate:選「Request a new SSL Certificate」
- 勾選「Force SSL」和「HTTP/2 Support」
- 勾選「I Agree to the Let’s Encrypt Terms of Service」
- 點擊「Save」
NPM 會自動向 Let’s Encrypt 申請憑證,完成後這條規則就上線了。整個過程不超過一分鐘。
讓 NPM 能連到同一臺機器上的其他 Docker 容器
這是最常見的困惑點。NPM 跑在自己的 Docker network 裡,要連到同一臺機器上的其他容器,需要讓它們共用同一個網路。
最乾淨的方式是建立一個共用 network:
1 | docker network create npm_proxy |
讓 NPM 加入這個 network:
1 | # NPM 的 compose.yaml |
讓其他服務也加入:
1 | # 其他服務的 compose.yaml |
這樣在 NPM 新增 Proxy Host 時,Forward Hostname 就直接填容器的 service 名稱(例如 myapp),不需要暴露 port 到 host。
port 81 的安全問題
預設設定下,NPM 的管理介面(port 81)對所有 IP 開放。在生產環境這不是個好主意。
處理方式有幾種:
- 把 port 81 綁定到 localhost:
"127.0.0.1:81:81",搭配 SSH tunnel 存取 - 用 UFW 只允許特定 IP 存取 81:
sudo ufw allow from 你的管理IP to any port 81 - 在 NPM 裡把管理介面本身也加一個 Access List 做 IP 白名單
特別提醒:如果你的 VPS 有跑 Docker,UFW 的規則對直接映射到 host 的 port 可能無效(Docker bypass UFW 問題)。最保險的做法是直接用 127.0.0.1:81:81 綁定,再透過 SSH tunnel 或 VPN 才能連到管理介面。
客製化 Nginx 設定
NPM 不讓你直接改 nginx.conf,但提供了幾個掛載點讓你加入自訂設定片段:
在 Proxy Host 的「Advanced」分頁,可以直接填入自訂的 Nginx location block:
1 | # 範例:設定更長的 proxy timeout |
需要全域設定的話,可以把設定檔放到 /data/nginx/custom/ 路徑:
http.conf:加在 http block 結尾root.conf:加在 nginx.conf 結尾
這個機制讓大多數常見的自訂需求都能處理,而不需要直接動到 NPM 內部的設定檔。
備份與遷移
NPM 的所有設定都在 ./data 目錄裡(SQLite 資料庫 + 其他設定),憑證在 ./letsencrypt。備份就是這兩個目錄,遷移到新機器也只需要把這兩個目錄複製過去,再用同樣的 compose.yaml 啟動就能完整還原。
NCSE Network 的 VPS 適合跑 NPM 搭配多個自架服務的場景,NVMe SSD 讓容器啟動和 I/O 都更快。有興趣可以到 ncse.tw 查看方案。