Published in
5 min readApr 22, 2024
# 前言
紀錄 Nginx config 的細節 route 流程
# config
以下為簡化後的 Laravel document 的預設 Nginx config
server {
listen 80;
listen [::]:80;
server_name example.com;
root /srv/example.com/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
# 初步語法解析
- listen:監聽的 port
- server_name:request host name
- root:location 會到哪一個位置 search file,如上範例,會到
/src/example.com/public
下,套用 location 規則搜尋 - index:當 destination 為 dir 時,會嘗試在 dir 底下搜尋 index.php file
- location / {}:match 所有 url
- location = /favicon.ico:當
$url
===/favicon.ico
時,才會執行 { } 內的 code - access_log off:該筆 request 不會 log 到 access_log
- error_page 404:若 fastcgi 返回 404 時,則觸發此 block,不過唯有當
fastcgi_intercept_errors on;
時這個 config 才有作用。若是使用 proxy pass 的話則是proxy_intercept_errors on;
。所以可以理解為,這個 config 基本上是無作用的 - location ~:正則搜尋,為 case sensitive
- location ~ .php$:符合
.php
結尾的會進到該 location - fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;:將 request pass 到指定 unix process socket
- include fastcgi_params;:include common params,檔案通常會放在
/etc/nginx
底下 - fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;:assign
$realpath_root$fastcgi_script_name
into 名為SCRIPT_FILENAME
的 fastcgi_param,若該 fastcgi_param 已存在於 fastcgi_params file,則按讀取順序覆蓋,所以 include common params 務必置於自定義 param 上方 - location ~ /.(?!well-known).* { … }:如果 $uri 的 pattern 為
/.(xxx)
開頭,只要不符合/.well-known
pattern 的全部 deny,.well-known 的用途在於驗證 SSL 憑證時會將 challenge file 放在此 dir 下
# 流程解析
當 request uri 為 example.com/app.css
時,會依照 location rule 來 search
- 依照 location rule,符合
/
location block - 到
/srv/example.com/public
下尋找app.css
- 沒找到,尋找
/srv/example.com/public/app.css/
dir 是否存在 - 若存在,則依據 index 語法設定,尋找
index.php
是否存在 - 若不存在,則 rewrite request uri 為
/index.php?$query_string;
- 依照 location rule,先經由前綴原則找到
/
location block - 依照 location rule,使用正則尋找符合的 location block,找到
~ \.index.php$
location block - 設定 fastcgi params 為 fastcgi_params file 定義的 params 以家 SCRIPT_FILENAME 為 $realpath_root$fastcgi_script_name,即
/src/example.com/public/index.php
- 將 request pass 到 fastcgi process socket
# 流程圖
可先參考 location rule,或參考 location rule 的簡易流程圖
然後是 try_files 的流程圖