標籤: dns

  • Nginx 中同一個網域設定不同應用程式/目錄

    Nginx 中同一個網域設定不同應用程式/目錄

    技能點還沒有點太多的領域一點點成果就會獲得大大的成就感。

    最近弄了一個可以在同一個網域中實作多的應用程式的設定,這邊紀錄一下。先講結論:

    1. 可以實現同一個網域前後端分離,讓版本控制的操作也分開來。
    2. 同理多個不同應用如果需要互相呼叫時,也可以使用 sub-path 不要 sub-domain 來處理。
    3. 強烈建議不要用套裝的應用程式,關於網域使用的設計需要特別處理。
    4. 個人認為,如果是不同功能的應用場景,還是應該用 sub-domain 處理,這應該是 UX 相關的設計,和技術較為無關。
    5. 系統層的設定較為複雜,包含 Nginx 的設定,如果沒有 full controll 的權限可能實現上較為困難。

    前提列一下:

    1. 主網域是 a.com.tw
    2. 第二個網域是 b.com.tw 作為 nginx 的 proxy 使用,如果有需要也會在 dns 上設定。

    目標有幾個:

    1. 用戶訪問 a.com.tw 時候,會跳轉至 /root-document/a.com.tw/ 路徑上的 web-app
    2. 用戶訪問 a.com.tw/admin 時候,會跳轉至 /root-document/b.com.tw/ 路徑上的 web-app
    3. 用戶訪問 a.com.tw/uploads 時候,會跳轉至 /root-document/b.com.tw/uploads 路徑上的靜態檔案

    實作步驟:

    設定 /etc/hosts 檔案,新增:

    127.0.0.1 b.com.tw

    如果有需要,可以在 DNS 上設定 CNAME 把 b.com.tw 設定為 a.com.tw 別名。

    設定 a.com.tw 的網站,Nginx 中添加:

    # 將 /admin/ 和 /admin/* 路徑指向後端應用程式
    location ^~ /admin/ {
      proxy_pass http://b.com.tw;
    }
    # 將 /uploads/ 和 /uploads/* 路徑的靜態檔案指向其他資料夾
    location ^~ /uploads/ {
      alias /root-document/b.com.tw/uploads/;
      try_files $uri $uri/ /index.html;
    }
    
    
    # Option 其他網站的配置,例如前端 
    location ^~ / {
      root /root-document/a.com.tw;
      ...
    }

    設定 b.com.tw 的網站,Nginx 按照一般的設定即可,不過在動態程式中需要特別注意幾項:

    1. b.com.tw 的顯示網域是主網域 a.com.tw,在畫面上如果顯示非相對域名,要注意顯示的是 a.com.tw 而不是 b.com.tw
    2. 尤其後端上傳行為與 form action 會需要特別注意。
    3. http://b.com.tw 作為後端服務 proxy_pass,要注意 ssl 設定,包含顯示網域的 ssl 是否寫死?或是 proxy_set_header 判斷處理。
    4. uploads 的路徑在範例中也是導向 /root-document/b.com.tw/ 裡面的路徑,如果單純只是靜態檔案也可以自行設定。建議事先規劃整理好。
    5. 需要請注意根目錄設定 .user.ini 檔案中的設定,建議把不同路徑都補進去。

    還有一些小細節:

    1. Nginx 中 alias 的路徑需要是 / 結尾。 alias 和 root 不同的地方,參考這裡
    2. Nginx 路徑匹配優先權問題,請參考這裡

    關於 Nginx 設定的注意事項,附上問 ChatGPT 生成回覆:

    配置意圖

    1. /admin//admin/* 路徑指向後端應用程式
      • location ^~ /admin/ { ... } 這個配置塊的意圖是將所有匹配 /admin/ 開頭的路徑(包括 /admin//admin/*)的請求,轉發到後端應用程式,其地址為 http://b.com.tw
      • proxy_pass http://b.com.tw; 這個指令表示將符合條件的請求轉發給 http://b.com.tw 這個後端服務處理。
    2. /uploads//uploads/* 路徑的靜態檔案指向其他資料夾
      • location ^~ /uploads/ { ... } 這個配置塊的意圖是處理匹配 /uploads/ 開頭的路徑(包括 /uploads//uploads/*)的請求,並將這些請求指向伺服器上的一個具體的資料夾來提供靜態檔案。
      • alias /root-document/b.com.tw/uploads/; 這個指令表示將 /uploads/ 路徑的請求映射到伺服器上 /root-document/b.com.tw/uploads/ 目錄中的對應檔案。例如,請求 /uploads/image.jpg 會映射到 /root-document/b.com.tw/uploads/image.jpg
      • try_files $uri $uri/ /index.html; 這個指令會嘗試按順序查找以下檔案:
        • $uri:請求的原始檔案或目錄(例如 /root-document/b.com.tw/uploads/image.jpg)。
        • $uri/:如果是目錄,則查找目錄下的檔案(例如 /root-document/b.com.tw/uploads/image.jpg/)。
        • 如果以上都未找到,則回退到 /index.html 這個檔案。

    注意事項

    1. ^~ 前綴
      • ^~ 表示如果路徑匹配 /admin//uploads/,那麼該配置塊將優先於其他正則表達式匹配(例如 location ~location /)來處理請求。這確保了 /admin//uploads/ 的請求被這些特定的配置塊處理。
    2. Proxy Pass 的上下文
      • 當使用 proxy_pass 指令時,Nginx 將請求轉發給後端服務(如 http://b.com.tw)。確保 b.com.tw 這個服務能夠正確處理接收到的 /admin/ 路徑,並且能夠返回正確的響應。
    3. Alias 的使用
      • alias 指令用於將 URL 路徑映射到文件系統上的實際路徑,注意它不同於 root 指令。使用 alias 時需要確保映射的目錄結構和權限設置正確,以便 Nginx 能夠讀取和提供靜態檔案。
    4. 靜態檔案的優先級
      • /uploads/ 路徑的靜態檔案配置中,try_files 的指令順序很重要。你需要確保 /index.html 是你希望用來處理靜態資源請求失敗時的回退頁面。
    5. 安全性考量
      • 在提供靜態資源時,應確保 /root-document/b.com.tw/uploads/ 資料夾內的檔案不包含敏感信息,且檔案權限設置得當,防止未經授權的訪問。

    這段配置主要是為了處理特定路徑的請求,將動態內容轉發給後端應用程式,並通過靜態資源提供功能來處理文件的提供。