iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
Modern Web

網站一條龍 - 從架站到前端系列 第 14

[Day14] 架設 Nginx 當我們的 Web Server

.NET 5 Web API 佈署到 Linux 上執行的時候,會跑在一個 Kestrel 伺服器上。Kestrel 從 .NET Core 1.x 發展至今,其實功能已經相當完善,可以直接當作對外的窗口。不過本系列不會用內建的 Kestrel 來對外,而是使用一個同樣輕巧、但是高效又炫炮的 web server 來幫我們做反向代理(inverse proxy),而這個炫炮的 server 就 Nginx。

什麼是 Web Server

筆者之前嘗試自己寫這段,但是後來找參考資料的時候發現這篇,就決定把自己寫的全部刪掉,直接開傳送門就好…等級差太多了QQ

不過,懶人包還是要有,web server以最粗淺的理解就是:

  1. 我們對外的窗口,接收 http/https request
  2. 根據接收到的 request,視情況回傳靜態資源或轉發 request 到背後執行的程式
  3. 在高流量的應用中作為負載平衡器(load balancer),把 request 分散到背後執行的多個程式實體

安裝並啟動 Nginx

一樣透過 yum 直接下載並安裝 Nginx
sudo yum install sudo yum install nginx

Nginx 其實是依附在 EPEL (Extra Packages for Enterprise Linux) 這個 Package 之中,GCP 的 CentOS 內建這個 EPEL所以可以直接安裝,如果邦友是用 DigitalOcean 的 CentOS,會需要先安裝 EPEL
sudo yum install epel-release

裝完之後,就能透過 systemctl 啟動 Nginx
sudo systemctl start nginx
接著到瀏覽器輸入 http://外部IP(不是 https 喔)就能看到 Nginx 在 CentOS 上的預設首頁
https://ithelp.ithome.com.tw/upload/images/20210914/20140664YC9bEOyTjS.png

這裡稍微說明一下,剛安裝完 Nginx 尚未做任何設定之前,Nginx 只幫我們處理 80 port 的 http request,而且會直接回覆靜態的 Welcome 首頁。因為 http request 預設走 80 port;https 走443,所以當我們發送 http request到我們的 VM 時,Nginx 就會幫我們回覆上面那個頁面。發送 https request 則會連不到東西 XD

Nginx 預設不會隨著開機啟動,為了方便,我們一樣透過 enable 指令把它加入開機自動啟動的名單中
sudo systemctl enable nginx

設定 Nginx 轉發請求

目前我們的 Nginx 是根據 /etc/nginx/nginx.conf 這個預設設定檔在執行,根據前輩們的建議,比較好的做法是把這個檔案裡的 server 區段註解掉,然後讓同樣這個檔案裡的 include /etc/nginx/conf.d/*.conf; 引入其他設定。

所以首先,先打開預設的設定檔
sudo vi /etc/nginx/nginx.conf
然後把 server 區段用井號(#)註解掉

#    server {
#        listen       80;
#        listen       [::]:80;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        # Load configuration files for the default server block.
#       include /etc/nginx/default.d/*.conf;
#
#        error_page 404 /404.html;
#        location = /404.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#        location = /50x.html {
#        }
#    }

接著,在 /etc/nginx/conf.d/ 資料夾底下,新增屬於我們 API 專案的設定檔
sudo touch /etc/nginx/conf.d/ironman.conf
再用 vim 打開這個檔案,加入下列設定

server {
    listen        80;
    server_name   example.com *.example.com;
    location / {
        proxy_pass         http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

存檔之後用 sudo nginx -t 指令測試設定檔有沒有問題。沒有問題的話就能用 sudo nginx -s reload 讓 Nginx 重新載入設定檔

這時候如果馬上就開啟瀏覽器連我們的 VM,會跳出 502 Bad Gateway 錯誤,這是因為 CentOS 有一個叫做 Security-Enhanced Linux (SELinux) 的東西來加強安全性,它會阻擋我們的連線。我們可以用下列這行指令來解決這個問題
sudo setsebool -P httpd_can_network_connect on

執行完畢之後,再次到瀏覽器輸入 http://外部IP/api/User 就會發現,我們的 http request 最後會變成 https://外部IP:5001/api/User,原因是我們的 request 被 Nginx 轉發到 127.0.0.1:5000(本機的 5000 port),然後 .NET 玉社會把 http request 重新導向到 https 監聽的 port,於是最後我們就從https://外部IP:5001/api/User 取得我們的資料。

Nginx 雖然輕巧而且功能強大,但是筆者覺得它的水也有點深,關於 Nginx 更多的知識與設定,請參考前面傳送門的續篇

明天我們將會稍微介紹一下如何為我們的 Nginx 掛上 SSL 憑證,替它加上鎖頭。


上一篇
[Day13] 在 GCP 上面設定防火牆
下一篇
[Day15] 幫我們的網站設定 SSL 憑證
系列文
網站一條龍 - 從架站到前端33

尚未有邦友留言

立即登入留言