用Docker建置具備HTTPS的NGINX反向代理伺服器:docker-HTTPS-Reverse-Proxy / Build a NGINX Reverse Proxy with HTTPS in Docker: docker-HTTPS-Reverse-Proxy
直接設定NGINX實在是太複雜了,那我們用Docker把複雜的內容都包裝起來,只追求最簡單的設定即可。
docker-HTTPS-Reverse-Proxy
https://github.com/pulipulichen/docker-HTTPS-Reverse-Proxy
docker-HTTPS-Reverse-Proxy是我為了將NGINX建置成理想的反向代理伺服器所開發的專案。其主要的特點有:
- 反向代理伺服器 (reverse proxy):在後端伺服器(backend)前面架設一層緩衝伺服器使用。
- 負載平衡 (loaidng balancing):如果設定多個後端伺服器,則流量會自動分配給它們使用。
- 自動快取與壓縮:大部分靜態資源,例如JavaScript、CSS、圖片、聲音與影片,都會被自動快取和壓縮。
- 隱藏伺服器資訊:Server、X-Powered-By等標頭會被自動移除。錯誤訊息的網頁也被簡化,讓人完全看不出這是什麼伺服器。
- 流量限制:避免DDoS攻擊。
- SSL憑證:分析後端伺服器的設定,使用certbot申請憑證並且安裝,每30天進行更新,一切全自動。
- 虛擬主機:根據域名判斷後端伺服器。
環境 / Environment
docker-HTTPS-Reverse-Proxy是以Docker為主。下載檔案需要用到git。部分腳本使用了只能在Linux運作的bash。
最難克服的應該只有Docker引擎的部分。關於Docker的安裝,請看Install Docker Engine。除了Docker引擎之外,還需要安裝docker-compose,詳細請看「Install the Compose standalone」。
使用方法 / Usage
首先我們要將docker-HTTPS-Reverse-Proxy用git複製到本地端:
git clone https://github.com/pulipulichen/docker-HTTPS-Reverse-Proxy.git
再來是複製./conf/backends.sample.yml為./conf/backends.yml,然後修改它。
backends:
- test-a111.pulipuli.info: example.com
- test-b222.pulipuli.info:
- www.helloworld.org
- example.com
https://github.com/pulipulichen/docker-HTTPS-Reverse-Proxy/blob/main/conf/backends.sample.yml
backends.yml是以YAML的格式撰寫。backends底下必須是陣列,而陣列中每個元素則是以key-value的形式配對。
以「test-a111.pulipuli.info: example.com」為例,key「test-a111.pulipuli.info」為後端伺服器的域名,value「example.com」為後端伺服器的連線方式。此時連線方式僅接受HTTP連線,通常可能的設定是「127.0.0.1:8080」。而後端伺服器不一定是要在本機端,也可連到其他伺服器去。
value也可以設定多個後端伺服器,這樣就能實現負載平衡的效果。以key「test-b222.pulipuli.info」為例,它的後端伺服器就包括了「www.helloworld.org」跟「example.com」。NGINX會自動將流量分配給現在連線數量最少的後端伺服器。
值得注意的是,如果域名本身已經在DNS註冊的話,docker-HTTPS-Reverse-Proxy會自動使用certbot申請Let's Encrypt憑證、安裝,並且每30天自動檢查憑證是否需要更新。
啟動 / Startup
設定好backends.yml後,請用以下腳本啟動:
./startup.sh
此時會進行以下程序:
- Docker引擎下載必要的映像檔。
- Docker編譯與安裝必要的元件。
- 啟動Docker容器。
- Docker容器檢查backends.yml,建立對應的NGINX設定檔,以及配置好certbot需要的指令。
- 如果有網域符合申請SSL憑證的資格,此時certbot會嘗試跟Let's Encrypt申請憑證。
- 啟動NGINX伺服器。
跟大部分Docker版本的NGINX伺服器一樣,網頁的連線資訊全部顯示在畫面上,不會保存在特定的文件中。如果有分析連線記錄需求的話,可能要在後端伺服器找找看。
NGINX進階設定 / NGINX configuration
https://github.com/pulipulichen/docker-HTTPS-Reverse-Proxy/tree/main/conf/nginx
如果你有特別的需求,可以手動修改NGINX設定。我將NGINX設定拆解成多個樣板檔案,放在./conf/nginx 之中。預設情況下,你只會看到「.sample.template」的範例檔案。一旦執行過「./startup.sh」,腳本會自動從範例檔案複製一份成為你的NGINX設定。你也可以自己手動從範例檔案複製,就跟前面從backends.sample.yml複製成backends.yml的做法一樣。
樣板檔案中以${}包裹的變數檔案是我在設定樣板時會使用的位置。你可以挪動變數的位置,但不要移除它。你可以在其他地方加入你需要的設定。
更新 / Update
如果你修改過NGINX的樣板檔案設定,那請使用「./git-reset.sh」更新。它會保留你修改的NGINX樣板檔案,以及backends.yml檔案。
如果你不想要保留NGINX樣板檔案的設定,也想要一併更新到目前的版本,那請執行「./reset-nginx.sh」。
結語 / Conclusion
其實用NGINX跟certbot實作具有HTTPS功能反向代理伺服器的方案很多,不過大部分的做法都是拆開成多個Docker容器來實作。而且大部分方案對於NGINX伺服器的設定還真的只有「反向代理伺服器」的簡單功能,至多就是連接到「後端伺服器」。好一點的方案有把certbot申請包含進去,但沒檢查域名狀態就申請實在很容易讓人搞砸,而且至多也只能支援申請一個域名,還沒有負載平衡的功能。
docker-HTTPS-Reverse-Proxy實作了我期望反向代理伺服器應該要做到的大部分功能,並且將設定儘可能地簡化。就如我之前期望的,希望docker-HTTPS-Reverse-Proxy不僅僅只是讓後端伺服器增加了HTTPS的功能,還能夠達到保護後端伺服器、阻擋DDoS、以及提高網頁服務效率等目的。
希望docker-HTTPS-Reverse-Proxy能減輕伺服器維護人員的負擔,也能夠讓網站使用者連線順利。祝網路世界和平、繁盛。
最後本篇的問題是:你用什麼軟體架設伺服器的呢?
歡迎大家在下面講講你們的經驗喔!