重載步驟是 Nginx 設定變更中的最後一個動作,而不是第一個。若要讓 Nginx 安全地重載設定,你需要先用 nginx -t 驗證新檔案,備份目前生效的設定,將審核過的片段放入其 include 情境中,請求具代表性的路徑,然後才發出 nginx -s reload(或平台等效指令),讓執行中的 worker 接收新指令而不會中斷連線。略過任何一個步驟,正是讓小錯字演變成長時間停機的原因。本文將帶你走過完整的重載流程,使用 Nginx 設定產生器作為審核片段的來源,並以 Nginx 核心文件作為你即將重載之每個指令的真相來源。
成功的 nginx -t 能確認語法與引用的檔案,但無法證明任何關於擁有權、DNS 解析、憑證鏈或實際路由行為的事。它是一道必要的關卡,而非放行信號。當重載指令受支援時,它本身就是平順的:主行程讀取新設定、進行第二次驗證,然後衍生出新的 worker 行程接手新連線,而舊的 worker 則處理完進行中的請求。這也是為什麼在平台允許的情況下,重載會比停掉再啟動更受偏好。讓重載過程平淡無奇的流程既小且嚴謹:建立最小的審核區塊、進行驗證、備份目前生效的檔案、放入對應情境、測試具代表性的路徑,然後重載並重新測試。

「重載 Nginx」真正的含義
Nginx 區分重載、重新啟動,以及停掉再啟動。重載是溫和的選項。當你對主行程發送 SIGHUP 或執行 nginx -s reload 時,Nginx 會重新讀取設定、執行內部驗證,然後啟動新的 worker 行程。現有的 worker 會繼續處理進行中的請求,直到完成後才結束。listen 累積佇列中的連線會被交接給新的 worker。從訪客的角度來看,這項變更在沒有中斷請求的情況下發生,這正是偏好重載而非強制重新啟動的全部意義。
代價在於,重載的安全性僅止於 Nginx 剛接收到的設定。如果新檔案引用的 document root 不存在、引用的網域未綁定到監聽 IP,或 gzip 類型在該編譯版本中不支援,新的 worker 將無法啟動,或在第一個請求時回傳錯誤的回應。這就是為什麼重載之前的步驟比重載指令本身更重要。重載是一句話結尾的標點符號,而那句話就是你花了一個小時才調好的設定。
在你建立區塊之前工具會驗證的輸入
Nginx 設定產生器將輸入縮減為四個你必須填對的欄位,以及一組會改變輸出區塊的小選擇。事先了解正在被驗證的內容,能讓你判斷片段出現於畫面後還有哪些需要人工審核。
- 一個精確的網域。產生器會拒絕通訊協定前置詞,並選出一個 server_name。它不會輸出萬用字元或 www 重新導向,因為這兩種選擇都會改變虛擬主機路由與憑證涵蓋範圍。
- 絕對 POSIX 的 document root,由有限的安全路徑字元組成。分號、大括號、變數,以及類似 shell 的語法都會被拒絕,以避免使用者輸入將額外指令偷渡進輸出檔案。
- 以天數表示的快取持續時間,介於 1 到 365 之間。該值會流入獨立 asset location 上的 expires 指令,該 location 涵蓋 CSS、JavaScript、常見圖片、圖示,以及 WOFF2 字體的固定副檔名清單。
- 一個 fallback 選擇。靜態 404 會回傳真正的「找不到」頁面;SPA fallback 則會將 try_files 最後一個參數改寫為 /index.html,讓前端路由收到未知的應用程式路徑。
| 產生器輸出的內容 | 刻意省略的內容 | 省略的原因 |
|---|---|---|
| listen 80;(涵蓋 IPv4 與 IPv6) | TLS listen 區塊、憑證路徑、HSTS | TLS 仰賴憑證位置、續期工具與代理拓樸;若憑空捏造會製造虛假的安全感 |
| 一個精確的 server_name | 萬用字元、regex 形式的 server 名稱、www 重新導向 | 每種選擇都會改變路由與憑證涵蓋範圍 |
| 來自驗證過絕對路徑的 root | PHP-FastCGI、proxy_pass 後端 | 應用程式後端需要部署專屬的證據 |
| location / 搭配 try_files(靜態或 SPA) | 自訂錯誤頁面、速率限制、身份驗證 | 超出有限的靜態網站範疇 |
| asset location 上的 expires 與 Cache-Control public | ETag 規則、immutable 旗標 | 在選擇長快取時間之前,先對長效資產進行版本指紋化 |
| 選用的 gzip on、gzip_types、gzip_vary on; | 預先壓縮的資產服務、Brotli | 壓縮的旁路管道與編碼器需要審核 |
建立經過審核的伺服器區塊
一旦填入這四個輸入並刻意選擇 fallback,產生器就會在瀏覽器中組裝出一個固定的 HTTP server 區塊。內容不會上傳;片段保留在本機,讓你可以貼進受控的審核流程中。能產生上述精簡區塊、並顯示用以證明輸入並未被默默接受的負面測試結果的工具,就是 Nginx 設定產生器。
在將區塊貼到任何地方之前,請逐行比對你 Nginx 版本實際編譯進去的模組。區塊中的指令——listen、server_name、root、try_files、expires、gzip、gzip_types、gzip_vary——都記錄在 Nginx 核心模組參考手冊 中。如果你的版本未包含 gzip 模組,對應的幾行會在語法測試時失敗,你需要將其刪除後再重新測試。
驗證、備份、放置、重載
以下是具體的流程。依照順序執行,重載就會成為這次變更中最微不足道的一步。
- 儲存目前的設定。將目前生效的 nginx.conf 與所有被引入的片段複製到一個帶有時間戳記的備份目錄。記錄 include 鏈,以便在部署輪替日誌或路徑時仍能找到該檔案。
- 將審核過的片段放入對應情境。將產生的區塊放入正確的 site-available 目錄,從 site-enabled 目錄(或你的發行版所使用的 include 模式)建立連結,並確認 include 路徑與 nginx.conf 實際讀取的一致。
- 對完整設定執行 nginx -t。閱讀輸出:成功的測試會回報 syntax is OK 與 test is successful。失敗的測試會印出有問題的檔案與行號;在輸出乾淨之前請勿重載。
- 在重載之前先請求具代表性的路徑。對 document root、一個已知的 asset,以及一個刻意不存在的路徑,使用 curl -I 或等效的 head 請求。將回應與新指令應產生的結果進行比對。
- 發出重載指令。當你的安裝支援 -s 控制套接字時,nginx -s reload 會對主行程發送 SIGHUP;在使用 systemd 的主機上,等效指令是 systemctl reload nginx。請依照平台程序操作,不要自行猜測。
- 再次測試同一組具代表性的路徑。語法上成功的重載,仍可能在擁有權或權限同時被變動的情況下回傳 500。
- 保持一個復原用的 shell 開啟,直到確認新的回應無誤。若發生任何退化,第 1 步的備份就是回退路徑。
nginx -t 能證明與不能證明的事
乾淨的 nginx -t 是必要條件,而非充分條件。該指令會開啟每個被引入的檔案、解析每條指令,並檢查引用的檔案與模組是否能從執行中的 Nginx 二進位檔觸及。它無法得知本機上 document root 是否存在、執行中的 worker 是否擁有讀取權限、DNS 是否將所選的 server_name 指向監聽 IP、TLS 憑證是否有效(因為這個區塊中沒有 TLS),或反向代理後方的應用程式是否健康。
這就是為什麼重載前後的 curl 檢查很重要。它們走的是真實訪客將會經過的同一條程式碼路徑。在 / 上得到 200、在 /assets/main.css 上得到帶有預期 Expires 與 Cache-Control 標頭的 200,以及在刻意不存在的路徑上得到真正的 404,這些是重載產生預期行為的最低訊號。若啟用了 SPA fallback,該不存在的路徑應回傳 200 並帶有首頁殼層;若未啟用,則應回傳 404。若你同時維運一個 Apache 來源、且即將重載的設定是從 .htaccess 檔案遷移而來,從 htaccess 轉換到 Nginx 設定:重載前稽核 這篇指南會更深入地說明該稽核步驟。
當重載造成問題時如何回退
產生錯誤回應的重載不是恐慌的理由,而是使用第 1 步備份的理由。將儲存的檔案複製回原位,再次執行 nginx -t 以確認還原後的設定是乾淨的,然後再重載一次。先前執行中的 worker 已經離開,所以這次回退的重載行為會與原本的重載相同:平順地、由讀取還原檔案的新 worker 接手處理進行中的請求。
如果還原後的備份在語法測試中失敗,代表原本的失敗並非由你正要部署的變更所引起。在進行下一次編輯之前,請停下來閱讀錯誤日誌;在與本次無關的故障上疊加重載,正是停機事故擴大的原因。若語法測試通過但請求仍然失敗,代表問題位於 Nginx 上游:DNS、檔案擁有權、應用程式後端,或憑證續期。請檢查設定中 access_log 與 error_log 路徑下的錯誤日誌,並在下一次嘗試重載之前先解決這些問題。
本工具未涵蓋的範圍(及其原因)
數項常見的 Nginx 職責被刻意排除在產生的區塊之外。HTTPS、PHP-FastCGI、反向代理、WebSocket、上傳、身份驗證、速率限制、自訂錯誤、MIME 引入路徑、日誌,以及安全性標頭,皆不會被輸出。這些項目每一項都仰賴瀏覽器無法取得的部署證據:憑證路徑與續期工具、上游應用程式位址與健康檢查、速率限制的金鑰與 zone,以及適用於該應用程式的安全性標頭。
可維護的結果,是一份與當前部署證據相符、且盡可能精簡的審核後設定。若你的問題只是小型靜態來源,上述產生器加上重載流程便已足夠。對於代管主機、容器、Kubernetes ingress,或 CDN 而言,真正提供流量的設定介面存在於其他位置;該處的重載遵循平台自身的程序,而非 nginx -s reload。當平台說了算,請信任平台,並在其重載指令的上游套用同樣的「先稽核」習慣。
若你正在權衡各種選項,htaccess 批次轉換到 Nginx:工具實際對應的內容 對此有更詳細的說明。