iT邦幫忙

2021 iThome 鐵人賽

DAY 26
1

前言

在昨天的文章介紹了 Nginx 的基本觀念以及 Nginx container 的內部操作,今天就要正式進入設定檔的撰寫了,由於 Nginx 可以設定的東西真的太多了,如果只用一篇文章來解釋的話可能沒辦法讓讀者更了解一些設定的使用情境,因此這邊筆者想要針對前端以及後端分別介紹幾個常用的設定,讓讀者可以更了解 Nginx 的好用之處,那我們就開始今天的文章吧!

前端 nginx.conf 寫法

首先我們先來看個範例:

server {
  listen 80;
  listen 443 default ssl;
  
  server_name _;
  
  ssl_certificate /etc/nginx/ssl/tls.crt;
  ssl_certificate_key /etc/nginx/ssl/tls.key;

  root /usr/share/nginx/html;
  charset utf-8;

  keepalive_timeout 600;
 
  location /healthz {
    return 200 "healthy\n";
  }

  location / {
    try_files $uri $uri/ /index.html?$args;
  }

  location = /favicon.ico { access_log off; log_not_found off; }
  location = /robots.txt { access_log off; log_not_found off; }

  client_max_body_size 10m;
 
  # set expiration of assets to MAX for caching
  location ~* \.(ico|css|js|gif|jpe?g|png)$ {
    expires max;
    add_header Cache-Control "public";
  }
}

可能讀者看到上面那麼多的設定一時之間會覺得很可怕,但其實前端的設定可以說是相當單純,接下來就來解析一下上面幾個常用的設定吧!

  • server block

    首先想要開始撰寫 Nginx 的內容前必須要先宣告一個 server block 也就是筆者一開始用的 server {},這樣 Nginx 在讀取設定值的時候才會知道這些設定其實是在同一個 server 上,而我們目前要設定的 server 是 web server。

  • listen

    listen 是用來告訴 Nginx 說我要監聽 server 上的某個 port,當有 request 從這個 port 進來的時候要跑這個 server 內的設定值,通常前端都會聽 80443,這兩個 port 是 http 以及 https 專用的 default port,相信沒有任何一個網站的網址是長 https://xxx.com.tw:8080 這樣吧XD

  • server_name

    server_name 代表的是只能接收從特定的 domain 來的需求,不是這個 domain 的都會擋掉,基本上前端不太會限制這個,除非你的網站是要擺在公司內網上,不然通常都會開放給大家連進來,所以今天要開放給所有人都可以看的話就可以打上 server_name _,這個 _ 就代表著我沒有要擋住任何外來的需求。

  • ssl_certificate & ssl_certificate_key

    擺放 SSL certificate credentials 的地方,這邊要把完整的路徑寫上去,而且此路徑一定要有這些檔案,不然 Nginx 會讀取不到這些憑證也就沒辦法使用 https 連線了。

  • root

    設定讀取檔案的資料夾要在哪個位置,還記得昨天的文章有提到 Nginx 在讀取 html 檔時都會在 /usr/share/nginx/html 這個資料夾讀取,所以假如讀者使用 Dockerfile 並搭配 multi-stage build 的觀念時,要記得把檔案都複製到 /usr/share/nginx/html 這個資料夾,這樣 Nginx 才能讀到 index.html 檔喔。

  • charset

    熟悉前端的讀者應該知道 charset 代表的是什麼,通常我們在 html 上面都會有這段 <meta charset="utf-8" /> 用來告訴網頁要用什麼編碼來解析這些內容,通常使用的都會是 utf-8,Nginx 代表的意思也是一樣。

  • keepalive_timeout

    用來設定 client 端連結到 server 端超過多少時間就要斷開連結,這邊的單位是 秒數 跟我們在寫程式中使用的 毫秒 不太一樣,這邊讀者要特別注意喔!

  • location

    location 代表的是遇到指定的 path 就要做相對應的事情,例如上面的範例有一段是 location /healthz { return 200 "healthy\n"; } 這段的意思就代表著當 path/healthz 時也就是 request url 為 https://xxx.com.tw/healthz 時要 return 200,這種設計通常都是做 health check 來確認 server 是否可以正常接收 request。

    這時候眼尖的讀者可能有注意到這段:

    location / {
      try_files $uri $uri/ /index.html?$args;
    }
    

    這段文字代表的是 root path 要去找 index.html 檔,也就是當我輸入 https://xxx.com.tw 時就要顯示 index.html 的內容,至於 $uri $uri/ 是什麼意思呢?這段話代表的是假如我在某個 path 上找不到相對應的檔案時都可以回來利用 index.html 進行渲染,通常網頁都是 SPA 的架構,透過這種設定方式就可以讓 SPA 可以利用一些框架的 router 操作進行畫面渲染了。

    接下來底下筆者還多設定了兩個 location

    # set expiration of assets to MAX for caching
    location ~* \.(ico|css|js|gif|jpe?g|png)$ {
      expires max;
      add_header Pragma public;
      add_header Cache-Control "public";
    }
    

    其實筆者已經先破梗了,看到上面的註解應該會知道這邊其實就是用來作 cache 的動作,還記得 Nginx 可以被用來當作是反向代理伺服器嗎?在反向代理伺服器中有一個很重要的機制就是 cache,透過代理伺服器我們就可以很簡單的幫檔案 cache 起來進而減少跟真正的伺服器端發 request,在前端的世界中通常圖片都不太容易變動,即便有變動也會是一張新的圖並且有著新的檔案名稱,利用這個特性我們就可以把圖片 cache 起來這樣日後在存取圖片時就可以很快速地取得了。

    這邊可以看到筆者做了幾個設定,接下來說明這幾個特性:

    • expires

      expires 簡單來說就是要替這個檔案新增幾天的 cache,在這幾天內都不會去跟 server 拿最新的資料,而筆者這邊設定 max 則代表 10 年內都不會去拉,可以當作是一個永久 cache 的概念。

    • add_header

      add_header 則是新增一個 http header,由於這邊跟 cache 有關因此設定 http header 中的 Cache-Control,透過這個設定就可以幫助這個檔案是否可以讓所有的來源都可以進行 cache 控制,所以 public 的意思就是全部都可以存取的意思。

  • client_max_body_size

    這個算是前端中蠻重要的一個設定,有時候我們要跟後端溝通,常常會因為帶過去的 payload 過大而無法完成,例如上傳圖片就是個很好的例子,圖片有大有小而為了要防止有心人士透過 postman 或 curl 直接跟後端溝通,進而繞過前端的檢查機制,因此我們這邊也必須要設定一個 max_body_size 來阻擋過大的 payload,這邊就看網站需求了只是要注意的是後面 m 這個單位代表的是 mb,所以不要設定過大的 client_max_body_size,不然隨便 payload 隨便帶都可以過關。

小結

今天介紹了前端的 Nginx 設定方式,可以發現前端的設定相當單純就是讓 Nginx 作為網頁伺服器而已,所以就想辦法讓根目錄可以讀到 index.html 檔就好,但是後端就沒那麼簡單了,後端就要用到其他 Nginx 的用法了,例如負載平衡、反向代理等等功能,這些都會在明天的文章做一個介紹。

如果對於文章有任何問題都歡迎留言給我,那我們就下一篇文章見嘍~


上一篇
Day25-好用的網頁伺服器-nginx(一)
下一篇
Day27-好用的網頁伺服器-nginx(三)
系列文
前端工程師學習 DevOps 之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言