在 Mac 上使用 Nginx + SSL & HTTP/2 做網站開發的設定

在 Mac 上使用 Nginx + SSL & HTTP/2 做網站開發的設定

1. 安裝 Nginx

推薦使用 Homebrew 在 Mac 上安裝 Nginx:

brew install nginx

安裝完成後,就能用 brew services 來幫我們啟動 Nginx:

sudo brew services start nginx

2. 設定 Nginx

用慣用的編輯器打開 /usr/local/etc/nginx/nginx.conf,然後確認裡面有 include servers/*.conf; 這行。(通常會在最後一行,把前面的 # 註解符號拿掉就可以了)

3. 安裝 DNS Server

雖然透過編輯 /etc/hosts 也能達到類似的效果,但個人覺得這個檔在 Mac 上還是把這個檔交給系統控制就好,所以自己的習慣是在電腦上架個 DNS Server,然後在網路設定使用電腦上的 DNS Server 就好。

用以下指令可以安裝並啟動 dnsmasq:

brew install dnsmasq
sudo brew services start dnsmasq

4. 設定 DNS Server

同樣的,打開 /usr/local/etc/dnsmasq.conf 並且確認有這行:

conf-dir=/usr/local/etc/dnsmasq.d/,*.conf

(也通常會寫在最後一行,把前面的 # 註解符號拿掉就可以了)

然後,建立 /usr/local/etc/dnsmasq.d/localhost.conf 這個檔案,在裡面寫:

address=/localhost/127.0.0.1

也就是把所有 *.localhost 的網址解析到 127.0.0.1 的意思。

存擋後,執行 sudo brew services reload dnsmasq 來重載 dnsmasq 的設定。

如果要測試 dnsmasq 有沒有正確設定,可以執行 nslookup test.localhost 127.0.0.1,應該要得到 IP 是 127.0.0.1 的結果。

再來就是在系統的網路設定,把 127.0.0.1 加成其中一個 DNS server:

注意除了 127.0.0.1 之外,裡面一定要有一個一般的 DNS server,不然其他公開的轉就會連不上去了。

要測試系統的 DNS server 有沒有設定好,可以在瀏覽器前往 http://test.localhost,應該要看到 ERR_CONNECTION_REFUSED 型而非 ERR_NAME_NOT_RESOLVED 的錯誤。

5. 簽署憑證與建立 Proxy 網站

為了方便執行這個步驟,我把需要做的事寫成了一個 shell script。如果要為一個 Rails 網站、使用預設的 port 3000 開個新 server 的話,只要在專案目錄下執行:

create-nginx-port-forwarding-localhost-server site-name 3000 "$(pwd)/public"

就會建立提供 SSL + HTTP/2 的 site-name.localhost Nginx Virtual Host。用 rails server 啟動 Rails 之後,就可以在瀏覽器中用 https://site-name.localhost 來測試自己的網站了!

小結

雖然目前這套作法持續被我愉快使用中,不過還是有一些延伸應用需要找時間研究,例如:

  • 如何設定 dnsmasq 來針對不同裝置回覆不同結果?例如自己的電腦要回 127.0.0.1,其他裝置就回目前電腦在區域網路下的 IP,這樣使用手機測試網站時,只要在手機改個 DNS 設定就方便了。
  • 如果是開發 iOS 應用的話,iOS Simulator 預設會沿用電腦的網路設定,而且 127.0.0.1 也是指向實體裝置,所以在 Safari 下可以無痛地使用 *.localhost 網址。但是 native app 似乎就完全無動於衷了,似乎改 iOS 系統的 DNS 設定也沒有用,有點小困擾。
  • Android Virtual Device 更麻煩一點,因為 AVD 系統中的 10.0.2.2 才是指向電腦的 127.0.0.1,所以無法只靠本篇的敘述就達成可以在 AVD 測試的目的。

也許最終極的作法是買個真實的 domain 搭配自架 reverse proxy,目前也還在研究中 XD