Nginx 基礎配置

Nginx 設定檔結構、server/location 區塊、匹配規則與存取控制完整指南


目錄


Nginx 指令

基本操作指令

# 啟動 Nginx
nginx                           # 直接啟動
sudo systemctl start nginx      # systemd 啟動

# 停止 Nginx
nginx -s stop                   # 快速停止(立即終止)
nginx -s quit                   # 優雅停止(等待請求處理完成)
sudo systemctl stop nginx       # systemd 停止

# 重新載入設定(不中斷服務)⭐ 常用
nginx -s reload
sudo systemctl reload nginx

# 重新開啟日誌檔案(log rotation 後使用)
nginx -s reopen

# 重啟 Nginx
sudo systemctl restart nginx

設定檔驗證 ⭐

# 檢查設定檔語法(最常用)
nginx -t
# 輸出範例:
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful

# 檢查並顯示完整設定(展開所有 include)
nginx -T

# 指定設定檔檢查
nginx -t -c /path/to/nginx.conf

# 檢查特定設定檔(不啟動)
nginx -t -c /etc/nginx/sites-available/example.conf

查詢資訊

# 查看 Nginx 版本
nginx -v
# 輸出:nginx version: nginx/1.24.0

# 查看詳細版本資訊(含編譯參數)
nginx -V
# 輸出:nginx version、configure arguments、編譯模組等

# 查看 Nginx 程序狀態
ps aux | grep nginx
# master process:主程序
# worker process:工作程序

# 查看 Nginx 監聽的 port
sudo ss -tlnp | grep nginx
# 或
sudo netstat -tlnp | grep nginx

# 查看 Nginx 狀態(systemd)
sudo systemctl status nginx

指令參數總覽

參數 說明 範例
-t 測試設定檔語法 nginx -t
-T 測試並輸出完整設定 nginx -T
-c 指定設定檔路徑 nginx -c /path/to/nginx.conf
-s 發送信號給主程序 nginx -s reload
-p 設定 prefix 路徑 nginx -p /var/nginx
-g 設定全域指令 nginx -g "daemon off;"
-v 顯示版本 nginx -v
-V 顯示版本和編譯資訊 nginx -V
-q 安靜模式(只顯示錯誤) nginx -t -q

-s 信號選項

信號 說明 使用情境
stop 快速停止 立即終止所有連線
quit 優雅停止 等待現有請求完成後停止
reload 重新載入設定 修改設定後套用(不中斷服務)⭐
reopen 重新開啟日誌 log rotation 後使用

常用操作流程

# 標準修改設定流程 ⭐
# 1. 編輯設定檔
sudo vim /etc/nginx/sites-available/example.conf

# 2. 檢查語法
sudo nginx -t

# 3. 如果語法正確,重新載入
sudo nginx -s reload
# 或
sudo systemctl reload nginx

# 啟用新站點(Debian/Ubuntu)
sudo ln -s /etc/nginx/sites-available/example.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo nginx -s reload

# 停用站點
sudo rm /etc/nginx/sites-enabled/example.conf
sudo nginx -t && sudo nginx -s reload

日誌相關

# 即時查看存取日誌
sudo tail -f /var/log/nginx/access.log

# 即時查看錯誤日誌
sudo tail -f /var/log/nginx/error.log

# 查看特定站點日誌
sudo tail -f /var/log/nginx/example.com.access.log

# 搜尋錯誤
sudo grep "error" /var/log/nginx/error.log

# 統計 HTTP 狀態碼
sudo awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

Debug 模式

# 以 debug 模式啟動(需編譯時啟用 --with-debug)
nginx -g "error_log /var/log/nginx/debug.log debug;"

# 在設定檔中啟用 debug(針對特定 IP)
events {
    debug_connection 192.168.1.100;
}

設定檔結構

主要設定檔位置

Linux / Docker Container(官方 nginx image)

# 主設定檔
/etc/nginx/nginx.conf

# 站點設定(Debian/Ubuntu)
/etc/nginx/sites-available/    # 可用站點設定
/etc/nginx/sites-enabled/      # 已啟用站點(symlink)

# 站點設定(CentOS/RHEL / 官方 Docker image)
/etc/nginx/conf.d/             # 所有 .conf 檔案自動載入 ⭐

# 其他
/etc/nginx/mime.types          # MIME 類型對應
/etc/nginx/fastcgi_params      # FastCGI 參數

macOS(Homebrew 安裝)

# 主設定檔
/usr/local/etc/nginx/nginx.conf        # Intel Mac
/opt/homebrew/etc/nginx/nginx.conf     # Apple Silicon (M1/M2)

# 站點設定
/usr/local/etc/nginx/servers/          # Intel Mac
/opt/homebrew/etc/nginx/servers/       # Apple Silicon

Docker 常用掛載方式

# 掛載自訂設定檔
docker run -d \
  -v /path/to/nginx.conf:/etc/nginx/nginx.conf:ro \
  -v /path/to/conf.d:/etc/nginx/conf.d:ro \
  -p 80:80 \
  nginx

# 掛載靜態檔案
docker run -d \
  -v /path/to/html:/usr/share/nginx/html:ro \
  -p 80:80 \
  nginx

# docker-compose 範例
services:
  nginx:
    image: nginx:alpine
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./conf.d:/etc/nginx/conf.d:ro
      - ./html:/usr/share/nginx/html:ro
    ports:
      - "80:80"

官方 Docker image 預設路徑

路徑 說明
/etc/nginx/nginx.conf 主設定檔
/etc/nginx/conf.d/ 額外設定檔目錄(*.conf 自動載入)
/etc/nginx/conf.d/default.conf 預設站點設定
/usr/share/nginx/html/ 預設網頁根目錄
/var/log/nginx/ 日誌目錄
/var/cache/nginx/ 快取目錄

階層結構

# nginx.conf 基本結構

# 全域區塊(main context)
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# events 區塊
events {
    worker_connections 1024;
}

# http 區塊
http {
    # http 全域設定
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # server 區塊(虛擬主機)
    server {
        listen 80;
        server_name example.com;

        # location 區塊
        location / {
            root /var/www/html;
        }
    }

    # 可以有多個 server 區塊
    server {
        listen 80;
        server_name another.com;
        # ...
    }

    # 引入其他設定檔
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

核心指令區塊

Nginx 設定檔由多個**區塊(Block/Context)**組成,每個區塊負責不同功能:

┌─────────────────────────────────────────────────────────────┐
│  main(全域)                                                │
│  ├─ 程序層級設定:worker 數量、使用者、PID、錯誤日誌              │
│  │                                                          │
│  ├─ events { }                                              │
│  │   └─ 連線處理:最大連線數、事件模型                           │
│  │                                                          │
│  └─ http { }                                                │
│      ├─ HTTP 全域設定:MIME、日誌、壓縮、快取                    │
│      │                                                      │
│      ├─ server { }  ← 虛擬主機 1                              │
│      │   ├─ 監聽 port、域名                                   │
│      │   └─ location { }  ← URL 路徑處理                      │
│      │                                                      │
│      └─ server { }  ← 虛擬主機 2                             │
│          └─ ...                                             │
└─────────────────────────────────────────────────────────────┘

區塊功能總覽

區塊 層級 主要功能
main 最外層 Nginx 程序本身的設定(worker、使用者、日誌)
events main 內 連線處理機制(最大連線數、事件驅動模型)
http main 內 HTTP 服務全域設定(MIME、日誌格式、壓縮)
server http 內 虛擬主機設定(域名、port、SSL)
location server 內 URL 路徑匹配與處理規則
upstream http 內 後端伺服器群組(負載平衡)

全域區塊(main context)

功能:設定 Nginx 程序本身的行為,影響整個 Nginx 服務

# 執行 Nginx 的使用者和群組(安全性:用低權限使用者)
user nginx nginx;

# worker 程序數量(auto = CPU 核心數)
worker_processes auto;

# 錯誤日誌位置和等級
error_log /var/log/nginx/error.log warn;
# 等級:debug, info, notice, warn, error, crit, alert, emerg

# PID 檔案位置
pid /var/run/nginx.pid;

# 單一 worker 可開啟的最大檔案數
worker_rlimit_nofile 65535;

events 區塊

功能:設定 Nginx 如何處理網路連線(事件驅動模型)

events {
    # 單一 worker 最大連線數
    # 總最大連線 = worker_processes × worker_connections
    worker_connections 1024;

    # 事件驅動模型(Linux 用 epoll 最高效)
    use epoll;
    # 可選:select, poll, epoll(Linux), kqueue(BSD/macOS)

    # 是否同時接受多個連線(高流量建議開啟)
    multi_accept on;
}

為什麼重要

  • Nginx 的高效能來自於非阻塞事件驅動架構
  • epoll(Linux)和 kqueue(macOS)是最高效的模型
  • worker_connections 決定能同時處理多少連線

http 區塊

功能:設定 HTTP 服務的全域行為,所有 server 區塊共享這些設定

http {
    # ===== MIME 類型 =====
    # 告訴瀏覽器如何處理不同檔案類型
    include /etc/nginx/mime.types;
    default_type application/octet-stream;  # 未知類型預設下載

    # ===== 日誌設定 =====
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    # ===== 效能優化 =====
    sendfile on;           # 高效檔案傳輸(零拷貝)
    tcp_nopush on;         # 減少網路封包數
    tcp_nodelay on;        # 減少延遲(小封包立即發送)

    # ===== 連線設定 =====
    keepalive_timeout 65;  # 保持連線超時(秒)
    types_hash_max_size 2048;

    # ===== Gzip 壓縮 =====
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    # ===== server 區塊(虛擬主機)=====
    server {
        # ...
    }

    # ===== upstream 區塊(負載平衡)=====
    upstream backend {
        server 192.168.1.101:3000;
        server 192.168.1.102:3000;
    }

    # ===== 引入其他設定檔 =====
    include /etc/nginx/conf.d/*.conf;
}

http 區塊常見設定分類

類別 設定項目 說明
MIME include mime.types 檔案類型對應
日誌 log_format, access_log 存取日誌格式
效能 sendfile, tcp_nopush 檔案傳輸優化
連線 keepalive_timeout 持久連線設定
壓縮 gzip 回應內容壓縮
快取 proxy_cache 代理快取設定

server 區塊

server 區塊定義一個虛擬主機(Virtual Host)。

基本結構

server {
    # 監聽設定
    listen 80;                    # IPv4
    listen [::]:80;               # IPv6
    listen 443 ssl http2;         # HTTPS + HTTP/2

    # 伺服器名稱
    server_name example.com www.example.com;

    # 文件根目錄
    root /var/www/example;

    # 預設索引檔案
    index index.html index.htm index.php;

    # location 區塊...
}

server_name 設定

# 精確匹配
server_name example.com;

# 多個域名
server_name example.com www.example.com;

# 萬用字元(開頭)
server_name *.example.com;

# 萬用字元(結尾)
server_name example.*;

# 正則表達式(以 ~ 開頭)
server_name ~^www\d+\.example\.com$;

# 正則表達式擷取
server_name ~^(?<subdomain>.+)\.example\.com$;
# 使用 $subdomain 變數

# 預設伺服器(處理未匹配的請求)
server_name _;

# 空主機名稱(直接用 IP 訪問)
server_name "";

server_name 匹配優先順序

  1. 精確名稱example.com
  2. 萬用字元開頭(最長優先):*.example.com
  3. 萬用字元結尾(最長優先):example.*
  4. 正則表達式(按設定檔順序):~^www\d+\.example\.com$
  5. default_serverlisten 80 default_server;

listen 指令詳解

# 基本用法
listen 80;                        # 監聽所有介面的 80 port
listen 127.0.0.1:80;              # 只監聽 localhost
listen 192.168.1.1:80;            # 監聽特定 IP

# IPv6
listen [::]:80;                   # 所有 IPv6 介面
listen [::1]:80;                  # IPv6 localhost

# 預設伺服器
listen 80 default_server;         # 未匹配時使用此 server

# HTTPS
listen 443 ssl;                   # 啟用 SSL
listen 443 ssl http2;             # SSL + HTTP/2

# Unix socket
listen unix:/var/run/nginx.sock;

root 與 alias 的差異

# root:將 URI 附加到 root 路徑
location /images/ {
    root /var/www;
    # 請求 /images/logo.png → /var/www/images/logo.png
}

# alias:將 URI 替換為 alias 路徑
location /images/ {
    alias /var/www/static/;
    # 請求 /images/logo.png → /var/www/static/logo.png
}

# ⚠️ alias 路徑結尾必須加 /(如果 location 也有 /)

location 區塊

location 區塊定義如何處理特定 URI 的請求。

語法格式

location [修飾符] 匹配模式 {
    # 指令...
}

修飾符類型

修飾符 說明 範例
(無) 前綴匹配 location /api/
= 精確匹配 location = /
~ 區分大小寫的正則 location ~ \.php$
~* 不區分大小寫的正則 location ~* \.(jpg|png)$
^~ 前綴匹配,優先於正則 location ^~ /static/

使用範例

# 精確匹配首頁
location = / {
    # 只匹配 / 本身
    return 200 "Homepage";
}

# 前綴匹配
location /api/ {
    # 匹配 /api/users, /api/products 等
    proxy_pass http://backend;
}

# 正則匹配(區分大小寫)
location ~ \.php$ {
    # 匹配 .php 結尾
    fastcgi_pass unix:/var/run/php-fpm.sock;
}

# 正則匹配(不區分大小寫)
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    # 匹配靜態資源
    expires 30d;
}

# 前綴優先(不再檢查正則)
location ^~ /static/ {
    # 匹配 /static/ 開頭,跳過正則檢查
    root /var/www;
}

location 匹配優先順序

這是 Nginx 最重要的概念之一。

匹配流程圖

1. 檢查所有「精確匹配」(=)
   ├─ 找到 → 使用該 location,停止搜尋
   └─ 未找到 → 繼續

2. 檢查所有「前綴匹配」(無修飾符 和 ^~)
   ├─ 記錄「最長匹配」的 location
   ├─ 如果最長匹配是 ^~ → 使用該 location,停止搜尋
   └─ 否則 → 繼續

3. 按順序檢查「正則表達式」(~ 和 ~*)
   ├─ 找到第一個匹配 → 使用該 location,停止搜尋
   └─ 全部未匹配 → 使用步驟 2 記錄的最長前綴匹配

優先順序總結

1. = (精確匹配) - 最高優先
2. ^~ (前綴匹配,停止正則) - 第二優先
3. ~ 或 ~* (正則表達式) - 按設定順序,第一個匹配生效
4. 無修飾符 (前綴匹配) - 最長匹配生效

實際範例

server {
    listen 80;
    server_name example.com;

    # 1. 精確匹配 /(最高優先)
    location = / {
        return 200 "Exact root";
    }

    # 2. ^~ 前綴匹配(優先於正則)
    location ^~ /static/ {
        return 200 "Static files (prefix priority)";
    }

    # 3. 正則匹配(按順序檢查)
    location ~ \.html$ {
        return 200 "HTML files (regex)";
    }

    location ~* \.(jpg|png)$ {
        return 200 "Images (regex case-insensitive)";
    }

    # 4. 普通前綴匹配(最長匹配)
    location /api/ {
        return 200 "API prefix";
    }

    location /api/v1/ {
        return 200 "API v1 prefix (longer match)";
    }

    # 5. 預設匹配
    location / {
        return 200 "Default";
    }
}

匹配測試結果

請求 URI 匹配的 location 原因
/ = / 精確匹配
/index.html ~ \.html$ 正則匹配
/static/style.css ^~ /static/ ^~ 前綴優先於正則
/static/logo.png ^~ /static/ ^~ 前綴優先於正則(不是 ~* 的 png)
/images/logo.png ~* \.(jpg|png)$ 正則匹配
/api/users /api/ 最長前綴匹配
/api/v1/users /api/v1/ 最長前綴匹配
/about / 預設前綴匹配

存取控制

IP 存取控制(allow/deny)

# 基本語法
location /admin/ {
    # 允許特定 IP
    allow 192.168.1.100;
    allow 10.0.0.0/8;       # 允許整個網段

    # 拒絕其他所有
    deny all;
}

# 規則順序很重要!(由上到下比對,第一個匹配生效)
location /api/ {
    deny 192.168.1.50;      # 先拒絕特定 IP
    allow 192.168.1.0/24;   # 允許同網段其他 IP
    deny all;               # 拒絕其他所有
}

# 只允許內部網路
location /internal/ {
    allow 10.0.0.0/8;
    allow 172.16.0.0/12;
    allow 192.168.0.0/16;
    allow 127.0.0.1;
    deny all;
}

基本認證(HTTP Basic Auth)

# 1. 建立密碼檔案
# sudo apt install apache2-utils  # 安裝 htpasswd
# sudo htpasswd -c /etc/nginx/.htpasswd username

# 2. 設定認證
location /admin/ {
    auth_basic "Restricted Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

# 結合 IP 控制
location /admin/ {
    # 內部網路不需認證
    satisfy any;

    allow 192.168.1.0/24;
    deny all;

    auth_basic "Admin Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

satisfy 指令

# satisfy all (預設):所有條件都必須滿足
# satisfy any:任一條件滿足即可

location /protected/ {
    satisfy any;    # IP 符合「或」密碼正確

    # IP 白名單
    allow 192.168.1.0/24;
    deny all;

    # 密碼認證
    auth_basic "Protected";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

限制請求方法

# 只允許 GET 和 HEAD
location /api/ {
    limit_except GET HEAD {
        deny all;
    }
}

# 只允許 GET、POST
if ($request_method !~ ^(GET|POST)$) {
    return 405;
}

防止目錄遍歷

# 禁止存取隱藏檔案
location ~ /\. {
    deny all;
    return 404;
}

# 禁止存取特定副檔名
location ~* \.(git|svn|env|sql|log|bak)$ {
    deny all;
    return 404;
}

# 禁止存取敏感目錄
location ~* /(\.git|\.svn|\.env|node_modules)/ {
    deny all;
    return 404;
}
location ~* \.(jpg|jpeg|png|gif|webp)$ {
    # 允許的 referer
    valid_referers none blocked server_names
                   *.example.com example.com;

    if ($invalid_referer) {
        return 403;
        # 或顯示替代圖片
        # rewrite ^ /images/hotlink-denied.png last;
    }
}

常用變數

請求相關變數

變數 說明 範例值
$uri 當前 URI(不含參數) /api/users
$request_uri 原始請求 URI(含參數) /api/users?page=1
$args 查詢參數 page=1&size=10
$arg_name 特定參數值 $arg_page1
$request_method 請求方法 GET, POST
$host 請求的 Host example.com
$http_host Host 標頭(含 port) example.com:8080
$scheme 協定 http, https

客戶端變數

變數 說明 範例值
$remote_addr 客戶端 IP 192.168.1.100
$remote_port 客戶端 port 52431
$http_user_agent User-Agent Mozilla/5.0...
$http_referer Referer 標頭 https://google.com
$http_cookie Cookie 標頭 session=abc123
$http_x_forwarded_for X-Forwarded-For 10.0.0.1, 192.168.1.1

伺服器變數

變數 說明 範例值
$server_name 匹配的 server_name example.com
$server_addr 伺服器 IP 192.168.1.1
$server_port 伺服器 port 80, 443
$document_root root 目錄路徑 /var/www/html
$request_filename 完整檔案路徑 /var/www/html/index.html

回應變數

變數 說明 範例值
$status 回應狀態碼 200, 404
$body_bytes_sent 傳送的位元組數 1024
$request_time 請求處理時間(秒) 0.032

使用範例

# 日誌格式
log_format detailed '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    'rt=$request_time';

# 條件判斷
if ($request_method = POST) {
    # ...
}

# Header 設定
add_header X-Request-ID $request_id;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# 重寫
rewrite ^/old/(.*)$ /new/$1 permanent;

實戰範例

範例 1:基本靜態網站

server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/example;
    index index.html index.htm;

    # 主要頁面
    location / {
        try_files $uri $uri/ =404;
    }

    # 靜態資源快取
    location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }

    # 禁止存取隱藏檔案
    location ~ /\. {
        deny all;
    }

    # 錯誤頁面
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
}

範例 2:反向代理 + 負載平衡

# 定義 upstream
upstream backend {
    least_conn;                    # 最少連線演算法
    server 192.168.1.101:3000 weight=3;
    server 192.168.1.102:3000 weight=2;
    server 192.168.1.103:3000 backup;
}

server {
    listen 80;
    server_name api.example.com;

    # API 代理
    location /api/ {
        proxy_pass http://backend;

        # 傳遞客戶端資訊
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 超時設定
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # 緩衝設定
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
    }

    # WebSocket 支援
    location /ws/ {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 86400;  # 24 小時
    }
}

範例 3:前後端分離部署

server {
    listen 80;
    server_name app.example.com;

    # 前端靜態檔案
    root /var/www/frontend/dist;
    index index.html;

    # SPA 路由(React/Vue)
    location / {
        try_files $uri $uri/ /index.html;
    }

    # API 代理到後端
    location /api/ {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # 靜態資源
    location /static/ {
        alias /var/www/frontend/dist/static/;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

範例 4:多網站配置

# 主網站
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/main;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

# 部落格子網域
server {
    listen 80;
    server_name blog.example.com;
    root /var/www/blog;
    index index.php index.html;

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

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

# API 子網域
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

範例 5:管理後台保護

server {
    listen 80;
    server_name admin.example.com;

    # 只允許公司內網存取
    allow 10.0.0.0/8;
    allow 192.168.1.0/24;
    deny all;

    root /var/www/admin;
    index index.html;

    # 額外密碼保護
    location / {
        auth_basic "Admin Area";
        auth_basic_user_file /etc/nginx/.htpasswd;
        try_files $uri $uri/ =404;
    }

    # 禁止存取敏感檔案
    location ~* \.(env|git|log)$ {
        deny all;
        return 404;
    }
}

常見問題

1. location 匹配不如預期

# ❌ 問題:/api/v1/users 匹配到 location /
# 原因:沒有定義 /api/ 的 location

# ✅ 解決:確保有對應的 location
location / {
    # 預設處理
}

location /api/ {
    # API 處理
}

2. 正則 location 沒生效

# ❌ 問題:正則被 ^~ 跳過
location ^~ /static/ {
    # ^~ 會阻止後續正則檢查
}

location ~* \.(css|js)$ {
    # 不會匹配 /static/style.css
}

# ✅ 解決:在 ^~ location 內處理
location ^~ /static/ {
    location ~* \.(css|js)$ {
        expires 30d;
    }
}

3. alias 路徑問題

# ❌ 錯誤:少了結尾 /
location /images/ {
    alias /var/www/static;
    # /images/logo.png → /var/www/staticlogo.png(錯誤)
}

# ✅ 正確:加上結尾 /
location /images/ {
    alias /var/www/static/;
    # /images/logo.png → /var/www/static/logo.png
}

4. try_files 找不到檔案

# ❌ 問題:SPA 路由 404
location / {
    try_files $uri $uri/ =404;
}

# ✅ 解決:回退到 index.html
location / {
    try_files $uri $uri/ /index.html;
}

5. IP 允許規則不生效

# ❌ 問題:順序錯誤
location /admin/ {
    deny all;           # 先拒絕所有
    allow 192.168.1.0/24;   # 這行不會生效!
}

# ✅ 正確:先允許再拒絕
location /admin/ {
    allow 192.168.1.0/24;
    deny all;
}

6. 設定檔語法檢查

# 檢查設定檔語法
sudo nginx -t

# 重新載入設定(不中斷服務)
sudo nginx -s reload

# 查看錯誤日誌
sudo tail -f /var/log/nginx/error.log

總結

location 匹配速查表

優先順序 修飾符 說明 範例
1 = 精確匹配 location = /
2 ^~ 前綴優先 location ^~ /static/
3 ~ 正則(大小寫敏感) location ~ \.php$
3 ~* 正則(不分大小寫) location ~* \.(jpg|png)$
4 (無) 前綴匹配 location /api/

常用指令速查

指令 用途 範例
listen 監聽 port listen 80;
server_name 域名 server_name example.com;
root 文件根目錄 root /var/www;
alias 路徑替換 alias /var/www/static/;
index 預設檔案 index index.html;
try_files 依序嘗試 try_files $uri $uri/ =404;
proxy_pass 反向代理 proxy_pass http://backend;
allow/deny IP 控制 allow 192.168.1.0/24;
auth_basic 密碼認證 auth_basic "Protected";

建立日期:2025-12-03 標籤:#Nginx #Web伺服器 #配置 #反向代理 #location

🔗相關文章